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