xref: /netbsd-src/sys/dev/scsipi/sd.c (revision 76dfffe33547c37f8bdd446e3e4ab0f3c16cea4b)
1 /*	$NetBSD: sd.c,v 1.105 1996/10/23 07:25:44 matthias Exp $	*/
2 
3 /*
4  * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *	This product includes software developed by Charles M. Hannum.
17  * 4. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Originally written by Julian Elischer (julian@dialix.oz.au)
34  * for TRW Financial Systems for use under the MACH(2.5) operating system.
35  *
36  * TRW Financial Systems, in accordance with their agreement with Carnegie
37  * Mellon University, makes this software available to CMU to distribute
38  * or use in any manner that they see fit as long as this message is kept with
39  * the software. For this reason TFS also grants any other persons or
40  * organisations permission to use or modify this software.
41  *
42  * TFS supplies this software to be publicly redistributed
43  * on the understanding that TFS is not responsible for the correct
44  * functioning of this software in any circumstances.
45  *
46  * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
47  */
48 
49 #include <sys/types.h>
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/kernel.h>
53 #include <sys/file.h>
54 #include <sys/stat.h>
55 #include <sys/ioctl.h>
56 #include <sys/buf.h>
57 #include <sys/uio.h>
58 #include <sys/malloc.h>
59 #include <sys/errno.h>
60 #include <sys/device.h>
61 #include <sys/disklabel.h>
62 #include <sys/disk.h>
63 #include <sys/proc.h>
64 #include <sys/conf.h>
65 
66 #include <scsi/scsi_all.h>
67 #include <scsi/scsi_disk.h>
68 #include <scsi/scsiconf.h>
69 
70 #define	SDOUTSTANDING	4
71 #define	SDRETRIES	4
72 
73 #define	SDUNIT(dev)			DISKUNIT(dev)
74 #define	SDPART(dev)			DISKPART(dev)
75 #define	MAKESDDEV(maj, unit, part)	MAKEDISKDEV(maj, unit, part)
76 
77 #define	SDLABELDEV(dev)	(MAKESDDEV(major(dev), SDUNIT(dev), RAW_PART))
78 
79 struct sd_softc {
80 	struct device sc_dev;
81 	struct disk sc_dk;
82 
83 	int flags;
84 #define	SDF_LOCKED	0x01
85 #define	SDF_WANTED	0x02
86 #define	SDF_WLABEL	0x04		/* label is writable */
87 #define	SDF_LABELLING	0x08		/* writing label */
88 #define	SDF_ANCIENT	0x10		/* disk is ancient; for minphys */
89 	struct scsi_link *sc_link;	/* contains our targ, lun, etc. */
90 	struct disk_parms {
91 		u_char heads;		/* number of heads */
92 		u_short cyls;		/* number of cylinders */
93 		u_char sectors;		/* number of sectors/track */
94 		int blksize;		/* number of bytes/sector */
95 		u_long disksize;	/* total number sectors */
96 	} params;
97 	struct buf buf_queue;
98 };
99 
100 struct scsi_mode_sense_data {
101 	struct scsi_mode_header header;
102 	struct scsi_blk_desc blk_desc;
103 	union disk_pages pages;
104 } scsi_sense;
105 
106 int	sdmatch __P((struct device *, void *, void *));
107 void	sdattach __P((struct device *, struct device *, void *));
108 int	sdlock __P((struct sd_softc *));
109 void	sdunlock __P((struct sd_softc *));
110 void	sdminphys __P((struct buf *));
111 void	sdgetdisklabel __P((struct sd_softc *));
112 void	sdstart __P((void *));
113 int	sddone __P((struct scsi_xfer *, int));
114 int	sd_reassign_blocks __P((struct sd_softc *, u_long));
115 int	sd_get_parms __P((struct sd_softc *, int));
116 static int sd_mode_sense __P((struct sd_softc *, struct scsi_mode_sense_data *,
117     int, int));
118 
119 struct cfattach sd_ca = {
120 	sizeof(struct sd_softc), sdmatch, sdattach
121 };
122 
123 struct cfdriver sd_cd = {
124 	NULL, "sd", DV_DISK
125 };
126 
127 struct dkdriver sddkdriver = { sdstrategy };
128 
129 struct scsi_device sd_switch = {
130 	NULL,			/* Use default error handler */
131 	sdstart,		/* have a queue, served by this */
132 	NULL,			/* have no async handler */
133 	sddone,			/* deal with stats at interrupt time */
134 };
135 
136 struct scsi_inquiry_pattern sd_patterns[] = {
137 	{T_DIRECT, T_FIXED,
138 	 "",         "",                 ""},
139 	{T_DIRECT, T_REMOV,
140 	 "",         "",                 ""},
141 	{T_OPTICAL, T_FIXED,
142 	 "",         "",                 ""},
143 	{T_OPTICAL, T_REMOV,
144 	 "",         "",                 ""},
145 };
146 
147 int
148 sdmatch(parent, match, aux)
149 	struct device *parent;
150 	void *match, *aux;
151 {
152 	struct scsibus_attach_args *sa = aux;
153 	int priority;
154 
155 	(void)scsi_inqmatch(sa->sa_inqbuf,
156 	    (caddr_t)sd_patterns, sizeof(sd_patterns)/sizeof(sd_patterns[0]),
157 	    sizeof(sd_patterns[0]), &priority);
158 	return (priority);
159 }
160 
161 /*
162  * The routine called by the low level scsi routine when it discovers
163  * a device suitable for this driver.
164  */
165 void
166 sdattach(parent, self, aux)
167 	struct device *parent, *self;
168 	void *aux;
169 {
170 	int error;
171 	struct sd_softc *sd = (void *)self;
172 	struct disk_parms *dp = &sd->params;
173 	struct scsibus_attach_args *sa = aux;
174 	struct scsi_link *sc_link = sa->sa_sc_link;
175 
176 	SC_DEBUG(sc_link, SDEV_DB2, ("sdattach: "));
177 
178 	/*
179 	 * Store information needed to contact our base driver
180 	 */
181 	sd->sc_link = sc_link;
182 	sc_link->device = &sd_switch;
183 	sc_link->device_softc = sd;
184 	if (sc_link->openings > SDOUTSTANDING)
185 		sc_link->openings = SDOUTSTANDING;
186 
187 	/*
188 	 * Initialize and attach the disk structure.
189 	 */
190 	sd->sc_dk.dk_driver = &sddkdriver;
191 	sd->sc_dk.dk_name = sd->sc_dev.dv_xname;
192 	disk_attach(&sd->sc_dk);
193 
194 #if !defined(i386)
195 	dk_establish(&sd->sc_dk, &sd->sc_dev);		/* XXX */
196 #endif
197 
198 	/*
199 	 * Note if this device is ancient.  This is used in sdminphys().
200 	 */
201 	if ((sa->sa_inqbuf->version & SID_ANSII) == 0)
202 		sd->flags |= SDF_ANCIENT;
203 
204 	/*
205 	 * Use the subdriver to request information regarding
206 	 * the drive. We cannot use interrupts yet, so the
207 	 * request must specify this.
208 	 */
209 	printf("\n");
210 	printf("%s: ", sd->sc_dev.dv_xname);
211 
212 	if ((sd->sc_link->quirks & SDEV_NOSTARTUNIT) == 0) {
213 		error = scsi_start(sd->sc_link, SSS_START,
214 				   SCSI_AUTOCONF | SCSI_IGNORE_ILLEGAL_REQUEST |
215 				   SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT);
216 	} else
217 		error = 0;
218 
219 	if (error || sd_get_parms(sd, SCSI_AUTOCONF) != 0)
220 		printf("drive offline\n");
221 	else
222 	        printf("%ldMB, %d cyl, %d head, %d sec, %d bytes/sec\n",
223 		    dp->disksize / (1048576 / dp->blksize), dp->cyls,
224 		    dp->heads, dp->sectors, dp->blksize);
225 }
226 
227 /*
228  * Wait interruptibly for an exclusive lock.
229  *
230  * XXX
231  * Several drivers do this; it should be abstracted and made MP-safe.
232  */
233 int
234 sdlock(sd)
235 	struct sd_softc *sd;
236 {
237 	int error;
238 
239 	while ((sd->flags & SDF_LOCKED) != 0) {
240 		sd->flags |= SDF_WANTED;
241 		if ((error = tsleep(sd, PRIBIO | PCATCH, "sdlck", 0)) != 0)
242 			return error;
243 	}
244 	sd->flags |= SDF_LOCKED;
245 	return 0;
246 }
247 
248 /*
249  * Unlock and wake up any waiters.
250  */
251 void
252 sdunlock(sd)
253 	struct sd_softc *sd;
254 {
255 
256 	sd->flags &= ~SDF_LOCKED;
257 	if ((sd->flags & SDF_WANTED) != 0) {
258 		sd->flags &= ~SDF_WANTED;
259 		wakeup(sd);
260 	}
261 }
262 
263 /*
264  * open the device. Make sure the partition info is a up-to-date as can be.
265  */
266 int
267 sdopen(dev, flag, fmt, p)
268 	dev_t dev;
269 	int flag, fmt;
270 	struct proc *p;
271 {
272 	struct sd_softc *sd;
273 	struct scsi_link *sc_link;
274 	int unit, part;
275 	int error;
276 
277 	unit = SDUNIT(dev);
278 	if (unit >= sd_cd.cd_ndevs)
279 		return ENXIO;
280 	sd = sd_cd.cd_devs[unit];
281 	if (!sd)
282 		return ENXIO;
283 
284 	sc_link = sd->sc_link;
285 
286 	SC_DEBUG(sc_link, SDEV_DB1,
287 	    ("sdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit,
288 	    sd_cd.cd_ndevs, SDPART(dev)));
289 
290 	if ((error = sdlock(sd)) != 0)
291 		return error;
292 
293 	if (sd->sc_dk.dk_openmask != 0) {
294 		/*
295 		 * If any partition is open, but the disk has been invalidated,
296 		 * disallow further opens.
297 		 */
298 		if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
299 			error = EIO;
300 			goto bad3;
301 		}
302 	} else {
303 		/* Check that it is still responding and ok. */
304 		error = scsi_test_unit_ready(sc_link,
305 					     SCSI_IGNORE_ILLEGAL_REQUEST |
306 					     SCSI_IGNORE_MEDIA_CHANGE |
307 					     SCSI_IGNORE_NOT_READY);
308 		if (error)
309 			goto bad3;
310 
311 		/* Start the pack spinning if necessary. */
312 		if ((sc_link->quirks & SDEV_NOSTARTUNIT) == 0) {
313 			error = scsi_start(sc_link, SSS_START,
314 					   SCSI_IGNORE_ILLEGAL_REQUEST |
315 					   SCSI_IGNORE_MEDIA_CHANGE |
316 					   SCSI_SILENT);
317 			if (error)
318 				goto bad3;
319 		}
320 
321 		sc_link->flags |= SDEV_OPEN;
322 
323 		/* Lock the pack in. */
324 		error = scsi_prevent(sc_link, PR_PREVENT,
325 				     SCSI_IGNORE_ILLEGAL_REQUEST |
326 				     SCSI_IGNORE_MEDIA_CHANGE);
327 		if (error)
328 			goto bad;
329 
330 		if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
331 			sc_link->flags |= SDEV_MEDIA_LOADED;
332 
333 			/* Load the physical device parameters. */
334 			if (sd_get_parms(sd, 0) != 0) {
335 				error = ENXIO;
336 				goto bad2;
337 			}
338 			SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded "));
339 
340 			/* Load the partition info if not already loaded. */
341 			sdgetdisklabel(sd);
342 			SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel loaded "));
343 		}
344 	}
345 
346 	part = SDPART(dev);
347 
348 	/* Check that the partition exists. */
349 	if (part != RAW_PART &&
350 	    (part >= sd->sc_dk.dk_label->d_npartitions ||
351 	     sd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
352 		error = ENXIO;
353 		goto bad;
354 	}
355 
356 	/* Insure only one open at a time. */
357 	switch (fmt) {
358 	case S_IFCHR:
359 		sd->sc_dk.dk_copenmask |= (1 << part);
360 		break;
361 	case S_IFBLK:
362 		sd->sc_dk.dk_bopenmask |= (1 << part);
363 		break;
364 	}
365 	sd->sc_dk.dk_openmask = sd->sc_dk.dk_copenmask | sd->sc_dk.dk_bopenmask;
366 
367 	SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n"));
368 	sdunlock(sd);
369 	return 0;
370 
371 bad2:
372 	sc_link->flags &= ~SDEV_MEDIA_LOADED;
373 
374 bad:
375 	if (sd->sc_dk.dk_openmask == 0) {
376 		scsi_prevent(sc_link, PR_ALLOW,
377 		    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);
378 		sc_link->flags &= ~SDEV_OPEN;
379 	}
380 
381 bad3:
382 	sdunlock(sd);
383 	return error;
384 }
385 
386 /*
387  * close the device.. only called if we are the LAST occurence of an open
388  * device.  Convenient now but usually a pain.
389  */
390 int
391 sdclose(dev, flag, fmt, p)
392 	dev_t dev;
393 	int flag, fmt;
394 	struct proc *p;
395 {
396 	struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(dev)];
397 	int part = SDPART(dev);
398 	int error;
399 
400 	if ((error = sdlock(sd)) != 0)
401 		return error;
402 
403 	switch (fmt) {
404 	case S_IFCHR:
405 		sd->sc_dk.dk_copenmask &= ~(1 << part);
406 		break;
407 	case S_IFBLK:
408 		sd->sc_dk.dk_bopenmask &= ~(1 << part);
409 		break;
410 	}
411 	sd->sc_dk.dk_openmask = sd->sc_dk.dk_copenmask | sd->sc_dk.dk_bopenmask;
412 
413 	if (sd->sc_dk.dk_openmask == 0) {
414 		/* XXXX Must wait for I/O to complete! */
415 
416 		scsi_prevent(sd->sc_link, PR_ALLOW,
417 		    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY);
418 		sd->sc_link->flags &= ~(SDEV_OPEN|SDEV_MEDIA_LOADED);
419 	}
420 
421 	sdunlock(sd);
422 	return 0;
423 }
424 
425 /*
426  * Actually translate the requested transfer into one the physical driver
427  * can understand.  The transfer is described by a buf and will include
428  * only one physical transfer.
429  */
430 void
431 sdstrategy(bp)
432 	struct buf *bp;
433 {
434 	struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(bp->b_dev)];
435 	int s;
436 
437 	SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdstrategy "));
438 	SC_DEBUG(sd->sc_link, SDEV_DB1,
439 	    ("%ld bytes @ blk %d\n", bp->b_bcount, bp->b_blkno));
440 	/*
441 	 * The transfer must be a whole number of blocks.
442 	 */
443 	if ((bp->b_bcount % sd->sc_dk.dk_label->d_secsize) != 0) {
444 		bp->b_error = EINVAL;
445 		goto bad;
446 	}
447 	/*
448 	 * If the device has been made invalid, error out
449 	 */
450 	if ((sd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
451 		bp->b_error = EIO;
452 		goto bad;
453 	}
454 	/*
455 	 * If it's a null transfer, return immediatly
456 	 */
457 	if (bp->b_bcount == 0)
458 		goto done;
459 
460 	/*
461 	 * Do bounds checking, adjust transfer. if error, process.
462 	 * If end of partition, just return.
463 	 */
464 	if (SDPART(bp->b_dev) != RAW_PART &&
465 	    bounds_check_with_label(bp, sd->sc_dk.dk_label,
466 	    (sd->flags & (SDF_WLABEL|SDF_LABELLING)) != 0) <= 0)
467 		goto done;
468 
469 	s = splbio();
470 
471 	/*
472 	 * Place it in the queue of disk activities for this disk
473 	 */
474 	disksort(&sd->buf_queue, bp);
475 
476 	/*
477 	 * Tell the device to get going on the transfer if it's
478 	 * not doing anything, otherwise just wait for completion
479 	 */
480 	sdstart(sd);
481 
482 	splx(s);
483 	return;
484 
485 bad:
486 	bp->b_flags |= B_ERROR;
487 done:
488 	/*
489 	 * Correctly set the buf to indicate a completed xfer
490 	 */
491 	bp->b_resid = bp->b_bcount;
492 	biodone(bp);
493 }
494 
495 /*
496  * sdstart looks to see if there is a buf waiting for the device
497  * and that the device is not already busy. If both are true,
498  * It dequeues the buf and creates a scsi command to perform the
499  * transfer in the buf. The transfer request will call scsi_done
500  * on completion, which will in turn call this routine again
501  * so that the next queued transfer is performed.
502  * The bufs are queued by the strategy routine (sdstrategy)
503  *
504  * This routine is also called after other non-queued requests
505  * have been made of the scsi driver, to ensure that the queue
506  * continues to be drained.
507  *
508  * must be called at the correct (highish) spl level
509  * sdstart() is called at splbio from sdstrategy and scsi_done
510  */
511 void
512 sdstart(v)
513 	register void *v;
514 {
515 	register struct sd_softc *sd = v;
516 	register struct	scsi_link *sc_link = sd->sc_link;
517 	struct buf *bp = 0;
518 	struct buf *dp;
519 	struct scsi_rw_big cmd_big;
520 	struct scsi_rw cmd_small;
521 	struct scsi_generic *cmdp;
522 	int blkno, nblks, cmdlen, error;
523 	struct partition *p;
524 
525 	SC_DEBUG(sc_link, SDEV_DB2, ("sdstart "));
526 	/*
527 	 * Check if the device has room for another command
528 	 */
529 	while (sc_link->openings > 0) {
530 		/*
531 		 * there is excess capacity, but a special waits
532 		 * It'll need the adapter as soon as we clear out of the
533 		 * way and let it run (user level wait).
534 		 */
535 		if (sc_link->flags & SDEV_WAITING) {
536 			sc_link->flags &= ~SDEV_WAITING;
537 			wakeup((caddr_t)sc_link);
538 			return;
539 		}
540 
541 		/*
542 		 * See if there is a buf with work for us to do..
543 		 */
544 		dp = &sd->buf_queue;
545 		if ((bp = dp->b_actf) == NULL)	/* yes, an assign */
546 			return;
547 		dp->b_actf = bp->b_actf;
548 
549 		/*
550 		 * If the device has become invalid, abort all the
551 		 * reads and writes until all files have been closed and
552 		 * re-opened
553 		 */
554 		if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
555 			bp->b_error = EIO;
556 			bp->b_flags |= B_ERROR;
557 			biodone(bp);
558 			continue;
559 		}
560 
561 		/*
562 		 * We have a buf, now we should make a command
563 		 *
564 		 * First, translate the block to absolute and put it in terms
565 		 * of the logical blocksize of the device.
566 		 */
567 		blkno =
568 		    bp->b_blkno / (sd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
569 		if (SDPART(bp->b_dev) != RAW_PART) {
570 		     p = &sd->sc_dk.dk_label->d_partitions[SDPART(bp->b_dev)];
571 		     blkno += p->p_offset;
572 		}
573 		nblks = howmany(bp->b_bcount, sd->sc_dk.dk_label->d_secsize);
574 
575 		/*
576 		 *  Fill out the scsi command.  If the transfer will
577 		 *  fit in a "small" cdb, use it.
578 		 */
579 		if (((blkno & 0x1fffff) == blkno) &&
580 		    ((nblks & 0xff) == nblks)) {
581 			/*
582 			 * We can fit in a small cdb.
583 			 */
584 			bzero(&cmd_small, sizeof(cmd_small));
585 			cmd_small.opcode = (bp->b_flags & B_READ) ?
586 			    READ_COMMAND : WRITE_COMMAND;
587 			_lto3b(blkno, cmd_small.addr);
588 			cmd_small.length = nblks & 0xff;
589 			cmdlen = sizeof(cmd_small);
590 			cmdp = (struct scsi_generic *)&cmd_small;
591 		} else {
592 			/*
593 			 * Need a large cdb.
594 			 */
595 			bzero(&cmd_big, sizeof(cmd_big));
596 			cmd_big.opcode = (bp->b_flags & B_READ) ?
597 			    READ_BIG : WRITE_BIG;
598 			_lto4b(blkno, cmd_big.addr);
599 			_lto2b(nblks, cmd_big.length);
600 			cmdlen = sizeof(cmd_big);
601 			cmdp = (struct scsi_generic *)&cmd_big;
602 		}
603 
604 		/* Instrumentation. */
605 		disk_busy(&sd->sc_dk);
606 
607 		/*
608 		 * Call the routine that chats with the adapter.
609 		 * Note: we cannot sleep as we may be an interrupt
610 		 */
611 		error = scsi_scsi_cmd(sc_link, cmdp, cmdlen,
612 		    (u_char *)bp->b_data, bp->b_bcount,
613 		    SDRETRIES, 10000, bp, SCSI_NOSLEEP |
614 		    ((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT));
615 		if (error)
616 			printf("%s: not queued, error %d\n",
617 			    sd->sc_dev.dv_xname, error);
618 	}
619 }
620 
621 int
622 sddone(xs, complete)
623 	struct scsi_xfer *xs;
624 	int complete;
625 {
626 	struct sd_softc *sd = xs->sc_link->device_softc;
627 
628 	if (complete && (xs->bp != NULL))
629 		disk_unbusy(&sd->sc_dk, (xs->bp->b_bcount - xs->bp->b_resid));
630 
631 	return (0);
632 }
633 
634 void
635 sdminphys(bp)
636 	struct buf *bp;
637 {
638 	struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(bp->b_dev)];
639 	long max;
640 
641 	/*
642 	 * If the device is ancient, we want to make sure that
643 	 * the transfer fits into a 6-byte cdb.
644 	 *
645 	 * XXX Note that the SCSI-I spec says that 256-block transfers
646 	 * are allowed in a 6-byte read/write, and are specified
647 	 * by settng the "length" to 0.  However, we're conservative
648 	 * here, allowing only 255-block transfers in case an
649 	 * ancient device gets confused by length == 0.  A length of 0
650 	 * in a 10-byte read/write actually means 0 blocks.
651 	 */
652 	if (sd->flags & SDF_ANCIENT) {
653 		max = sd->sc_dk.dk_label->d_secsize * 0xff;
654 
655 		if (bp->b_bcount > max)
656 			bp->b_bcount = max;
657 	}
658 
659 	(*sd->sc_link->adapter->scsi_minphys)(bp);
660 }
661 
662 int
663 sdread(dev, uio, ioflag)
664 	dev_t dev;
665 	struct uio *uio;
666 	int ioflag;
667 {
668 
669 	return (physio(sdstrategy, NULL, dev, B_READ, sdminphys, uio));
670 }
671 
672 int
673 sdwrite(dev, uio, ioflag)
674 	dev_t dev;
675 	struct uio *uio;
676 	int ioflag;
677 {
678 
679 	return (physio(sdstrategy, NULL, dev, B_WRITE, sdminphys, uio));
680 }
681 
682 /*
683  * Perform special action on behalf of the user
684  * Knows about the internals of this device
685  */
686 int
687 sdioctl(dev, cmd, addr, flag, p)
688 	dev_t dev;
689 	u_long cmd;
690 	caddr_t addr;
691 	int flag;
692 	struct proc *p;
693 {
694 	struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(dev)];
695 	int error;
696 
697 	SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdioctl 0x%lx ", cmd));
698 
699 	/*
700 	 * If the device is not valid.. abandon ship
701 	 */
702 	if ((sd->sc_link->flags & SDEV_MEDIA_LOADED) == 0)
703 		return EIO;
704 
705 	switch (cmd) {
706 	case DIOCGDINFO:
707 		*(struct disklabel *)addr = *(sd->sc_dk.dk_label);
708 		return 0;
709 
710 	case DIOCGPART:
711 		((struct partinfo *)addr)->disklab = sd->sc_dk.dk_label;
712 		((struct partinfo *)addr)->part =
713 		    &sd->sc_dk.dk_label->d_partitions[SDPART(dev)];
714 		return 0;
715 
716 	case DIOCWDINFO:
717 	case DIOCSDINFO:
718 		if ((flag & FWRITE) == 0)
719 			return EBADF;
720 
721 		if ((error = sdlock(sd)) != 0)
722 			return error;
723 		sd->flags |= SDF_LABELLING;
724 
725 		error = setdisklabel(sd->sc_dk.dk_label,
726 		    (struct disklabel *)addr, /*sd->sc_dk.dk_openmask : */0,
727 		    sd->sc_dk.dk_cpulabel);
728 		if (error == 0) {
729 			if (cmd == DIOCWDINFO)
730 				error = writedisklabel(SDLABELDEV(dev),
731 				    sdstrategy, sd->sc_dk.dk_label,
732 				    sd->sc_dk.dk_cpulabel);
733 		}
734 
735 		sd->flags &= ~SDF_LABELLING;
736 		sdunlock(sd);
737 		return error;
738 
739 	case DIOCWLABEL:
740 		if ((flag & FWRITE) == 0)
741 			return EBADF;
742 		if (*(int *)addr)
743 			sd->flags |= SDF_WLABEL;
744 		else
745 			sd->flags &= ~SDF_WLABEL;
746 		return 0;
747 
748 	case DIOCLOCK:
749 		return scsi_prevent(sd->sc_link,
750 		    (*(int *)addr) ? PR_PREVENT : PR_ALLOW, 0);
751 
752 	case DIOCEJECT:
753 		return ((sd->sc_link->flags & SDEV_REMOVABLE) == 0 ? ENOTTY :
754 		    scsi_start(sd->sc_link, SSS_STOP|SSS_LOEJ, 0));
755 
756 	default:
757 		if (SDPART(dev) != RAW_PART)
758 			return ENOTTY;
759 		return scsi_do_ioctl(sd->sc_link, dev, cmd, addr, flag, p);
760 	}
761 
762 #ifdef DIAGNOSTIC
763 	panic("sdioctl: impossible");
764 #endif
765 }
766 
767 /*
768  * Load the label information on the named device
769  */
770 void
771 sdgetdisklabel(sd)
772 	struct sd_softc *sd;
773 {
774 	struct disklabel *lp = sd->sc_dk.dk_label;
775 	char *errstring;
776 
777 	bzero(lp, sizeof(struct disklabel));
778 	bzero(sd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
779 
780 	lp->d_secsize = sd->params.blksize;
781 	lp->d_ntracks = sd->params.heads;
782 	lp->d_nsectors = sd->params.sectors;
783 	lp->d_ncylinders = sd->params.cyls;
784 	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
785 	if (lp->d_secpercyl == 0) {
786 		lp->d_secpercyl = 100;
787 		/* as long as it's not 0 - readdisklabel divides by it (?) */
788 	}
789 
790 	strncpy(lp->d_typename, "SCSI disk", 16);
791 	lp->d_type = DTYPE_SCSI;
792 	strncpy(lp->d_packname, "fictitious", 16);
793 	lp->d_secperunit = sd->params.disksize;
794 	lp->d_rpm = 3600;
795 	lp->d_interleave = 1;
796 	lp->d_flags = 0;
797 
798 	lp->d_partitions[RAW_PART].p_offset = 0;
799 	lp->d_partitions[RAW_PART].p_size =
800 	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
801 	lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
802 	lp->d_npartitions = RAW_PART + 1;
803 
804 	lp->d_magic = DISKMAGIC;
805 	lp->d_magic2 = DISKMAGIC;
806 	lp->d_checksum = dkcksum(lp);
807 
808 	/*
809 	 * Call the generic disklabel extraction routine
810 	 */
811 	errstring = readdisklabel(MAKESDDEV(0, sd->sc_dev.dv_unit, RAW_PART),
812 				  sdstrategy, lp, sd->sc_dk.dk_cpulabel);
813 	if (errstring) {
814 		printf("%s: %s\n", sd->sc_dev.dv_xname, errstring);
815 		return;
816 	}
817 }
818 
819 /*
820  * Tell the device to map out a defective block
821  */
822 int
823 sd_reassign_blocks(sd, blkno)
824 	struct sd_softc *sd;
825 	u_long blkno;
826 {
827 	struct scsi_reassign_blocks scsi_cmd;
828 	struct scsi_reassign_blocks_data rbdata;
829 
830 	bzero(&scsi_cmd, sizeof(scsi_cmd));
831 	bzero(&rbdata, sizeof(rbdata));
832 	scsi_cmd.opcode = REASSIGN_BLOCKS;
833 
834 	_lto2b(sizeof(rbdata.defect_descriptor[0]), rbdata.length);
835 	_lto4b(blkno, rbdata.defect_descriptor[0].dlbaddr);
836 
837 	return scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd,
838 	    sizeof(scsi_cmd), (u_char *)&rbdata, sizeof(rbdata), SDRETRIES,
839 	    5000, NULL, SCSI_DATA_OUT);
840 }
841 
842 
843 
844 static int
845 sd_mode_sense(sd, scsi_sense, page, flags)
846 	struct sd_softc *sd;
847 	struct scsi_mode_sense_data *scsi_sense;
848 	int page, flags;
849 {
850 	struct scsi_mode_sense scsi_cmd;
851 
852 	bzero(&scsi_cmd, sizeof(scsi_cmd));
853 	scsi_cmd.opcode = MODE_SENSE;
854 	scsi_cmd.page = page;
855 	scsi_cmd.length = 0x20;
856 	/*
857 	 * If the command worked, use the results to fill out
858 	 * the parameter structure
859 	 */
860 	return scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd,
861 	    sizeof(scsi_cmd), (u_char *)scsi_sense, sizeof(*scsi_sense),
862 	    SDRETRIES, 6000, NULL, flags | SCSI_DATA_IN | SCSI_SILENT);
863 }
864 
865 /*
866  * Get the scsi driver to send a full inquiry to the * device and use the
867  * results to fill out the disk parameter structure.
868  */
869 int
870 sd_get_parms(sd, flags)
871 	struct sd_softc *sd;
872 	int flags;
873 {
874 	struct disk_parms *dp = &sd->params;
875 	struct scsi_mode_sense_data scsi_sense;
876 	u_long sectors;
877 	int page;
878 	int error;
879 
880 	if ((error = sd_mode_sense(sd, &scsi_sense, page = 4, flags)) == 0) {
881 		SC_DEBUG(sd->sc_link, SDEV_DB3,
882 		    ("%d cyls, %d heads, %d precomp, %d red_write, %d land_zone\n",
883 		    _3btol(scsi_sense.pages.rigid_geometry.ncyl),
884 		    scsi_sense.pages.rigid_geometry.nheads,
885 		    _2btol(scsi_sense.pages.rigid_geometry.st_cyl_wp),
886 		    _2btol(scsi_sense.pages.rigid_geometry.st_cyl_rwc),
887 		    _2btol(scsi_sense.pages.rigid_geometry.land_zone)));
888 
889 		/*
890 		 * KLUDGE!! (for zone recorded disks)
891 		 * give a number of sectors so that sec * trks * cyls
892 		 * is <= disk_size
893 		 * can lead to wasted space! THINK ABOUT THIS !
894 		 */
895 		dp->heads = scsi_sense.pages.rigid_geometry.nheads;
896 		dp->cyls = _3btol(scsi_sense.pages.rigid_geometry.ncyl);
897 		dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
898 
899 		if (dp->heads == 0 || dp->cyls == 0)
900 			goto fake_it;
901 
902 		if (dp->blksize == 0)
903 			dp->blksize = 512;
904 
905 		sectors = scsi_size(sd->sc_link, flags);
906 		dp->disksize = sectors;
907 		sectors /= (dp->heads * dp->cyls);
908 		dp->sectors = sectors;	/* XXX dubious on SCSI */
909 
910 		return 0;
911 	}
912 
913 	if ((error = sd_mode_sense(sd, &scsi_sense, page = 5, flags)) == 0) {
914 		dp->heads = scsi_sense.pages.flex_geometry.nheads;
915 		dp->cyls = _2btol(scsi_sense.pages.flex_geometry.ncyl);
916 		dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
917 		dp->sectors = scsi_sense.pages.flex_geometry.ph_sec_tr;
918 		dp->disksize = dp->heads * dp->cyls * dp->sectors;
919 		if (dp->disksize == 0)
920 			goto fake_it;
921 
922 		if (dp->blksize == 0)
923 			dp->blksize = 512;
924 
925 		return 0;
926 	}
927 
928 fake_it:
929 	if ((sd->sc_link->quirks & SDEV_NOMODESENSE) == 0) {
930 		if (error == 0)
931 			printf("%s: mode sense (%d) returned nonsense",
932 			    sd->sc_dev.dv_xname, page);
933 		else
934 			printf("%s: could not mode sense (4/5)",
935 			    sd->sc_dev.dv_xname);
936 		printf("; using fictitious geometry\n");
937 	}
938 	/*
939 	 * use adaptec standard fictitious geometry
940 	 * this depends on which controller (e.g. 1542C is
941 	 * different. but we have to put SOMETHING here..)
942 	 */
943 	sectors = scsi_size(sd->sc_link, flags);
944 	dp->heads = 64;
945 	dp->sectors = 32;
946 	dp->cyls = sectors / (64 * 32);
947 	dp->blksize = 512;
948 	dp->disksize = sectors;
949 	return 0;
950 }
951 
952 int
953 sdsize(dev)
954 	dev_t dev;
955 {
956 	struct sd_softc *sd;
957 	int part;
958 	int size;
959 
960 	if (sdopen(dev, 0, S_IFBLK, NULL) != 0)
961 		return -1;
962 	sd = sd_cd.cd_devs[SDUNIT(dev)];
963 	part = SDPART(dev);
964 	if (sd->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
965 		size = -1;
966 	else
967 		size = sd->sc_dk.dk_label->d_partitions[part].p_size;
968 	if (sdclose(dev, 0, S_IFBLK, NULL) != 0)
969 		return -1;
970 	return size;
971 }
972 
973 #ifndef __BDEVSW_DUMP_OLD_TYPE
974 /* #define SD_DUMP_NOT_TRUSTED if you just want to watch */
975 static struct scsi_xfer sx;
976 static int sddoingadump;
977 
978 /*
979  * dump all of physical memory into the partition specified, starting
980  * at offset 'dumplo' into the partition.
981  */
982 int
983 sddump(dev, blkno, va, size)
984 	dev_t dev;
985 	daddr_t blkno;
986 	caddr_t va;
987 	size_t size;
988 {
989 	struct sd_softc *sd;	/* disk unit to do the I/O */
990 	struct disklabel *lp;	/* disk's disklabel */
991 	int	unit, part;
992 	int	sectorsize;	/* size of a disk sector */
993 	int	nsects;		/* number of sectors in partition */
994 	int	sectoff;	/* sector offset of partition */
995 	int	totwrt;		/* total number of sectors left to write */
996 	int	nwrt;		/* current number of sectors to write */
997 	struct scsi_rw_big cmd;	/* write command */
998 	struct scsi_xfer *xs;	/* ... convenience */
999 	int	retval;
1000 
1001 	/* Check if recursive dump; if so, punt. */
1002 	if (sddoingadump)
1003 		return EFAULT;
1004 
1005 	/* Mark as active early. */
1006 	sddoingadump = 1;
1007 
1008 	unit = SDUNIT(dev);	/* Decompose unit & partition. */
1009 	part = SDPART(dev);
1010 
1011 	/* Check for acceptable drive number. */
1012 	if (unit >= sd_cd.cd_ndevs || (sd = sd_cd.cd_devs[unit]) == NULL)
1013 		return ENXIO;
1014 
1015 	/*
1016 	 * XXX Can't do this check, since the media might have been
1017 	 * XXX marked `invalid' by successful unmounting of all
1018 	 * XXX filesystems.
1019 	 */
1020 #if 0
1021 	/* Make sure it was initialized. */
1022 	if ((sd->sc_link->flags & SDEV_MEDIA_LOADED) != SDEV_MEDIA_LOADED)
1023 		return ENXIO;
1024 #endif
1025 
1026 	/* Convert to disk sectors.  Request must be a multiple of size. */
1027 	lp = sd->sc_dk.dk_label;
1028 	sectorsize = lp->d_secsize;
1029 	if ((size % sectorsize) != 0)
1030 		return EFAULT;
1031 	totwrt = size / sectorsize;
1032 	blkno = dbtob(blkno) / sectorsize;	/* blkno in DEV_BSIZE units */
1033 
1034 	nsects = lp->d_partitions[part].p_size;
1035 	sectoff = lp->d_partitions[part].p_offset;
1036 
1037 	/* Check transfer bounds against partition size. */
1038 	if ((blkno < 0) || ((blkno + totwrt) > nsects))
1039 		return EINVAL;
1040 
1041 	/* Offset block number to start of partition. */
1042 	blkno += sectoff;
1043 
1044 	xs = &sx;
1045 
1046 	while (totwrt > 0) {
1047 		nwrt = totwrt;		/* XXX */
1048 #ifndef	SD_DUMP_NOT_TRUSTED
1049 		/*
1050 		 *  Fill out the scsi command
1051 		 */
1052 		bzero(&cmd, sizeof(cmd));
1053 		cmd.opcode = WRITE_BIG;
1054 		_lto4b(blkno, cmd.addr);
1055 		_lto2b(nwrt, cmd.length);
1056 		/*
1057 		 * Fill out the scsi_xfer structure
1058 		 *    Note: we cannot sleep as we may be an interrupt
1059 		 * don't use scsi_scsi_cmd() as it may want
1060 		 * to wait for an xs.
1061 		 */
1062 		bzero(xs, sizeof(sx));
1063 		xs->flags |= SCSI_AUTOCONF | INUSE | SCSI_DATA_OUT;
1064 		xs->sc_link = sd->sc_link;
1065 		xs->retries = SDRETRIES;
1066 		xs->timeout = 10000;	/* 10000 millisecs for a disk ! */
1067 		xs->cmd = (struct scsi_generic *)&cmd;
1068 		xs->cmdlen = sizeof(cmd);
1069 		xs->resid = nwrt * sectorsize;
1070 		xs->error = XS_NOERROR;
1071 		xs->bp = 0;
1072 		xs->data = va;
1073 		xs->datalen = nwrt * sectorsize;
1074 
1075 		/*
1076 		 * Pass all this info to the scsi driver.
1077 		 */
1078 		retval = (*(sd->sc_link->adapter->scsi_cmd)) (xs);
1079 		if (retval != COMPLETE)
1080 			return ENXIO;
1081 #else	/* SD_DUMP_NOT_TRUSTED */
1082 		/* Let's just talk about this first... */
1083 		printf("sd%d: dump addr 0x%x, blk %d\n", unit, va, blkno);
1084 		delay(500 * 1000);	/* half a second */
1085 #endif	/* SD_DUMP_NOT_TRUSTED */
1086 
1087 		/* update block count */
1088 		totwrt -= nwrt;
1089 		blkno += nwrt;
1090 		va += sectorsize * nwrt;
1091 	}
1092 	sddoingadump = 0;
1093 	return 0;
1094 }
1095 #else	/* __BDEVSW_DUMP_NEW_TYPE */
1096 int
1097 sddump(dev, blkno, va, size)
1098 	dev_t dev;
1099 	daddr_t blkno;
1100 	caddr_t va;
1101 	size_t size;
1102 {
1103 
1104 	/* Not implemented. */
1105 	return ENXIO;
1106 }
1107 #endif	/* __BDEVSW_DUMP_NEW_TYPE */
1108