xref: /original-bsd/sys/hp300/dev/sd.c (revision 609cdd5c)
1 /*
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Van Jacobson of Lawrence Berkeley Laboratory.
7  *
8  * %sccs.include.redist.c%
9  *
10  *	@(#)sd.c	7.18 (Berkeley) 02/18/93
11  */
12 
13 /*
14  * SCSI CCS (Command Command Set) disk driver.
15  */
16 #include "sd.h"
17 #if NSD > 0
18 
19 #ifndef lint
20 static char rcsid[] = "$Header: /usr/src/sys/hp300/dev/RCS/sd.c,v 1.4 92/12/26 13:26:40 mike Exp $";
21 #endif
22 
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/buf.h>
26 #include <sys/stat.h>
27 #include <sys/dkstat.h>
28 #include <sys/disklabel.h>
29 #include <sys/malloc.h>
30 #include <sys/proc.h>
31 #include <sys/ioctl.h>
32 #include <sys/fcntl.h>
33 
34 #include <hp/dev/device.h>
35 #include <hp300/dev/scsireg.h>
36 #include <hp300/dev/sdvar.h>
37 #ifdef USELEDS
38 #include <hp300/hp300/led.h>
39 #endif
40 
41 #include <vm/vm_param.h>
42 #include <vm/lock.h>
43 #include <vm/vm_prot.h>
44 #include <vm/pmap.h>
45 
46 extern int scsi_test_unit_rdy();
47 extern int scsi_request_sense();
48 extern int scsi_inquiry();
49 extern int scsi_read_capacity();
50 extern int scsi_tt_write();
51 extern int scsireq();
52 extern int scsiustart();
53 extern int scsigo();
54 extern void scsifree();
55 extern void scsireset();
56 extern void scsi_delay();
57 
58 extern void disksort();
59 extern void biodone();
60 extern int physio();
61 extern void TBIS();
62 
63 int	sdinit();
64 void	sdstrategy(), sdstart(), sdustart(), sdgo(), sdintr();
65 
66 struct	driver sddriver = {
67 	sdinit, "sd", (int (*)())sdstart, (int (*)())sdgo, (int (*)())sdintr,
68 };
69 
70 #ifdef DEBUG
71 int sddebug = 1;
72 #define SDB_ERROR	0x01
73 #define SDB_PARTIAL	0x02
74 #endif
75 
76 struct	sd_softc sd_softc[NSD];
77 struct	sdstats sdstats[NSD];
78 struct	buf sdtab[NSD];
79 struct	scsi_fmt_cdb sdcmd[NSD];
80 struct	scsi_fmt_sense sdsense[NSD];
81 
82 static struct scsi_fmt_cdb sd_read_cmd = { 10, CMD_READ_EXT };
83 static struct scsi_fmt_cdb sd_write_cmd = { 10, CMD_WRITE_EXT };
84 
85 /*
86  * Table of scsi commands users are allowed to access via "format"
87  * mode.  0 means not legal.  1 means "immediate" (doesn't need dma).
88  * -1 means needs dma and/or wait for intr.
89  */
90 static char legal_cmds[256] = {
91 /*****  0   1   2   3   4   5   6   7     8   9   A   B   C   D   E   F */
92 /*00*/	0,  0,  0,  0, -1,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
93 /*10*/	0,  0,  1,  0,  0,  1,  0,  0,    0,  0,  1,  0,  0,  0,  0,  0,
94 /*20*/	0,  0,  0,  0,  0,  1,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
95 /*30*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
96 /*40*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
97 /*50*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
98 /*60*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
99 /*70*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
100 /*80*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
101 /*90*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
102 /*a0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
103 /*b0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
104 /*c0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
105 /*d0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
106 /*e0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
107 /*f0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
108 };
109 
110 static struct scsi_inquiry inqbuf;
111 static struct scsi_fmt_cdb inq = {
112 	6,
113 	CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0
114 };
115 
116 static u_char capbuf[8];
117 struct scsi_fmt_cdb cap = {
118 	10,
119 	CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0
120 };
121 
122 static int
123 sdident(sc, hd)
124 	struct sd_softc *sc;
125 	struct hp_device *hd;
126 {
127 	int unit;
128 	register int ctlr, slave;
129 	register int i;
130 	register int tries = 10;
131 	char idstr[32];
132 	int ismo = 0;
133 
134 	ctlr = hd->hp_ctlr;
135 	slave = hd->hp_slave;
136 	unit = sc->sc_punit;
137 	scsi_delay(-1);
138 
139 	/*
140 	 * See if unit exists and is a disk then read block size & nblocks.
141 	 */
142 	while ((i = scsi_test_unit_rdy(ctlr, slave, unit)) != 0) {
143 		if (i == -1 || --tries < 0) {
144 			if (ismo)
145 				break;
146 			/* doesn't exist or not a CCS device */
147 			goto failed;
148 		}
149 		if (i == STS_CHECKCOND) {
150 			u_char sensebuf[128];
151 			struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf;
152 
153 			scsi_request_sense(ctlr, slave, unit, sensebuf,
154 					   sizeof(sensebuf));
155 			if (sp->class == 7)
156 				switch (sp->key) {
157 				/* not ready -- might be MO with no media */
158 				case 2:
159 					if (sp->len == 12 &&
160 					    sensebuf[12] == 10)	/* XXX */
161 						ismo = 1;
162 					break;
163 				/* drive doing an RTZ -- give it a while */
164 				case 6:
165 					DELAY(1000000);
166 					break;
167 				default:
168 					break;
169 				}
170 		}
171 		DELAY(1000);
172 	}
173 	/*
174 	 * Find out about device
175 	 */
176 	if (scsi_immed_command(ctlr, slave, unit, &inq,
177 			       (u_char *)&inqbuf, sizeof(inqbuf), B_READ))
178 		goto failed;
179 	switch (inqbuf.type) {
180 	case 0:		/* disk */
181 	case 4:		/* WORM */
182 	case 5:		/* CD-ROM */
183 	case 7:		/* Magneto-optical */
184 		break;
185 	default:	/* not a disk */
186 		goto failed;
187 	}
188 	/*
189 	 * Get a usable id string
190 	 */
191 	switch (inqbuf.version) {
192 	case 1:
193 	case 2:
194 		bcopy((caddr_t)&inqbuf.vendor_id, (caddr_t)idstr, 28);
195 		for (i = 27; i > 23; --i)
196 			if (idstr[i] != ' ')
197 				break;
198 		idstr[i+1] = 0;
199 		for (i = 23; i > 7; --i)
200 			if (idstr[i] != ' ')
201 				break;
202 		idstr[i+1] = 0;
203 		for (i = 7; i >= 0; --i)
204 			if (idstr[i] != ' ')
205 				break;
206 		idstr[i+1] = 0;
207 		break;
208 	default:
209 		bcopy("UNKNOWN", &idstr[0], 8);
210 		bcopy("DRIVE TYPE", &idstr[8], 11);
211 	}
212 	i = scsi_immed_command(ctlr, slave, unit, &cap,
213 			       (u_char *)&capbuf, sizeof(capbuf), B_READ);
214 	if (i) {
215 		if (i != STS_CHECKCOND ||
216 		    bcmp(&idstr[0], "HP", 3) ||
217 		    bcmp(&idstr[8], "S6300.650A", 11))
218 			goto failed;
219 		/* XXX unformatted or non-existant MO media; fake it */
220 		sc->sc_blks = 318664;
221 		sc->sc_blksize = 1024;
222 	} else {
223 		sc->sc_blks = *(u_int *)&capbuf[0];
224 		sc->sc_blksize = *(int *)&capbuf[4];
225 	}
226 	/* return value of read capacity is last valid block number */
227 	sc->sc_blks++;
228 
229 	switch (inqbuf.version) {
230 	case 1:
231 	case 2:
232 		printf("sd%d: %s %s rev %s", hd->hp_unit, idstr, &idstr[8],
233 			&idstr[24]);
234 		if (inqbuf.version == 2)
235 			printf(" (SCSI-2)");
236 		break;
237 	default:
238 		printf("sd%d: type 0x%x, qual 0x%x, ver %d", hd->hp_unit,
239 		       inqbuf.type, inqbuf.qual, inqbuf.version);
240 		break;
241 	}
242 	printf(", %d %d byte blocks\n", sc->sc_blks, sc->sc_blksize);
243 	if (inqbuf.qual & 0x80)
244 		sc->sc_flags |= SDF_RMEDIA;
245 	if (sc->sc_blksize != DEV_BSIZE) {
246 		if (sc->sc_blksize < DEV_BSIZE) {
247 			printf("sd%d: need %d byte blocks - drive ignored\n",
248 				unit, DEV_BSIZE);
249 			goto failed;
250 		}
251 		for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1)
252 			++sc->sc_bshift;
253 		sc->sc_blks <<= sc->sc_bshift;
254 	}
255 	sc->sc_wpms = 32 * (60 * DEV_BSIZE / 2);	/* XXX */
256 	scsi_delay(0);
257 	return(inqbuf.type);
258 failed:
259 	scsi_delay(0);
260 	return(-1);
261 }
262 
263 int
264 sdinit(hd)
265 	register struct hp_device *hd;
266 {
267 	register struct sd_softc *sc = &sd_softc[hd->hp_unit];
268 
269 	sc->sc_hd = hd;
270 	sc->sc_flags = 0;
271 	sc->sc_punit = sdpunit(hd->hp_flags);
272 	sc->sc_type = sdident(sc, hd);
273 	if (sc->sc_type < 0)
274 		return(0);
275 	sc->sc_dq.dq_ctlr = hd->hp_ctlr;
276 	sc->sc_dq.dq_unit = hd->hp_unit;
277 	sc->sc_dq.dq_slave = hd->hp_slave;
278 	sc->sc_dq.dq_driver = &sddriver;
279 
280 	sc->sc_flags |= SDF_ALIVE;
281 	return(1);
282 }
283 
284 void
285 sdreset(sc, hd)
286 	register struct sd_softc *sc;
287 	register struct hp_device *hd;
288 {
289 	sdstats[hd->hp_unit].sdresets++;
290 }
291 
292 /*
293  * Read or constuct a disklabel
294  */
295 int
296 sdgetinfo(dev)
297 	dev_t dev;
298 {
299 	int unit = sdunit(dev);
300 	register struct sd_softc *sc = &sd_softc[unit];
301 	register struct disklabel *lp = &sc->sc_info.si_label;
302 	register struct partition *pi;
303 	char *msg, *readdisklabel();
304 
305 	/*
306 	 * Set some default values to use while reading the label
307 	 * or to use if there isn't a label.
308 	 */
309 	bzero((caddr_t)lp, sizeof *lp);
310 	lp->d_type = DTYPE_SCSI;
311 	lp->d_secsize = DEV_BSIZE;
312 	lp->d_nsectors = 32;
313 	lp->d_ntracks = 20;
314 	lp->d_ncylinders = 1;
315 	lp->d_secpercyl = 32*20;
316 	lp->d_npartitions = 3;
317 	lp->d_partitions[2].p_offset = 0;
318 	/* XXX we can open a device even without SDF_ALIVE */
319 	if (sc->sc_blksize == 0)
320 		sc->sc_blksize = DEV_BSIZE;
321 	/* XXX ensure size is at least one device block */
322 	lp->d_partitions[2].p_size =
323 		roundup(LABELSECTOR+1, btodb(sc->sc_blksize));
324 
325 	/*
326 	 * Now try to read the disklabel
327 	 */
328 	msg = readdisklabel(sdlabdev(dev), sdstrategy, lp);
329 	if (msg == NULL)
330 		return(0);
331 	if (bcmp(msg, "I/O", 3) == 0) /* XXX */
332 		return(EIO);
333 
334 	pi = lp->d_partitions;
335 	printf("sd%d: WARNING: %s, ", unit, msg);
336 #ifdef COMPAT_NOLABEL
337 	printf("using old default partitioning\n");
338 	sdmakedisklabel(unit, lp);
339 #else
340 	printf("defining `c' partition as entire disk\n");
341 	pi[2].p_size = sc->sc_blks;
342 #endif
343 	return(0);
344 }
345 
346 int
347 sdopen(dev, flags, mode, p)
348 	dev_t dev;
349 	int flags, mode;
350 	struct proc *p;
351 {
352 	register int unit = sdunit(dev);
353 	register struct sd_softc *sc = &sd_softc[unit];
354 	int mask, error;
355 
356 	if (unit >= NSD)
357 		return(ENXIO);
358 	if ((sc->sc_flags & SDF_ALIVE) == 0 && suser(p->p_ucred, &p->p_acflag))
359 		return(ENXIO);
360 	if (sc->sc_flags & SDF_ERROR)
361 		return(EIO);
362 
363 	/*
364 	 * Wait for any pending opens/closes to complete
365 	 */
366 	while (sc->sc_flags & (SDF_OPENING|SDF_CLOSING))
367 		sleep((caddr_t)sc, PRIBIO);
368 	/*
369 	 * On first open, get label and partition info.
370 	 * We may block reading the label, so be careful
371 	 * to stop any other opens.
372 	 */
373 	if (sc->sc_info.si_open == 0) {
374 		sc->sc_flags |= SDF_OPENING;
375 		error = sdgetinfo(dev);
376 		sc->sc_flags &= ~SDF_OPENING;
377 		wakeup((caddr_t)sc);
378 		if (error)
379 			return(error);
380 	}
381 	if (sc->sc_hd->hp_dk >= 0)
382 		dk_wpms[sc->sc_hd->hp_dk] = sc->sc_wpms;
383 
384 	mask = 1 << sdpart(dev);
385 	if (mode == S_IFCHR)
386 		sc->sc_info.si_copen |= mask;
387 	else
388 		sc->sc_info.si_bopen |= mask;
389 	sc->sc_info.si_open |= mask;
390 	return(0);
391 }
392 
393 int
394 sdclose(dev, flag, mode, p)
395 	dev_t dev;
396 	int flag, mode;
397 	struct proc *p;
398 {
399 	int unit = sdunit(dev);
400 	register struct sd_softc *sc = &sd_softc[unit];
401 	register struct sdinfo *si = &sc->sc_info;
402 	int mask, s;
403 
404 	mask = 1 << sdpart(dev);
405 	if (mode == S_IFCHR)
406 		si->si_copen &= ~mask;
407 	else
408 		si->si_bopen &= ~mask;
409 	si->si_open = si->si_bopen | si->si_copen;
410 	/*
411 	 * On last close, we wait for all activity to cease since
412 	 * the label/parition info will become invalid.  Since we
413 	 * might sleep, we must block any opens while we are here.
414 	 * Note we don't have to about other closes since we know
415 	 * we are the last one.
416 	 */
417 	if (si->si_open == 0) {
418 		sc->sc_flags |= SDF_CLOSING;
419 		s = splbio();
420 		while (sdtab[unit].b_active) {
421 			sc->sc_flags |= SDF_WANTED;
422 			sleep((caddr_t)&sdtab[unit], PRIBIO);
423 		}
424 		splx(s);
425 		sc->sc_flags &= ~(SDF_CLOSING|SDF_WLABEL|SDF_ERROR);
426 		wakeup((caddr_t)sc);
427 	}
428 	sc->sc_format_pid = 0;
429 	return(0);
430 }
431 
432 /*
433  * This routine is called for partial block transfers and non-aligned
434  * transfers (the latter only being possible on devices with a block size
435  * larger than DEV_BSIZE).  The operation is performed in three steps
436  * using a locally allocated buffer:
437  *	1. transfer any initial partial block
438  *	2. transfer full blocks
439  *	3. transfer any final partial block
440  */
441 static void
442 sdlblkstrat(bp, bsize)
443 	register struct buf *bp;
444 	register int bsize;
445 {
446 	register struct buf *cbp = (struct buf *)malloc(sizeof(struct buf),
447 							M_DEVBUF, M_WAITOK);
448 	caddr_t cbuf = (caddr_t)malloc(bsize, M_DEVBUF, M_WAITOK);
449 	register int bn, resid;
450 	register caddr_t addr;
451 
452 	bzero((caddr_t)cbp, sizeof(*cbp));
453 	cbp->b_proc = curproc;		/* XXX */
454 	cbp->b_dev = bp->b_dev;
455 	bn = bp->b_blkno;
456 	resid = bp->b_bcount;
457 	addr = bp->b_un.b_addr;
458 #ifdef DEBUG
459 	if (sddebug & SDB_PARTIAL)
460 		printf("sdlblkstrat: bp %x flags %x bn %x resid %x addr %x\n",
461 		       bp, bp->b_flags, bn, resid, addr);
462 #endif
463 
464 	while (resid > 0) {
465 		register int boff = dbtob(bn) & (bsize - 1);
466 		register int count;
467 
468 		if (boff || resid < bsize) {
469 			sdstats[sdunit(bp->b_dev)].sdpartials++;
470 			count = min(resid, bsize - boff);
471 			cbp->b_flags = B_BUSY | B_PHYS | B_READ;
472 			cbp->b_blkno = bn - btodb(boff);
473 			cbp->b_un.b_addr = cbuf;
474 			cbp->b_bcount = bsize;
475 #ifdef DEBUG
476 			if (sddebug & SDB_PARTIAL)
477 				printf(" readahead: bn %x cnt %x off %x addr %x\n",
478 				       cbp->b_blkno, count, boff, addr);
479 #endif
480 			sdstrategy(cbp);
481 			biowait(cbp);
482 			if (cbp->b_flags & B_ERROR) {
483 				bp->b_flags |= B_ERROR;
484 				bp->b_error = cbp->b_error;
485 				break;
486 			}
487 			if (bp->b_flags & B_READ) {
488 				bcopy(&cbuf[boff], addr, count);
489 				goto done;
490 			}
491 			bcopy(addr, &cbuf[boff], count);
492 #ifdef DEBUG
493 			if (sddebug & SDB_PARTIAL)
494 				printf(" writeback: bn %x cnt %x off %x addr %x\n",
495 				       cbp->b_blkno, count, boff, addr);
496 #endif
497 		} else {
498 			count = resid & ~(bsize - 1);
499 			cbp->b_blkno = bn;
500 			cbp->b_un.b_addr = addr;
501 			cbp->b_bcount = count;
502 #ifdef DEBUG
503 			if (sddebug & SDB_PARTIAL)
504 				printf(" fulltrans: bn %x cnt %x addr %x\n",
505 				       cbp->b_blkno, count, addr);
506 #endif
507 		}
508 		cbp->b_flags = B_BUSY | B_PHYS | (bp->b_flags & B_READ);
509 		sdstrategy(cbp);
510 		biowait(cbp);
511 		if (cbp->b_flags & B_ERROR) {
512 			bp->b_flags |= B_ERROR;
513 			bp->b_error = cbp->b_error;
514 			break;
515 		}
516 done:
517 		bn += btodb(count);
518 		resid -= count;
519 		addr += count;
520 #ifdef DEBUG
521 		if (sddebug & SDB_PARTIAL)
522 			printf(" done: bn %x resid %x addr %x\n",
523 			       bn, resid, addr);
524 #endif
525 	}
526 	free(cbuf, M_DEVBUF);
527 	free(cbp, M_DEVBUF);
528 }
529 
530 void
531 sdstrategy(bp)
532 	register struct buf *bp;
533 {
534 	int unit = sdunit(bp->b_dev);
535 	register struct sd_softc *sc = &sd_softc[unit];
536 	register struct buf *dp = &sdtab[unit];
537 	register struct partition *pinfo;
538 	register daddr_t bn;
539 	register int sz, s;
540 
541 	if (sc->sc_flags & SDF_ERROR) {
542 		bp->b_error = EIO;
543 		goto bad;
544 	}
545 	if (sc->sc_format_pid) {
546 		if (sc->sc_format_pid != curproc->p_pid) {	/* XXX */
547 			bp->b_error = EPERM;
548 			goto bad;
549 		}
550 		bp->b_cylin = 0;
551 	} else {
552 		bn = bp->b_blkno;
553 		sz = howmany(bp->b_bcount, DEV_BSIZE);
554 		pinfo = &sc->sc_info.si_label.d_partitions[sdpart(bp->b_dev)];
555 		if (bn < 0 || bn + sz > pinfo->p_size) {
556 			sz = pinfo->p_size - bn;
557 			if (sz == 0) {
558 				bp->b_resid = bp->b_bcount;
559 				goto done;
560 			}
561 			if (sz < 0) {
562 				bp->b_error = EINVAL;
563 				goto bad;
564 			}
565 			bp->b_bcount = dbtob(sz);
566 		}
567 		/*
568 		 * Check for write to write protected label
569 		 */
570 		if (bn + pinfo->p_offset <= LABELSECTOR &&
571 #if LABELSECTOR != 0
572 		    bn + pinfo->p_offset + sz > LABELSECTOR &&
573 #endif
574 		    !(bp->b_flags & B_READ) && !(sc->sc_flags & SDF_WLABEL)) {
575 			bp->b_error = EROFS;
576 			goto bad;
577 		}
578 		/*
579 		 * Non-aligned or partial-block transfers handled specially.
580 		 */
581 		s = sc->sc_blksize - 1;
582 		if ((dbtob(bn) & s) || (bp->b_bcount & s)) {
583 			sdlblkstrat(bp, sc->sc_blksize);
584 			goto done;
585 		}
586 		bp->b_cylin = (bn + pinfo->p_offset) >> sc->sc_bshift;
587 	}
588 	s = splbio();
589 	disksort(dp, bp);
590 	if (dp->b_active == 0) {
591 		dp->b_active = 1;
592 		sdustart(unit);
593 	}
594 	splx(s);
595 	return;
596 bad:
597 	bp->b_flags |= B_ERROR;
598 done:
599 	biodone(bp);
600 }
601 
602 void
603 sdustart(unit)
604 	register int unit;
605 {
606 	if (scsireq(&sd_softc[unit].sc_dq))
607 		sdstart(unit);
608 }
609 
610 /*
611  * Return:
612  *	0	if not really an error
613  *	<0	if we should do a retry
614  *	>0	if a fatal error
615  */
616 static int
617 sderror(unit, sc, hp, stat)
618 	int unit, stat;
619 	register struct sd_softc *sc;
620 	register struct hp_device *hp;
621 {
622 	int cond = 1;
623 
624 	sdsense[unit].status = stat;
625 	if (stat & STS_CHECKCOND) {
626 		struct scsi_xsense *sp;
627 
628 		scsi_request_sense(hp->hp_ctlr, hp->hp_slave,
629 				   sc->sc_punit, sdsense[unit].sense,
630 				   sizeof(sdsense[unit].sense));
631 		sp = (struct scsi_xsense *)sdsense[unit].sense;
632 		printf("sd%d: scsi sense class %d, code %d", unit,
633 			sp->class, sp->code);
634 		if (sp->class == 7) {
635 			printf(", key %d", sp->key);
636 			if (sp->valid)
637 				printf(", blk %d", *(int *)&sp->info1);
638 			switch (sp->key) {
639 			/* no sense, try again */
640 			case 0:
641 				cond = -1;
642 				break;
643 			/* recovered error, not a problem */
644 			case 1:
645 				cond = 0;
646 				break;
647 			/* possible media change */
648 			case 6:
649 				/*
650 				 * For removable media, if we are doing the
651 				 * first open (i.e. reading the label) go
652 				 * ahead and retry, otherwise someone has
653 				 * changed the media out from under us and
654 				 * we should abort any further operations
655 				 * until a close is done.
656 				 */
657 				if (sc->sc_flags & SDF_RMEDIA) {
658 					if (sc->sc_flags & SDF_OPENING)
659 						cond = -1;
660 					else
661 						sc->sc_flags |= SDF_ERROR;
662 				}
663 				break;
664 			}
665 		}
666 		printf("\n");
667 	}
668 	return(cond);
669 }
670 
671 static void
672 sdfinish(unit, sc, bp)
673 	int unit;
674 	register struct sd_softc *sc;
675 	register struct buf *bp;
676 {
677 	register struct buf *dp = &sdtab[unit];
678 
679 	dp->b_errcnt = 0;
680 	dp->b_actf = bp->b_actf;
681 	bp->b_resid = 0;
682 	biodone(bp);
683 	scsifree(&sc->sc_dq);
684 	if (dp->b_actf)
685 		sdustart(unit);
686 	else {
687 		dp->b_active = 0;
688 		if (sc->sc_flags & SDF_WANTED) {
689 			sc->sc_flags &= ~SDF_WANTED;
690 			wakeup((caddr_t)dp);
691 		}
692 	}
693 }
694 
695 void
696 sdstart(unit)
697 	register int unit;
698 {
699 	register struct sd_softc *sc = &sd_softc[unit];
700 	register struct hp_device *hp = sc->sc_hd;
701 
702 	/*
703 	 * we have the SCSI bus -- in format mode, we may or may not need dma
704 	 * so check now.
705 	 */
706 	if (sc->sc_format_pid && legal_cmds[sdcmd[unit].cdb[0]] > 0) {
707 		register struct buf *bp = sdtab[unit].b_actf;
708 		register int sts;
709 
710 		sts = scsi_immed_command(hp->hp_ctlr, hp->hp_slave,
711 					 sc->sc_punit, &sdcmd[unit],
712 					 bp->b_un.b_addr, bp->b_bcount,
713 					 bp->b_flags & B_READ);
714 		sdsense[unit].status = sts;
715 		if (sts & 0xfe) {
716 			(void) sderror(unit, sc, hp, sts);
717 			bp->b_flags |= B_ERROR;
718 			bp->b_error = EIO;
719 		}
720 		sdfinish(unit, sc, bp);
721 
722 	} else if (scsiustart(hp->hp_ctlr))
723 		sdgo(unit);
724 }
725 
726 void
727 sdgo(unit)
728 	register int unit;
729 {
730 	register struct sd_softc *sc = &sd_softc[unit];
731 	register struct hp_device *hp = sc->sc_hd;
732 	register struct buf *bp = sdtab[unit].b_actf;
733 	register int pad;
734 	register struct scsi_fmt_cdb *cmd;
735 
736 	/*
737 	 * Drive is in an error state, abort all operations
738 	 */
739 	if (sc->sc_flags & SDF_ERROR) {
740 		bp->b_flags |= B_ERROR;
741 		bp->b_error = EIO;
742 		sdfinish(unit, sc, bp);
743 		return;
744 	}
745 	if (sc->sc_format_pid) {
746 		cmd = &sdcmd[unit];
747 		pad = 0;
748 	} else {
749 		cmd = bp->b_flags & B_READ? &sd_read_cmd : &sd_write_cmd;
750 		*(int *)(&cmd->cdb[2]) = bp->b_cylin;
751 		pad = howmany(bp->b_bcount, sc->sc_blksize);
752 		*(u_short *)(&cmd->cdb[7]) = pad;
753 		pad = (bp->b_bcount & (sc->sc_blksize - 1)) != 0;
754 #ifdef DEBUG
755 		if (pad)
756 			printf("sd%d: partial block xfer -- %x bytes\n",
757 			       unit, bp->b_bcount);
758 #endif
759 		sdstats[unit].sdtransfers++;
760 	}
761 #ifdef USELEDS
762 	if (inledcontrol == 0)
763 		ledcontrol(0, 0, LED_DISK);
764 #endif
765 	if (scsigo(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, bp, cmd, pad) == 0) {
766 		if (hp->hp_dk >= 0) {
767 			dk_busy |= 1 << hp->hp_dk;
768 			++dk_seek[hp->hp_dk];
769 			++dk_xfer[hp->hp_dk];
770 			dk_wds[hp->hp_dk] += bp->b_bcount >> 6;
771 		}
772 		return;
773 	}
774 #ifdef DEBUG
775 	if (sddebug & SDB_ERROR)
776 		printf("sd%d: sdstart: %s adr %d blk %d len %d ecnt %d\n",
777 		       unit, bp->b_flags & B_READ? "read" : "write",
778 		       bp->b_un.b_addr, bp->b_cylin, bp->b_bcount,
779 		       sdtab[unit].b_errcnt);
780 #endif
781 	bp->b_flags |= B_ERROR;
782 	bp->b_error = EIO;
783 	sdfinish(unit, sc, bp);
784 }
785 
786 void
787 sdintr(unit, stat)
788 	register int unit;
789 	int stat;
790 {
791 	register struct sd_softc *sc = &sd_softc[unit];
792 	register struct buf *bp = sdtab[unit].b_actf;
793 	register struct hp_device *hp = sc->sc_hd;
794 	int cond;
795 
796 	if (bp == NULL) {
797 		printf("sd%d: bp == NULL\n", unit);
798 		return;
799 	}
800 	if (hp->hp_dk >= 0)
801 		dk_busy &=~ (1 << hp->hp_dk);
802 	if (stat) {
803 #ifdef DEBUG
804 		if (sddebug & SDB_ERROR)
805 			printf("sd%d: sdintr: bad scsi status 0x%x\n",
806 				unit, stat);
807 #endif
808 		cond = sderror(unit, sc, hp, stat);
809 		if (cond) {
810 			if (cond < 0 && sdtab[unit].b_errcnt++ < SDRETRY) {
811 #ifdef DEBUG
812 				if (sddebug & SDB_ERROR)
813 					printf("sd%d: retry #%d\n",
814 					       unit, sdtab[unit].b_errcnt);
815 #endif
816 				sdstart(unit);
817 				return;
818 			}
819 			bp->b_flags |= B_ERROR;
820 			bp->b_error = EIO;
821 		}
822 	}
823 	sdfinish(unit, sc, bp);
824 }
825 
826 int
827 sdread(dev, uio, flags)
828 	dev_t dev;
829 	struct uio *uio;
830 	int flags;
831 {
832 	register int unit = sdunit(dev);
833 	register int pid;
834 
835 	if ((pid = sd_softc[unit].sc_format_pid) &&
836 	    pid != uio->uio_procp->p_pid)
837 		return (EPERM);
838 
839 	return (physio(sdstrategy, NULL, dev, B_READ, minphys, uio));
840 }
841 
842 int
843 sdwrite(dev, uio, flags)
844 	dev_t dev;
845 	struct uio *uio;
846 	int flags;
847 {
848 	register int unit = sdunit(dev);
849 	register int pid;
850 
851 	if ((pid = sd_softc[unit].sc_format_pid) &&
852 	    pid != uio->uio_procp->p_pid)
853 		return (EPERM);
854 
855 	return (physio(sdstrategy, NULL, dev, B_WRITE, minphys, uio));
856 }
857 
858 int
859 sdioctl(dev, cmd, data, flag, p)
860 	dev_t dev;
861 	int cmd;
862 	caddr_t data;
863 	int flag;
864 	struct proc *p;
865 {
866 	int unit = sdunit(dev);
867 	register struct sd_softc *sc = &sd_softc[unit];
868 	register struct disklabel *lp = &sc->sc_info.si_label;
869 	int error, flags;
870 
871 	switch (cmd) {
872 	default:
873 		return (EINVAL);
874 
875 	case DIOCGDINFO:
876 		*(struct disklabel *)data = *lp;
877 		return (0);
878 
879 	case DIOCGPART:
880 		((struct partinfo *)data)->disklab = lp;
881 		((struct partinfo *)data)->part =
882 			&lp->d_partitions[sdpart(dev)];
883 		return (0);
884 
885         case DIOCWLABEL:
886                 if ((flag & FWRITE) == 0)
887                         return (EBADF);
888 		if (*(int *)data)
889 			sc->sc_flags |= SDF_WLABEL;
890 		else
891 			sc->sc_flags &= ~SDF_WLABEL;
892 		return (0);
893 
894         case DIOCSDINFO:
895                 if ((flag & FWRITE) == 0)
896                         return (EBADF);
897 		error = setdisklabel(lp, (struct disklabel *)data,
898 				     (sc->sc_flags & SDF_WLABEL) ? 0
899 				     : sc->sc_info.si_open);
900 		return (error);
901 
902         case DIOCWDINFO:
903 		if ((flag & FWRITE) == 0)
904 			return (EBADF);
905 		error = setdisklabel(lp, (struct disklabel *)data,
906 				     (sc->sc_flags & SDF_WLABEL) ? 0
907 				     : sc->sc_info.si_open);
908 		if (error)
909 			return (error);
910 		flags = sc->sc_flags;
911 		sc->sc_flags = SDF_ALIVE | SDF_WLABEL;
912 		error = writedisklabel(sdlabdev(dev), sdstrategy, lp);
913 		sc->sc_flags = flags;
914 		return (error);
915 
916 	case SDIOCSFORMAT:
917 		/* take this device into or out of "format" mode */
918 		if (suser(p->p_ucred, &p->p_acflag))
919 			return(EPERM);
920 
921 		if (*(int *)data) {
922 			if (sc->sc_format_pid)
923 				return (EPERM);
924 			sc->sc_format_pid = p->p_pid;
925 		} else
926 			sc->sc_format_pid = 0;
927 		return (0);
928 
929 	case SDIOCGFORMAT:
930 		/* find out who has the device in format mode */
931 		*(int *)data = sc->sc_format_pid;
932 		return (0);
933 
934 	case SDIOCSCSICOMMAND:
935 		/*
936 		 * Save what user gave us as SCSI cdb to use with next
937 		 * read or write to the char device.
938 		 */
939 		if (sc->sc_format_pid != p->p_pid)
940 			return (EPERM);
941 		if (legal_cmds[((struct scsi_fmt_cdb *)data)->cdb[0]] == 0)
942 			return (EINVAL);
943 		bcopy(data, (caddr_t)&sdcmd[unit], sizeof(sdcmd[0]));
944 		return (0);
945 
946 	case SDIOCSENSE:
947 		/*
948 		 * return the SCSI sense data saved after the last
949 		 * operation that completed with "check condition" status.
950 		 */
951 		bcopy((caddr_t)&sdsense[unit], data, sizeof(sdsense[0]));
952 		return (0);
953 
954 	}
955 	/*NOTREACHED*/
956 }
957 
958 int
959 sdsize(dev)
960 	dev_t dev;
961 {
962 	register int unit = sdunit(dev);
963 	register struct sd_softc *sc = &sd_softc[unit];
964 	int psize, didopen = 0;
965 
966 	if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0)
967 		return(-1);
968 
969 	/*
970 	 * We get called very early on (via swapconf)
971 	 * without the device being open so we may need
972 	 * to handle it here.
973 	 */
974 	if (sc->sc_info.si_open == 0) {
975 		if (sdopen(dev, FREAD|FWRITE, S_IFBLK, NULL))
976 			return(-1);
977 		didopen = 1;
978 	}
979 	psize = sc->sc_info.si_label.d_partitions[sdpart(dev)].p_size;
980 	if (didopen)
981 		(void) sdclose(dev, FREAD|FWRITE, S_IFBLK, NULL);
982 	return (psize);
983 }
984 
985 /*
986  * Non-interrupt driven, non-dma dump routine.
987  */
988 int
989 sddump(dev)
990 	dev_t dev;
991 {
992 	int part = sdpart(dev);
993 	int unit = sdunit(dev);
994 	register struct sd_softc *sc = &sd_softc[unit];
995 	register struct hp_device *hp = sc->sc_hd;
996 	register struct partition *pinfo;
997 	register daddr_t baddr;
998 	register int maddr;
999 	register int pages, i;
1000 	int stat;
1001 	extern int lowram;
1002 
1003 	/* is drive ok? */
1004 	if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0)
1005 		return (ENXIO);
1006 	pinfo = &sc->sc_info.si_label.d_partitions[part];
1007 	/* dump parameters in range? */
1008 	if (dumplo < 0 || dumplo >= pinfo->p_size ||
1009 	    pinfo->p_fstype != FS_SWAP)
1010 		return (EINVAL);
1011 	pages = physmem;
1012 	if (dumplo + ctod(pages) > pinfo->p_size)
1013 		pages = dtoc(pinfo->p_size - dumplo);
1014 	maddr = lowram;
1015 	baddr = dumplo + pinfo->p_offset;
1016 	/* scsi bus idle? */
1017 	if (!scsireq(&sc->sc_dq)) {
1018 		scsireset(hp->hp_ctlr);
1019 		sdreset(sc, sc->sc_hd);
1020 		printf("[ drive %d reset ] ", unit);
1021 	}
1022 	for (i = 0; i < pages; i++) {
1023 #define NPGMB	(1024*1024/NBPG)
1024 		/* print out how many Mbs we have dumped */
1025 		if (i && (i % NPGMB) == 0)
1026 			printf("%d ", i / NPGMB);
1027 #undef NPBMG
1028 		pmap_enter(kernel_pmap, (vm_offset_t)vmmap, maddr,
1029 		    VM_PROT_READ, TRUE);
1030 		stat = scsi_tt_write(hp->hp_ctlr, hp->hp_slave, sc->sc_punit,
1031 				     vmmap, NBPG, baddr, sc->sc_bshift);
1032 		if (stat) {
1033 			printf("sddump: scsi write error 0x%x\n", stat);
1034 			return (EIO);
1035 		}
1036 		maddr += NBPG;
1037 		baddr += ctod(1);
1038 	}
1039 	return (0);
1040 }
1041 #endif
1042