xref: /original-bsd/sys/dev/scsi/sd.c (revision 60e1d6e0)
1 /*
2  * Copyright (c) 1990, 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This software was developed by the Computer Systems Engineering group
6  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7  * contributed to Berkeley.
8  *
9  * All advertising materials mentioning features or use of this software
10  * must display the following acknowledgement:
11  *	This product includes software developed by the University of
12  *	California, Lawrence Berkeley Laboratories.
13  *
14  * %sccs.include.redist.c%
15  *
16  *	@(#)sd.c	5.3 (Berkeley) 07/23/92
17  *
18  * from: $Header: sd.c,v 1.18 92/06/11 17:55:56 torek Exp $
19  */
20 
21 /*
22  * SCSI CCS (Command Command Set) disk driver.
23  *
24  * MACHINE INDEPENDENT (do not put machine dependent goo in here!)
25  *
26  * (from sd.c,v 1.7 90/12/15 14:11:26 van Exp)
27  */
28 
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/proc.h>
32 #include <sys/buf.h>
33 #include <sys/errno.h>
34 #include <sys/device.h>
35 #include <sys/disklabel.h>
36 #include <sys/dkstat.h>
37 #include <sys/disk.h>
38 #include <sys/ioctl.h>
39 #include <sys/malloc.h>
40 
41 #include <machine/cpu.h>
42 
43 #include "scsi.h"
44 #include "disk.h"
45 #include "scsivar.h"
46 #include "scsi_ioctl.h"
47 
48 #include "sdtrace.h"
49 
50 #ifdef sparc					/* XXX */
51 #define SUN_LABEL_HACK				/* XXX */
52 #endif						/* XXX */
53 
54 #ifdef SUN_LABEL_HACK
55 #include <sparc/sunos/sun_disklabel.h>
56 #endif
57 
58 /*
59  * Per-disk variables.
60  *
61  * sd_dk contains all the `disk' specific stuff (label/partitions,
62  * transfer rate, etc).  We need only things that are special to
63  * scsi disks.  Note that our blocks are in terms of DEV_BSIZE blocks.
64  */
65 struct sd_softc {
66 	struct	dkdevice sc_dk;	/* base disk device, must be first */
67 	struct	unit sc_unit;	/* scsi unit */
68 	pid_t	sc_format_pid;	/* process using "format" mode */
69 	u_char	sc_type;	/* drive type */
70 	u_char	sc_bshift;	/* convert device blocks to DEV_BSIZE blks */
71 	short	sc_flags;	/* see below */
72 	u_int	sc_blks;	/* number of blocks on device */
73 	int	sc_blksize;	/* device block size in bytes */
74 
75 	/* should be in dkdevice?? */
76 	struct	buf sc_tab;	/* transfer queue */
77 
78 	/* statistics */
79 	long	sc_resets;	/* number of times reset */
80 	long	sc_transfers;	/* count of total transfers */
81 	long	sc_partials;	/* count of `partial' transfers */
82 
83 	/* for user formatting */
84 	struct	scsi_cdb sc_cmd;
85 	struct	scsi_fmt_sense sc_sense;
86 };
87 
88 #define	SDF_ALIVE	1	/* drive OK for regular kernel use */
89 
90 /* definition of the autoconfig driver */
91 int	sdmatch __P((struct device *, struct cfdata *, void *));
92 void	sdattach __P((struct device *, struct device *, void *));
93 
94 struct cfdriver sdcd =
95     { NULL, "sd", sdmatch, sdattach, DV_DISK, sizeof(struct sd_softc) };
96 
97 /* definition of the unit driver, for hba */
98 void	sdigo __P((struct device *, struct scsi_cdb *));
99 void	sdgo __P((struct device *, struct scsi_cdb *));
100 void	sdintr __P((struct device *, int, int));
101 void	sdreset __P((struct unit *));
102 
103 static struct unitdriver sdunitdriver = { /*sdgo, sdintr*/ sdreset };
104 
105 /* definition of the disk driver, for kernel */
106 void	sdstrategy __P((struct buf *));
107 
108 #ifdef notyet
109 static struct sddkdriver = { sdstrategy };
110 #endif
111 
112 #ifdef DEBUG
113 int sddebug = 1;
114 #define SDB_ERROR	0x01
115 #define SDB_PARTIAL	0x02
116 #endif
117 
118 #define	sdunit(x)	(minor(x) >> 3)
119 #define sdpart(x)	(minor(x) & 0x7)
120 
121 #define	b_cylin		b_resid
122 
123 #define	SDRETRY		2
124 
125 /*
126  * Table of scsi commands users are allowed to access via `format'
127  * mode.  0 means not legal.  1 means `immediate' (doesn't need dma).
128  * -1 means needs dma and/or wait for intr (i.e., `slow').
129  */
130 static char legal_cmds[256] = {
131 /*****  0   1   2   3   4   5   6   7     8   9   A   B   C   D   E   F */
132 /*00*/	0,  0,  0,  0, -1,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
133 /*10*/	0,  0,  1,  0,  0,  1,  0,  0,    0,  0,  1,  0,  0,  0,  0,  0,
134 /*20*/	0,  0,  0,  0,  0,  1,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
135 /*30*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
136 /*40*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
137 /*50*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
138 /*60*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
139 /*70*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
140 /*80*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
141 /*90*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
142 /*a0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
143 /*b0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
144 /*c0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
145 /*d0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
146 /*e0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
147 /*f0*/	0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
148 };
149 
150 int
151 sdmatch(parent, cf, aux)
152 	struct device *parent;
153 	register struct cfdata *cf;
154 	void *aux;
155 {
156 	register struct scsi_attach_args *sa = aux;
157 #ifdef DEBUG
158 	char *whynot;
159 #endif
160 
161 	/*
162 	 * unit number must match, or be given as `any'
163 	 */
164 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != sa->sa_unit)
165 		return (0);
166 	/*
167 	 * drive must be a disk, and of a kind we recognize
168 	 */
169 	if ((sa->sa_inq_status & STS_MASK) != STS_GOOD) {
170 #ifdef DEBUG
171 		whynot = "INQUIRY failed";
172 #endif
173 		goto notdisk;
174 	}
175 
176 	switch (sa->sa_si.si_type & TYPE_TYPE_MASK) {
177 
178 	case TYPE_DAD:		/* disk */
179 	case TYPE_WORM:		/* WORM */
180 	case TYPE_ROM:		/* CD-ROM */
181 	case TYPE_MO:		/* Magneto-optical */
182 	case TYPE_JUKEBOX:	/* medium changer */
183 		break;
184 
185 	default:
186 	notdisk:
187 #ifdef DEBUG
188 		whynot = "not a disk";
189 		printf("[not matching `sd' at unit %d: %s]\n",
190 		    sa->sa_unit, whynot);
191 #endif
192 		return (0);
193 	}
194 
195 	/*
196 	 * It is a disk of some kind; take it.  We will figure out
197 	 * the rest in the attach routine.
198 	 */
199 	return (1);
200 }
201 
202 /*
203  * Attach a disk (called after sdmatch returns true).
204  * Note that this routine is never reentered (so we can use statics).
205  */
206 void
207 sdattach(parent, self, aux)
208 	struct device *parent, *self;
209 	void *aux;
210 {
211 	register struct sd_softc *sc = (struct sd_softc *)self;
212 	register struct scsi_attach_args *sa = aux;
213 	register int i;
214 	char vendor[10], drive[17], rev[5];
215 	static u_char capbuf[8];
216 	static struct scsi_cdb cap = { CMD_READ_CAPACITY };
217 #ifdef SUN_LABEL_HACK
218 	static struct scsi_cdb rd0 = { CMD_READ10, 0, 0, 0, 0, 0, 0, 0, 1, 0 };
219 	caddr_t sector;
220 #endif
221 
222 	/*
223 	 * Declare our existence.
224 	 */
225 	sc->sc_unit.u_driver = &sdunitdriver;
226 	scsi_establish(&sc->sc_unit, &sc->sc_dk.dk_dev, sa->sa_unit);
227 
228 	/*
229 	 * Figure out what kind of disk this is.
230 	 * We only accepted it if the inquiry succeeded, so
231 	 * we can inspect those fields.
232 	 */
233 	i = (sa->sa_si.si_version >> VER_ANSI_SHIFT) & VER_ANSI_MASK;
234 	if (i == 1 || i == 2) {
235 		scsi_inq_ansi((struct scsi_inq_ansi *)&sa->sa_si,
236 		    vendor, drive, rev);
237 		printf(": %s %s", vendor, drive);
238 		/* XXX should we even ever bother printing this? */
239 		if (rev[0])
240 			printf(" %s", rev);
241 	} else {
242 		/* bleah */
243 		bcopy("<unknown>", vendor, 10);
244 		bcopy("<unknown>", drive, 10);
245 		printf(": type 0x%x, qual 0x%x, ver %d",
246 		    sa->sa_si.si_type, sa->sa_si.si_qual,
247 		    sa->sa_si.si_version);
248 	}
249 
250 #ifdef notyet
251 	sc->sc_dk.dk_driver = &sddkdriver;
252 	dk_establish(&sc->sc_dk);
253 	/* READ DISK LABEL HERE, UNLESS REMOVABLE MEDIUM... NEEDS THOUGHT */
254 #endif
255 
256 	CDB10(&cap)->cdb_lun_rel = sc->sc_unit.u_unit << 5;
257 	i = (*sc->sc_unit.u_hbd->hd_icmd)(sc->sc_unit.u_hba,
258 	    sc->sc_unit.u_targ, &cap, (char *)capbuf, sizeof capbuf, B_READ);
259 	i &= STS_MASK;
260 	if (i == STS_GOOD) {
261 #define	NUMBER(p) (((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | (p)[3])
262 		sc->sc_blks = NUMBER(&capbuf[0]);
263 		sc->sc_blksize = NUMBER(&capbuf[4]);
264 	} else if (i == STS_CHECKCOND &&
265 	    (strcmp(vendor, "HP") == 0 && strcmp(drive, "S6300.650A") == 0)) {
266 		/* XXX unformatted or nonexistent MO medium: fake it */
267 		sc->sc_blks = 318664;
268 		sc->sc_blksize = 1024;
269 	} else {
270 		printf(": unable to determine drive capacity [sts=%x]\n", i);
271 		return;
272 	}
273 	/* return value from read capacity is last valid block, not nblocks */
274 	sc->sc_blks++;
275 	printf(", %u %d byte blocks\n", sc->sc_blks, sc->sc_blksize);
276 	if (sc->sc_blksize != DEV_BSIZE) {
277 		for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1)
278 			++sc->sc_bshift;
279 		if (i != DEV_BSIZE) {
280 			printf("%s: blksize not multiple of %d: cannot use\n",
281 			    sc->sc_dk.dk_dev.dv_xname, DEV_BSIZE);
282 			return;
283 		}
284 		sc->sc_blks <<= sc->sc_bshift;
285 	}
286 	sc->sc_type = sa->sa_si.si_type;	/* sufficient? */
287 	sc->sc_dk.dk_wpms = 32 * (60 * DEV_BSIZE / 2);	/* XXX */
288 
289 	sc->sc_dk.dk_label.d_secsize = 512;	/* XXX */
290 
291 #ifdef SUN_LABEL_HACK
292 	sector = (caddr_t)malloc(sc->sc_blksize, M_DEVBUF, M_NOWAIT);
293 	CDB10(&rd0)->cdb_lun_rel = sc->sc_unit.u_unit << 5;
294 	i = (*sc->sc_unit.u_hbd->hd_icmd)(sc->sc_unit.u_hba,
295 	    sc->sc_unit.u_targ, &rd0, sector, sc->sc_blksize, B_READ);
296 	if (i == STS_GOOD) {
297 		printf("%s: <%s>\n", sc->sc_dk.dk_dev.dv_xname,
298 		    ((struct sun_disklabel *)sector)->sl_text);
299 		if (sun_disklabel(sector, &sc->sc_dk.dk_label))
300 			sc->sc_flags |= SDF_ALIVE;
301 		else
302 			printf("%s: sun_disklabel fails\n",
303 			    sc->sc_dk.dk_dev.dv_xname);
304 	} else
305 		printf("%s: could not read sector 0 for disk label\n",
306 		    sc->sc_dk.dk_dev.dv_xname);
307 	free(sector, M_DEVBUF);
308 #endif
309 }
310 
311 /*
312  * Reset a disk, after a SCSI bus reset.
313  *
314  * XXX untested and probably incomplete/incorrect
315  */
316 void
317 sdreset(u)
318 	register struct unit *u;
319 {
320 	register struct sd_softc *sc = (struct sd_softc *)u->u_dev;
321 
322 	printf(" %s", sc->sc_dk.dk_dev.dv_xname);
323 	sc->sc_resets++;
324 }
325 
326 /* dev_t is short, must use prototype syntax */
327 int
328 sdopen(dev_t dev, int flags, int ifmt, struct proc *p)
329 {
330 	register int unit = sdunit(dev);
331 	register struct sd_softc *sc;
332 
333 	if (unit >= sdcd.cd_ndevs || (sc = sdcd.cd_devs[unit]) == NULL)
334 		return (ENXIO);
335 	if ((sc->sc_flags & SDF_ALIVE) == 0 &&
336 	    !suser(p->p_ucred, &p->p_acflag))
337 		return (ENXIO);
338 	return (0);
339 }
340 
341 int
342 sdclose(dev_t dev, int flags, int ifmt, struct proc *p)
343 {
344 	register struct sd_softc *sc = sdcd.cd_devs[sdunit(dev)];
345 
346 	sc->sc_format_pid = 0;
347 	return (0);
348 }
349 
350 /*
351  * This routine is called for partial block transfers and non-aligned
352  * transfers (the latter only being possible on devices with a block size
353  * larger than DEV_BSIZE).  The operation is performed in three steps
354  * using a locally allocated buffer:
355  *	1. transfer any initial partial block
356  *	2. transfer full blocks
357  *	3. transfer any final partial block
358  */
359 static void
360 sdlblkstrat(bp, bsize)
361 	register struct buf *bp;
362 	register int bsize;
363 {
364 	register int bn, resid, boff, count;
365 	register caddr_t addr, cbuf;
366 	struct buf tbp;
367 
368 	cbuf = (caddr_t)malloc(bsize, M_DEVBUF, M_WAITOK);
369 	bzero((caddr_t)&tbp, sizeof tbp);
370 	tbp.b_proc = curproc;
371 	tbp.b_dev = bp->b_dev;
372 	bn = bp->b_blkno;
373 	resid = bp->b_bcount;
374 	addr = bp->b_un.b_addr;
375 #ifdef DEBUG
376 	if (sddebug & SDB_PARTIAL)
377 		printf("sdlblkstrat: bp %x flags %x bn %x resid %x addr %x\n",
378 		       bp, bp->b_flags, bn, resid, addr);
379 #endif
380 
381 	while (resid > 0) {
382 		boff = dbtob(bn) & (bsize - 1);
383 		if (boff || resid < bsize) {
384 			struct sd_softc *sc = sdcd.cd_devs[sdunit(bp->b_dev)];
385 			sc->sc_partials++;
386 			count = min(resid, bsize - boff);
387 			tbp.b_flags = B_BUSY | B_READ;
388 			tbp.b_blkno = bn - btodb(boff);
389 			tbp.b_un.b_addr = cbuf;
390 			tbp.b_bcount = bsize;
391 #ifdef DEBUG
392 			if (sddebug & SDB_PARTIAL)
393 				printf(" readahead: bn %x cnt %x off %x addr %x\n",
394 				       tbp.b_blkno, count, boff, addr);
395 #endif
396 			sdstrategy(&tbp);
397 			biowait(&tbp);
398 			if (tbp.b_flags & B_ERROR) {
399 				bp->b_flags |= B_ERROR;
400 				bp->b_error = tbp.b_error;
401 				break;
402 			}
403 			if (bp->b_flags & B_READ) {
404 				bcopy(&cbuf[boff], addr, count);
405 				goto done;
406 			}
407 			bcopy(addr, &cbuf[boff], count);
408 #ifdef DEBUG
409 			if (sddebug & SDB_PARTIAL)
410 				printf(" writeback: bn %x cnt %x off %x addr %x\n",
411 				       tbp.b_blkno, count, boff, addr);
412 #endif
413 		} else {
414 			count = resid & ~(bsize - 1);
415 			tbp.b_blkno = bn;
416 			tbp.b_un.b_addr = addr;
417 			tbp.b_bcount = count;
418 #ifdef DEBUG
419 			if (sddebug & SDB_PARTIAL)
420 				printf(" fulltrans: bn %x cnt %x addr %x\n",
421 				       tbp.b_blkno, count, addr);
422 #endif
423 		}
424 		tbp.b_flags = B_BUSY | (bp->b_flags & B_READ);
425 		sdstrategy(&tbp);
426 		biowait(&tbp);
427 		if (tbp.b_flags & B_ERROR) {
428 			bp->b_flags |= B_ERROR;
429 			bp->b_error = tbp.b_error;
430 			break;
431 		}
432 done:
433 		bn += btodb(count);
434 		resid -= count;
435 		addr += count;
436 #ifdef DEBUG
437 		if (sddebug & SDB_PARTIAL)
438 			printf(" done: bn %x resid %x addr %x\n",
439 			       bn, resid, addr);
440 #endif
441 	}
442 	free(cbuf, M_DEVBUF);
443 	biodone(bp);
444 }
445 
446 /*
447  * Start a transfer on sc as described by bp
448  * (i.e., call hba or target start).
449  * If in format mode, we may not need dma.
450  */
451 #define sdstart(sc, bp) { \
452 	SD_TRACE(T_START, sc, bp); \
453 	if ((sc)->sc_format_pid && legal_cmds[(sc)->sc_cmd.cdb_bytes[0]] > 0) \
454 		(*(sc)->sc_unit.u_start)((sc)->sc_unit.u_updev, \
455 		    &(sc)->sc_unit.u_forw, (struct buf *)NULL, \
456 		    sdigo, &(sc)->sc_dk.dk_dev); \
457 	else \
458 		(*(sc)->sc_unit.u_start)((sc)->sc_unit.u_updev, \
459 		    &(sc)->sc_unit.u_forw, bp, sdgo, &(sc)->sc_dk.dk_dev); \
460 }
461 
462 void
463 sdstrategy(bp)
464 	register struct buf *bp;
465 {
466 	register struct sd_softc *sc = sdcd.cd_devs[sdunit(bp->b_dev)];
467 	register int s;
468 
469 	if (sc->sc_format_pid) {
470 		/* XXXXXXXXX SHOULD NOT COMPARE curproc IN HERE!?! */
471 		/*
472 		 * In format mode, only allow the owner to mess
473 		 * with the drive.  Skip all the partition checks.
474 		 */
475 		if (sc->sc_format_pid != curproc->p_pid) {
476 			bp->b_error = EPERM;
477 			bp->b_flags |= B_ERROR;
478 			biodone(bp);
479 			return;
480 		}
481 		bp->b_cylin = 0;
482 	} else {
483 		register daddr_t bn = bp->b_blkno;
484 		register int sz = howmany(bp->b_bcount, DEV_BSIZE);
485 		register struct partition *p;
486 
487 		/*
488 		 * Make sure transfer is within partition.
489 		 * If it starts at the end, return EOF; if
490 		 * it extends past the end, truncate it.
491 		 */
492 		p = &sc->sc_dk.dk_label.d_partitions[sdpart(bp->b_dev)];
493 		if ((unsigned)bn >= p->p_size) {
494 			if ((unsigned)bn > p->p_size) {
495 				bp->b_error = EINVAL;
496 				bp->b_flags |= B_ERROR;
497 			} else
498 				bp->b_resid = bp->b_bcount;
499 			biodone(bp);
500 			return;
501 		}
502 		if (bn + sz > p->p_size) {
503 			sz = p->p_size - bn;
504 			bp->b_bcount = dbtob(sz);
505 		}
506 		/*
507 		 * Non-aligned or partial-block transfers handled specially.
508 		 * SHOULD THIS BE AT A HIGHER LEVEL?
509 		 */
510 		s = sc->sc_blksize - 1;
511 		if ((dbtob(bn) & s) || (bp->b_bcount & s)) {
512 			sdlblkstrat(bp, sc->sc_blksize);
513 			return;
514 		}
515 		bp->b_cylin = (bn + p->p_offset) >> sc->sc_bshift;
516 	}
517 
518 	/*
519 	 * Transfer valid, or format mode.  Queue the request
520 	 * on the drive, and maybe try to start it.
521 	 */
522 	s = splbio();
523 	disksort(&sc->sc_tab, bp);
524 	if (sc->sc_tab.b_active == 0) {
525 		sc->sc_tab.b_active = 1;
526 		sdstart(sc, bp);
527 	}
528 	splx(s);
529 }
530 
531 int
532 sderror(sc, stat)
533 	register struct sd_softc *sc;
534 	register int stat;
535 {
536 	register struct scsi_sense *sn;
537 	int retry = 0;
538 
539 	sc->sc_sense.status = stat;
540 	if ((stat & STS_MASK) == STS_CHECKCOND) {
541 		sn = (struct scsi_sense *)sc->sc_sense.sense;
542 		stat = scsi_request_sense(sc->sc_unit.u_hba,
543 		    sc->sc_unit.u_targ, sc->sc_unit.u_unit,
544 		    (caddr_t)sn, sizeof sc->sc_sense.sense);
545 		sc->sc_sense.status = stat;	/* ??? */
546 		if ((stat & STS_MASK) != STS_GOOD) {
547 			printf("%s: sense failed, status %x\n",
548 			    sc->sc_dk.dk_dev.dv_xname, stat);
549 			return (0);
550 		}
551 		printf("%s: scsi sense class %d, code %d",
552 		    sc->sc_dk.dk_dev.dv_xname,
553 		    SENSE_ECLASS(sn), SENSE_ECODE(sn));
554 		if (SENSE_ISXSENSE(sn) && XSENSE_ISSTD(sn)) {
555 			int key;
556 
557 			/*
558 			 * Standard extended sense: can examine sense key
559 			 * and (if valid) info.
560 			 */
561 			key = XSENSE_KEY(sn);
562 			printf(", key %d", key);
563 			if (XSENSE_IVALID(sn))
564 				printf(", blk %d", XSENSE_INFO(sn));
565 			/* no sense or recovered error, try again */
566 			if (key == 0 || key == 1)
567 				retry = 1;
568 		}
569 		printf("\n");
570 	}
571 	return (retry);
572 }
573 
574 /*
575  * sdigo is called from the hba driver when it has got the scsi bus
576  * for us, and we were doing a format op that did not need dma.
577  */
578 void
579 sdigo(sc0, cdb)
580 	struct device *sc0;
581 	struct scsi_cdb *cdb;
582 {
583 	register struct sd_softc *sc = (struct sd_softc *)sc0;
584 	register struct buf *bp = sc->sc_tab.b_actf;
585 	register int stat;
586 
587 	stat = (*sc->sc_unit.u_hbd->hd_icmd)(sc->sc_unit.u_hba,
588 	    sc->sc_unit.u_targ, &sc->sc_cmd, bp->b_un.b_addr, bp->b_bcount,
589 	    bp->b_flags & B_READ);
590 	sc->sc_sense.status = stat;
591 	if (stat & 0xfe) {		/* XXX */
592 		(void) sderror(sc, stat);
593 		bp->b_flags |= B_ERROR;
594 		bp->b_error = EIO;
595 	}
596 	/*
597 	 * Done with SCSI bus, before we `ought' to be.  Release it.
598 	 */
599 	(*sc->sc_unit.u_rel)(sc->sc_unit.u_updev);
600 	bp->b_resid = 0;
601 	sc->sc_tab.b_errcnt = 0;
602 	sc->sc_tab.b_actf = bp->b_actf;
603 	biodone(bp);
604 	if ((bp = sc->sc_tab.b_actf) == NULL)
605 		sc->sc_tab.b_active = 0;
606 	else
607 		sdstart(sc, bp);
608 }
609 
610 /*
611  * sdgo is called from the hba driver or target code when it has
612  * allocated the scsi bus and DMA resources and target datapath for us.
613  */
614 void
615 sdgo(sc0, cdb)
616 	struct device *sc0;
617 	register struct scsi_cdb *cdb;
618 {
619 	register struct sd_softc *sc = (struct sd_softc *)sc0;
620 	register struct buf *bp = sc->sc_tab.b_actf;
621 	register int n;
622 	register unsigned int u;
623 
624 	SD_TRACE(T_MKCDB, sc, bp);
625 	if (sc->sc_format_pid) {
626 		*cdb = sc->sc_cmd;
627 		n = 0;
628 	} else {
629 		CDB10(cdb)->cdb_cmd = bp->b_flags & B_READ ? CMD_READ10 :
630 		    CMD_WRITE10;
631 		CDB10(cdb)->cdb_lun_rel = sc->sc_unit.u_unit << 5;
632 		u = bp->b_cylin;
633 		CDB10(cdb)->cdb_lbah = u >> 24;
634 		CDB10(cdb)->cdb_lbahm = u >> 16;
635 		CDB10(cdb)->cdb_lbalm = u >> 8;
636 		CDB10(cdb)->cdb_lbal = u;
637 		CDB10(cdb)->cdb_xxx = 0;
638 		n = sc->sc_blksize - 1;
639 		u = (bp->b_bcount + n) >> (DEV_BSHIFT + sc->sc_bshift);
640 		CDB10(cdb)->cdb_lenh = u >> 8;
641 		CDB10(cdb)->cdb_lenl = u;
642 		CDB10(cdb)->cdb_ctrl = 0;
643 		n = (bp->b_bcount & n) != 0;
644 #ifdef DEBUG
645 		if (n)
646 			printf("%s: partial block xfer -- %x bytes\n",
647 			    sc->sc_dk.dk_dev.dv_xname, bp->b_bcount);
648 #endif
649 		sc->sc_transfers++;
650 	}
651 	if ((*sc->sc_unit.u_go)(sc->sc_unit.u_updev, sc->sc_unit.u_targ,
652 	    sdintr, (void *)sc, bp, n) == 0) {
653 #ifdef notyet
654 		sc->sc_dk.dk_busy = 1;
655 		sc->sc_dk.dk_seek++;	/* XXX */
656 		sc->sc_dk.dk_xfer++;
657 		sc->sc_dk.dk_wds += bp->b_bcount >> 6;
658 #endif
659 		return;
660 	}
661 	/*
662 	 * Some sort of nasty unrecoverable error: clobber the
663 	 * transfer.  Call the bus release function first, though.
664 	 */
665 	(*sc->sc_unit.u_rel)(sc->sc_unit.u_updev);
666 #ifdef DEBUG
667 	if (sddebug & SDB_ERROR)
668 		printf("%s: sdgo: %s adr %d blk %d len %d ecnt %d\n",
669 		    sc->sc_dk.dk_dev.dv_xname,
670 		    bp->b_flags & B_READ? "read" : "write",
671 		    bp->b_un.b_addr, bp->b_cylin, bp->b_bcount,
672 		    sc->sc_tab.b_errcnt);
673 #endif
674 	bp->b_flags |= B_ERROR;
675 	bp->b_error = EIO;
676 	bp->b_resid = 0;
677 	sc->sc_tab.b_errcnt = 0;
678 	sc->sc_tab.b_actf = bp->b_actf;
679 	biodone(bp);
680 	if ((bp = sc->sc_tab.b_actf) == NULL)
681 		sc->sc_tab.b_active = 0;
682 	else
683 		sdstart(sc, bp);
684 }
685 
686 /*
687  * A transfer finished (or, someday, disconnected).
688  * We are already off the target/hba queues.
689  * Restart this one for error recovery, or start the next, as appropriate.
690  */
691 void
692 sdintr(sc0, stat, resid)
693 	struct device *sc0;
694 	int stat, resid;
695 {
696 	register struct sd_softc *sc = (struct sd_softc *)sc0;
697 	register struct buf *bp = sc->sc_tab.b_actf;
698 	int retry;
699 
700 	if (bp == NULL)
701 		panic("sdintr");
702 	SD_TRACE(T_INTR, sc, bp);
703 #ifdef notyet
704 	sc->sc_dk.dk_busy = 0;
705 #endif
706 	if ((stat & STS_MASK) != STS_GOOD) {
707 #ifdef DEBUG
708 		if (sddebug & SDB_ERROR)
709 			printf("%s: sdintr scsi status 0x%x resid %d\n",
710 			    sc->sc_dk.dk_dev.dv_xname, stat, resid);
711 #endif
712 		retry = sderror(sc, stat);
713 		if (retry && ++sc->sc_tab.b_errcnt <= SDRETRY) {
714 			printf("%s: retry %d\n",
715 			    sc->sc_dk.dk_dev.dv_xname, sc->sc_tab.b_errcnt);
716 			goto restart;
717 		}
718 		bp->b_flags |= B_ERROR;
719 		bp->b_error = EIO;
720 	}
721 	bp->b_resid = resid;
722 	sc->sc_tab.b_errcnt = 0;
723 	sc->sc_tab.b_actf = bp->b_actf;
724 	biodone(bp);
725 	if ((bp = sc->sc_tab.b_actf) == NULL)
726 		sc->sc_tab.b_active = 0;
727 	else {
728 restart:
729 		sdstart(sc, bp);
730 	}
731 }
732 
733 int
734 sdioctl(dev_t dev, int cmd, register caddr_t data, int flag, struct proc *p)
735 {
736 	register struct sd_softc *sc = sdcd.cd_devs[sdunit(dev)];
737 #ifdef COMPAT_SUNOS
738 	int error;
739 
740 	error = sun_dkioctl(&sc->sc_dk, cmd, data, sdpart(dev));
741 	if (error >= 0)
742 		return (error);
743 #endif
744 	switch (cmd) {
745 
746 	case SDIOCSFORMAT:
747 		/* take this device into or out of "format" mode */
748 		if (!suser(p->p_ucred, &p->p_acflag))
749 			return (EPERM);
750 		if (*(int *)data) {
751 			if (sc->sc_format_pid)
752 				return (EPERM);
753 			sc->sc_format_pid = p->p_pid;
754 		} else
755 			sc->sc_format_pid = 0;
756 		break;
757 
758 	case SDIOCGFORMAT:
759 		/* find out who has the device in format mode */
760 		*(int *)data = sc->sc_format_pid;
761 		break;
762 
763 	case SDIOCSCSICOMMAND:
764 #define cdb ((struct scsi_cdb *)data)
765 		/*
766 		 * Save what user gave us as SCSI cdb to use with next
767 		 * read or write to the char device.
768 		 */
769 		if (sc->sc_format_pid != p->p_pid)
770 			return (EPERM);
771 		if (legal_cmds[cdb->cdb_bytes[0]] == 0)
772 			return (EINVAL);
773 		sc->sc_cmd = *cdb;
774 #undef	cdb
775 		break;
776 
777 	case SDIOCSENSE:
778 		/*
779 		 * return the SCSI sense data saved after the last
780 		 * operation that completed with "check condition" status.
781 		 */
782 		sc->sc_sense = *(struct scsi_fmt_sense *)data;
783 		break;
784 
785 	default:
786 		return (ENOTTY);
787 	}
788 	return (0);
789 }
790 
791 int
792 sdsize(dev_t dev)
793 {
794 	register int unit = sdunit(dev);
795 	register struct sd_softc *sc;
796 
797 	if (unit >= sdcd.cd_ndevs || (sc = sdcd.cd_devs[unit]) == NULL ||
798 	    (sc->sc_flags & SDF_ALIVE) == 0)
799 		return (-1);
800 	return (sc->sc_dk.dk_label.d_partitions[sdpart(dev)].p_size);
801 }
802 
803 /*
804  * Write `len' bytes from address `addr' to drive and partition in `dev',
805  * at block blkoff from the beginning of the partition.  The address is
806  * either kernel virtual or physical (some machines may never use one or
807  * the other, but we need it in the protocol to stay machine-independent).
808  */
809 int
810 sddump(dev_t dev, daddr_t blkoff, caddr_t addr, int len)
811 {
812 	register struct sd_softc *sc;
813 	register struct partition *p;
814 	register daddr_t bn, n, nblks;
815 	register struct hba_softc *hba;
816 	register int stat, unit;
817 	struct scsi_cdb cdb;
818 
819 	/* drive ok? */
820 	unit = sdunit(dev);
821 	if (unit >= sdcd.cd_ndevs || (sc = sdcd.cd_devs[unit]) == NULL ||
822 	    (sc->sc_flags & SDF_ALIVE) == 0)
823 		return (ENXIO);
824 
825 	/* blocks in range? */
826 	p = &sc->sc_dk.dk_label.d_partitions[sdpart(dev)];
827 	n = (len + sc->sc_blksize - 1) >> DEV_BSHIFT;
828 	if (blkoff < 0 || blkoff >= p->p_size || blkoff + n > p->p_size)
829 		return (EINVAL);
830 	bn = blkoff + p->p_offset;
831 	bn >>= sc->sc_bshift;
832 
833 	/* scsi bus idle? */
834 	hba = sc->sc_unit.u_hba;
835 	if (hba->hba_head) {
836 		(*hba->hba_driver->hd_reset)(hba, 0);
837 		printf("[reset %s] ", sc->sc_dk.dk_dev.dv_xname);
838 	}
839 
840 	CDB10(&cdb)->cdb_cmd = CMD_WRITE10;
841 	CDB10(&cdb)->cdb_lun_rel = sc->sc_unit.u_unit << 5;
842 	CDB10(&cdb)->cdb_xxx = 0;
843 	CDB10(&cdb)->cdb_ctrl = 0;
844 
845 #define	DUMP_MAX	(32 * 1024)	/* no more than 32k per write */
846 	for (;;) {
847 		if ((n = len) > DUMP_MAX)
848 			n = DUMP_MAX;
849 		CDB10(&cdb)->cdb_lbah = bn >> 24;
850 		CDB10(&cdb)->cdb_lbahm = bn >> 16;
851 		CDB10(&cdb)->cdb_lbalm = bn >> 8;
852 		CDB10(&cdb)->cdb_lbal = bn;
853 		nblks = n >> (DEV_BSHIFT + sc->sc_bshift);
854 		CDB10(&cdb)->cdb_lenh = nblks >> 8;
855 		CDB10(&cdb)->cdb_lenl = nblks;
856 		stat = hba->hba_driver->hd_dump(hba, sc->sc_unit.u_targ,
857 		    &cdb, addr, n);
858 		if ((stat & STS_MASK) != STS_GOOD) {
859 			printf("%s: scsi write error 0x%x\ndump ",
860 			    sc->sc_dk.dk_dev.dv_xname, stat);
861 			return (EIO);
862 		}
863 		if ((len -= n) == 0)
864 			return (0);
865 		addr += n;
866 		bn += nblks;
867 	}
868 }
869