xref: /original-bsd/sys/hp300/stand/sd.c (revision bb7e46d0)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Van Jacobson of Lawrence Berkeley Laboratory and the Systems
8  * Programming Group of the University of Utah Computer Science Department.
9  *
10  * %sccs.include.redist.c%
11  *
12  * from: Utah $Hdr: sd.c 1.2 90/01/23$
13  *
14  *	@(#)sd.c	7.6 (Berkeley) 08/14/92
15  */
16 
17 /*
18  * SCSI CCS disk driver
19  */
20 
21 #include "sys/param.h"
22 #include "saio.h"
23 #include "samachdep.h"
24 
25 #include "../dev/scsireg.h"
26 
27 struct	sd_softc {
28 	char	sc_retry;
29 	char	sc_alive;
30 	short	sc_blkshift;
31 } sd_softc[NSCSI][NSD];
32 
33 int sdpartoff[] = {
34 	1024,	17408,	0,	17408,
35 	115712,	218112,	82944,	115712
36 };
37 
38 #define	SDRETRY		2
39 
40 sdinit(ctlr, unit)
41 	int ctlr, unit;
42 {
43 	register struct sd_softc *ss = &sd_softc[ctlr][unit];
44 	u_char stat;
45 	int capbuf[2];
46 
47 	stat = scsi_test_unit_rdy(ctlr, unit);
48 	if (stat) {
49 		/* drive may be doing RTZ - wait a bit */
50 		if (stat == STS_CHECKCOND) {
51 			DELAY(1000000);
52 			stat = scsi_test_unit_rdy(ctlr, unit);
53 		}
54 		if (stat) {
55 			printf("sd(%d,%d,0,0): init failed (stat=%x)\n",
56 			       ctlr, unit, stat);
57 			return (0);
58 		}
59 	}
60 	/*
61 	 * try to get the drive block size.
62 	 */
63 	capbuf[0] = 0;
64 	capbuf[1] = 0;
65 	stat = scsi_read_capacity(ctlr, unit,
66 				  (u_char *)capbuf, sizeof(capbuf));
67 	if (stat == 0) {
68 		if (capbuf[1] > DEV_BSIZE)
69 			for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1)
70 				++ss->sc_blkshift;
71 	}
72 	ss->sc_alive = 1;
73 	return (1);
74 }
75 
76 sdreset(ctlr, unit)
77 	int ctlr, unit;
78 {
79 }
80 
81 sdopen(io)
82 	struct iob *io;
83 {
84 	register struct sd_softc *ss;
85 	int ctlr, unit, part;
86 
87 	devconvert(io);
88 
89 	ctlr = io->i_adapt;
90 	if (ctlr >= NSCSI || scsialive(ctlr) == 0)
91 		return (EADAPT);
92 	unit = io->i_ctlr;
93 	if (unit >= NSD)
94 		return (ECTLR);
95 	ss = &sd_softc[ctlr][unit];
96 	if (ss->sc_alive == 0)
97 		if (sdinit(ctlr, unit) == 0)
98 			return (ENXIO);
99 	part = io->i_part;
100 	if (part >= 8)
101 		return (EPART);
102 	io->i_boff = sdpartoff[part];
103 	return (0);
104 }
105 
106 sdstrategy(io, func)
107 	register struct iob *io;
108 	int func;
109 {
110 	register int ctlr = io->i_adapt;
111 	register int unit = io->i_ctlr;
112 	register struct sd_softc *ss = &sd_softc[ctlr][unit];
113 	daddr_t blk = io->i_bn >> ss->sc_blkshift;
114 	u_int nblk = io->i_cc >> ss->sc_blkshift;
115 	char stat;
116 
117 	if (io->i_cc == 0)
118 		return(0);
119 
120 	ss->sc_retry = 0;
121 retry:
122 	if (func == F_READ)
123 		stat = scsi_tt_read(ctlr, unit, io->i_ma, io->i_cc, blk, nblk);
124 	else
125 		stat = scsi_tt_write(ctlr, unit, io->i_ma, io->i_cc, blk, nblk);
126 	if (stat) {
127 		printf("sd(%d,%d,%d,%d): block=%x, error=0x%x\n",
128 		       ctlr, unit, io->i_unit, io->i_part, blk, stat);
129 		if (++ss->sc_retry > SDRETRY)
130 			return(-1);
131 		goto retry;
132 	}
133 	return(io->i_cc);
134 }
135