xref: /original-bsd/sys/hp300/stand/sd.c (revision 3705696b)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1990, 1993
4  *	The Regents of the University of California.  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.9 92/12/21$
13  *
14  *	@(#)sd.c	8.1 (Berkeley) 06/10/93
15  */
16 
17 /*
18  * SCSI CCS disk driver
19  */
20 
21 #include <sys/param.h>
22 #include <sys/disklabel.h>
23 #include <stand.att/saio.h>
24 #include <hp300/stand/samachdep.h>
25 
26 #include <hp300/dev/scsireg.h>
27 
28 struct	disklabel sdlabel;
29 
30 struct	sdminilabel {
31 	u_short	npart;
32 	u_long	offset[MAXPARTITIONS];
33 };
34 
35 struct	sd_softc {
36 	char	sc_retry;
37 	char	sc_alive;
38 	short	sc_blkshift;
39 	struct	sdminilabel sc_pinfo;
40 } sd_softc[NSCSI][NSD];
41 
42 #define	SDRETRY		2
43 
44 sdinit(ctlr, unit)
45 	int ctlr, unit;
46 {
47 	register struct sd_softc *ss = &sd_softc[ctlr][unit];
48 	u_char stat;
49 	int capbuf[2];
50 
51 	stat = scsi_test_unit_rdy(ctlr, unit);
52 	if (stat) {
53 		/* drive may be doing RTZ - wait a bit */
54 		if (stat == STS_CHECKCOND) {
55 			DELAY(1000000);
56 			stat = scsi_test_unit_rdy(ctlr, unit);
57 		}
58 		if (stat) {
59 			printf("sd(%d,%d,0,0): init failed (stat=%x)\n",
60 			       ctlr, unit, stat);
61 			return (0);
62 		}
63 	}
64 	/*
65 	 * try to get the drive block size.
66 	 */
67 	capbuf[0] = 0;
68 	capbuf[1] = 0;
69 	stat = scsi_read_capacity(ctlr, unit,
70 				  (u_char *)capbuf, sizeof(capbuf));
71 	if (stat == 0) {
72 		if (capbuf[1] > DEV_BSIZE)
73 			for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1)
74 				++ss->sc_blkshift;
75 	}
76 	ss->sc_alive = 1;
77 	return (1);
78 }
79 
80 sdreset(ctlr, unit)
81 	int ctlr, unit;
82 {
83 }
84 
85 #ifdef COMPAT_NOLABEL
86 struct	sdminilabel defaultpinfo = {
87 	8,
88 	{ 1024, 17408, 0, 17408, 115712, 218112, 82944, 115712 }
89 };
90 #endif
91 
92 sdgetinfo(io)
93 	register struct iob *io;
94 {
95 	struct sd_softc *ss = &sd_softc[io->i_adapt][io->i_ctlr];
96 	register struct sdminilabel *pi = &ss->sc_pinfo;
97 	register struct disklabel *lp = &sdlabel;
98 	char *msg, *readdisklabel();
99 	int sdstrategy(), i;
100 
101 	bzero((caddr_t)lp, sizeof *lp);
102 	lp->d_secsize = (DEV_BSIZE << ss->sc_blkshift);
103 	msg = readdisklabel(io, sdstrategy, lp);
104 	if (msg) {
105 		printf("sd(%d,%d,%d,%d): WARNING: %s, ",
106 		       io->i_adapt, io->i_ctlr, io->i_unit, io->i_part, msg);
107 #ifdef COMPAT_NOLABEL
108 		printf("using old default partitioning\n");
109 		*pi = defaultpinfo;
110 #else
111 		printf("defining `c' partition as entire disk\n");
112 		pi->npart = 3;
113 		pi->offset[0] = pi->offset[1] = -1;
114 		pi->offset[2] = 0;
115 #endif
116 	} else {
117 		pi->npart = lp->d_npartitions;
118 		for (i = 0; i < pi->npart; i++)
119 			pi->offset[i] = lp->d_partitions[i].p_size == 0 ?
120 				-1 : lp->d_partitions[i].p_offset;
121 	}
122 	return(1);
123 }
124 
125 sdopen(io)
126 	struct iob *io;
127 {
128 	register struct sd_softc *ss;
129 	int ctlr, unit, part;
130 
131 	devconvert(io);
132 
133 	ctlr = io->i_adapt;
134 	if (ctlr >= NSCSI || scsialive(ctlr) == 0)
135 		return (EADAPT);
136 	unit = io->i_ctlr;
137 	if (unit >= NSD)
138 		return (ECTLR);
139 	ss = &sd_softc[ctlr][unit];
140 	if (ss->sc_alive == 0) {
141 		if (sdinit(ctlr, unit) == 0)
142 			return (ENXIO);
143 		if (sdgetinfo(io) == 0)
144 			return (ERDLAB);
145 	}
146 	part = io->i_part;
147 	if (part >= ss->sc_pinfo.npart || ss->sc_pinfo.offset[part] == -1)
148 		return (EPART);
149 	io->i_boff = ss->sc_pinfo.offset[part];
150 	return (0);
151 }
152 
153 sdstrategy(io, func)
154 	register struct iob *io;
155 	int func;
156 {
157 	register int ctlr = io->i_adapt;
158 	register int unit = io->i_ctlr;
159 	register struct sd_softc *ss = &sd_softc[ctlr][unit];
160 	daddr_t blk = io->i_bn >> ss->sc_blkshift;
161 	u_int nblk = io->i_cc >> ss->sc_blkshift;
162 	char stat;
163 
164 	if (io->i_cc == 0)
165 		return(0);
166 
167 	ss->sc_retry = 0;
168 retry:
169 	if (func == F_READ)
170 		stat = scsi_tt_read(ctlr, unit, io->i_ma, io->i_cc, blk, nblk);
171 	else
172 		stat = scsi_tt_write(ctlr, unit, io->i_ma, io->i_cc, blk, nblk);
173 	if (stat) {
174 		printf("sd(%d,%d,%d,%d): block=%x, error=0x%x\n",
175 		       ctlr, unit, io->i_unit, io->i_part, blk, stat);
176 		if (++ss->sc_retry > SDRETRY)
177 			return(-1);
178 		goto retry;
179 	}
180 	return(io->i_cc);
181 }
182