FreeBSD/Linux Kernel Cross Reference
sys/scsi/sd.c
1 /*
2 * Written by Julian Elischer (julian@dialix.oz.au)
3 * for TRW Financial Systems for use under the MACH(2.5) operating system.
4 *
5 * TRW Financial Systems, in accordance with their agreement with Carnegie
6 * Mellon University, makes this software available to CMU to distribute
7 * or use in any manner that they see fit as long as this message is kept with
8 * the software. For this reason TFS also grants any other persons or
9 * organisations permission to use or modify this software.
10 *
11 * TFS supplies this software to be publicly redistributed
12 * on the understanding that TFS is not responsible for the correct
13 * functioning of this software in any circumstances.
14 *
15 * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
16 *
17 * $FreeBSD: src/sys/scsi/sd.c,v 1.95.2.11 1999/09/05 08:21:49 peter Exp $
18 */
19
20 #include "opt_bounce.h"
21 #include "opt_scsi.h"
22
23 #define SPLSD splbio
24 #include <sys/param.h>
25 #include <sys/kernel.h>
26 #include <sys/dkbad.h>
27 #include <sys/systm.h>
28 #include <sys/ioctl.h>
29 #include <sys/buf.h>
30 #include <sys/disklabel.h>
31 #include <sys/diskslice.h>
32 #include <sys/dkstat.h>
33 #include <sys/errno.h>
34 #include <sys/malloc.h>
35 #include <sys/conf.h>
36 #ifdef DEVFS
37 #include <sys/devfsext.h>
38 #endif /*DEVFS*/
39
40 #include <scsi/scsi_all.h>
41 #include <scsi/scsi_disk.h>
42 #include <scsi/scsiconf.h>
43
44 #include <vm/vm.h>
45 #include <vm/vm_param.h>
46 #include <vm/vm_prot.h>
47 #include <vm/pmap.h>
48 #include <machine/md_var.h>
49 #include <i386/i386/cons.h> /* XXX *//* for aborting dump */
50 #ifdef PC98
51 #include <pc98/pc98/pc98_machdep.h>
52 #endif
53
54 static u_int32_t sdstrats, sdqueues;
55
56 #define SECSIZE 512
57 #ifdef PC98
58 #define SDOUTSTANDING 2
59 #else
60 #define SDOUTSTANDING 4
61 #endif
62 #define SD_RETRIES 4
63 #define MAXTRANSFER 8 /* 1 page at a time */
64
65 #define PARTITION(dev) dkpart(dev)
66 #define SDUNIT(dev) dkunit(dev)
67
68 /* XXX introduce a dkmodunit() macro for this. */
69 #define SDSETUNIT(DEV, U) \
70 makedev(major(DEV), dkmakeminor((U), dkslice(DEV), dkpart(DEV)))
71
72 static errval sd_get_parms __P((int unit, int flags));
73 static errval sd_reassign_blocks __P((int unit, int block));
74 static u_int32_t sd_size __P((int unit, int flags, int *secsize));
75 static void sdstrategy1 __P((struct buf *));
76
77 static int sd_sense_handler __P((struct scsi_xfer *));
78 static void sdstart __P((u_int32_t, u_int32_t));
79
80 struct scsi_data {
81 u_int32_t flags;
82 #define SDINIT 0x04 /* device has been init'd */
83 struct disk_parms {
84 u_char heads; /* Number of heads */
85 u_int16_t cyls; /* Number of cylinders */
86 u_char sectors; /*dubious *//* Number of sectors/track */
87 u_int16_t secsiz; /* Number of bytes/sector */
88 u_int32_t disksize; /* total number sectors */
89 } params;
90 struct diskslices *dk_slices; /* virtual drives */
91 struct buf_queue_head buf_queue;
92 int dkunit; /* disk stats unit number */
93 #ifdef DEVFS
94 void *b_devfs_token;
95 void *c_devfs_token;
96 void *ctl_devfs_token;
97 #endif
98 };
99
100 static int sdunit(dev_t dev) { return SDUNIT(dev); }
101 static dev_t sdsetunit(dev_t dev, int unit) { return SDSETUNIT(dev, unit); }
102
103 static errval sd_open __P((dev_t dev, int mode, int fmt, struct proc *p,
104 struct scsi_link *sc_link));
105 static errval sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
106 struct proc *p, struct scsi_link *sc_link);
107 static errval sd_close __P((dev_t dev, int fflag, int fmt, struct proc *p,
108 struct scsi_link *sc_link));
109 static void sd_strategy(struct buf *bp, struct scsi_link *sc_link);
110
111 static d_open_t sdopen;
112 static d_close_t sdclose;
113 static d_ioctl_t sdioctl;
114 static d_dump_t sddump;
115 static d_psize_t sdsize;
116 static d_strategy_t sdstrategy;
117
118 #define CDEV_MAJOR 13
119 #define BDEV_MAJOR 4
120 static struct cdevsw sd_cdevsw;
121 static struct bdevsw sd_bdevsw =
122 { sdopen, sdclose, sdstrategy, sdioctl, /*4*/
123 sddump, sdsize, 0, "sd", &sd_cdevsw, -1 };
124
125
126
127 SCSI_DEVICE_ENTRIES(sd)
128
129 static struct scsi_device sd_switch =
130 {
131 sd_sense_handler,
132 sdstart, /* have a queue, served by this */
133 NULL, /* have no async handler */
134 NULL, /* Use default 'done' routine */
135 "sd",
136 0,
137 {0, 0},
138 0, /* Link flags */
139 sdattach,
140 "Direct-Access",
141 sdopen,
142 sizeof(struct scsi_data),
143 T_DIRECT,
144 sdunit,
145 sdsetunit,
146 sd_open,
147 sd_ioctl,
148 sd_close,
149 sd_strategy,
150 };
151
152 static struct scsi_xfer sx;
153
154
155 static __inline void
156 sd_registerdev(int unit)
157 {
158 if(dk_ndrive < DK_NDRIVE) {
159 sprintf(dk_names[dk_ndrive], "sd%d", unit);
160 dk_wpms[dk_ndrive] = (8*1024*1024/2);
161 SCSI_DATA(&sd_switch, unit)->dkunit = dk_ndrive++;
162 } else {
163 SCSI_DATA(&sd_switch, unit)->dkunit = -1;
164 }
165 }
166
167
168 /*
169 * The routine called by the low level scsi routine when it discovers
170 * a device suitable for this driver.
171 */
172 static errval
173 sdattach(struct scsi_link *sc_link)
174 {
175 u_int32_t unit;
176 struct disk_parms *dp;
177 #ifdef DEVFS
178 int mynor;
179 #endif
180
181 struct scsi_data *sd = sc_link->sd;
182
183 unit = sc_link->dev_unit;
184
185 dp = &(sd->params);
186
187 if (sc_link->opennings > SDOUTSTANDING)
188 sc_link->opennings = SDOUTSTANDING;
189
190 bufq_init(&sd->buf_queue);
191 /*
192 * In case it is a funny one, tell it to start
193 * not needed for most hard drives (ignore failure)
194 */
195 scsi_start_unit(sc_link,
196 SCSI_ERR_OK | SCSI_SILENT | SCSI_NOSLEEP | SCSI_NOMASK);
197 /*
198 * Use the subdriver to request information regarding
199 * the drive. We cannot use interrupts yet, so the
200 * request must specify this.
201 */
202 sd_get_parms(unit, SCSI_NOSLEEP | SCSI_NOMASK);
203 /*
204 * if we don't have actual parameters, assume 512 bytes/sec
205 * (could happen on removable media - MOD)
206 * -- this avoids the division below from falling over
207 */
208 if(dp->secsiz == 0) dp->secsiz = SECSIZE;
209 printf("%ldMB (%ld %d byte sectors)",
210 dp->disksize / ((1024L * 1024L) / dp->secsiz),
211 dp->disksize,
212 dp->secsiz);
213
214 #ifndef SCSI_REPORT_GEOMETRY
215 if ( (sc_link->flags & SDEV_BOOTVERBOSE) )
216 #endif
217 {
218 sc_print_addr(sc_link);
219 printf("with %d cyls, %d heads, and an average %d sectors/track",
220 dp->cyls, dp->heads, dp->sectors);
221 }
222
223 sd->flags |= SDINIT;
224 sd_registerdev(unit);
225
226 #ifdef DEVFS
227 mynor = dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART);
228 sd->b_devfs_token = devfs_add_devswf(&sd_bdevsw, mynor, DV_BLK,
229 UID_ROOT, GID_OPERATOR, 0640,
230 "sd%d", unit);
231 sd->c_devfs_token = devfs_add_devswf(&sd_cdevsw, mynor, DV_CHR,
232 UID_ROOT, GID_OPERATOR, 0640,
233 "rsd%d", unit);
234 mynor = dkmakeminor(unit, 0, 0); /* XXX */
235 sd->ctl_devfs_token = devfs_add_devswf(&sd_cdevsw,
236 mynor | SCSI_CONTROL_MASK,
237 DV_CHR,
238 UID_ROOT, GID_WHEEL, 0600,
239 "rsd%d.ctl", unit);
240 #endif
241
242 return 0;
243 }
244
245 /*
246 * open the device. Make sure the partition info is a up-to-date as can be.
247 */
248 static errval
249 sd_open(dev, mode, fmt, p, sc_link)
250 dev_t dev;
251 int mode;
252 int fmt;
253 struct proc *p;
254 struct scsi_link *sc_link;
255 {
256 errval errcode = 0;
257 u_int32_t unit;
258 struct disklabel label;
259 struct scsi_data *sd;
260
261 unit = SDUNIT(dev);
262 sd = sc_link->sd;
263
264 /*
265 * Make sure the disk has been initialised
266 * At some point in the future, get the scsi driver
267 * to look for a new device if we are not initted
268 */
269 if ((!sd) || (!(sd->flags & SDINIT))) {
270 return (ENXIO);
271 }
272
273 SC_DEBUG(sc_link, SDEV_DB1,
274 ("sd_open: dev=0x%lx (unit %ld, partition %d)\n",
275 dev, unit, PARTITION(dev)));
276
277 /*
278 * "unit attention" errors should occur here if the
279 * drive has been restarted or the pack changed.
280 * just ingnore the result, it's a decoy instruction
281 * The error handlers will act on the error though
282 * and invalidate any media information we had.
283 */
284 scsi_test_unit_ready(sc_link, 0);
285
286 /*
287 * If it's been invalidated, then forget the label
288 */
289 sc_link->flags |= SDEV_OPEN; /* unit attn becomes an err now */
290 if (!(sc_link->flags & SDEV_MEDIA_LOADED) && sd->dk_slices != NULL) {
291 /*
292 * If somebody still has it open, then forbid re-entry.
293 */
294 if (dsisopen(sd->dk_slices)) {
295 errcode = ENXIO;
296 goto bad;
297 }
298
299 dsgone(&sd->dk_slices);
300 }
301
302 /*
303 * Check that it is still responding and ok.
304 */
305 if (scsi_test_unit_ready(sc_link, 0)) {
306 SC_DEBUG(sc_link, SDEV_DB3, ("device not reponding\n"));
307 errcode = ENXIO;
308 goto bad;
309 }
310 SC_DEBUG(sc_link, SDEV_DB3, ("device ok\n"));
311
312 /*
313 * Load the physical device parameters
314 */
315 sd_get_parms(unit, 0); /* sets SDEV_MEDIA_LOADED */
316 /* Hack for some special disk in disk arrays */
317 if ( sd->params.secsiz == 528 ){
318 printf("sd%ld: Forcing sector size to %d\n", unit, SECSIZE);
319 sd->params.secsiz = SECSIZE;
320 }
321
322 if (sd->params.secsiz != SECSIZE) { /* XXX One day... */
323 printf("sd%ld: Can't deal with %d bytes logical blocks\n",
324 unit, sd->params.secsiz);
325 Debugger("sd");
326 errcode = ENXIO;
327 goto bad;
328 }
329 SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded "));
330
331 /* Lock the pack in. */
332 scsi_prevent(sc_link, PR_PREVENT, SCSI_ERR_OK | SCSI_SILENT);
333
334 /* Build label for whole disk. */
335 bzero(&label, sizeof label);
336 label.d_secsize = sd->params.secsiz;
337 label.d_nsectors = sd->params.sectors;
338 label.d_ntracks = sd->params.heads;
339 label.d_ncylinders = sd->params.cyls;
340 label.d_secpercyl = sd->params.heads * sd->params.sectors;
341 if (label.d_secpercyl == 0)
342 label.d_secpercyl = 100;
343 /* XXX as long as it's not 0 - readdisklabel divides by it (?) */
344 label.d_secperunit = sd->params.disksize;
345
346 /* Initialize slice tables. */
347 errcode = dsopen("sd", dev, fmt, &sd->dk_slices, &label, sdstrategy1,
348 (ds_setgeom_t *)NULL, &sd_bdevsw, &sd_cdevsw);
349 if (errcode != 0)
350 goto bad;
351 SC_DEBUG(sc_link, SDEV_DB3, ("Slice tables initialized "));
352
353 SC_DEBUG(sc_link, SDEV_DB3, ("open %ld %ld\n", sdstrats, sdqueues));
354
355 return 0;
356
357 bad:
358 if (!dsisopen(sd->dk_slices)) {
359 scsi_prevent(sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT);
360 sc_link->flags &= ~SDEV_OPEN;
361 }
362 return errcode;
363 }
364
365 /*
366 * close the device.. only called if we are the LAST occurence of an open
367 * device. Convenient now but usually a pain.
368 */
369 static errval
370 sd_close(dev, fflag, fmt, p, sc_link)
371 dev_t dev;
372 int fflag;
373 int fmt;
374 struct proc *p;
375 struct scsi_link *sc_link;
376 {
377 struct scsi_data *sd;
378
379 sd = sc_link->sd;
380 dsclose(dev, fmt, sd->dk_slices);
381 if (!dsisopen(sd->dk_slices)) {
382 scsi_prevent(sc_link, PR_ALLOW, SCSI_SILENT | SCSI_ERR_OK);
383 sc_link->flags &= ~SDEV_OPEN;
384 }
385 return (0);
386 }
387
388 /*
389 * Actually translate the requested transfer into one the physical driver
390 * can understand. The transfer is described by a buf and will include
391 * only one physical transfer.
392 */
393 static void
394 sd_strategy(struct buf *bp, struct scsi_link *sc_link)
395 {
396 u_int32_t opri;
397 struct scsi_data *sd;
398 u_int32_t unit;
399
400 sdstrats++;
401 unit = SDUNIT((bp->b_dev));
402 sd = sc_link->sd;
403 /*
404 * If the device has been made invalid, error out
405 */
406 if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
407 bp->b_error = EIO;
408 goto bad;
409 }
410
411 /*
412 * check it's not too big a transfer for our adapter
413 */
414 scsi_minphys(bp,&sd_switch);
415
416 /*
417 * Odd number of bytes or negative offset
418 */
419 if (bp->b_blkno < 0 || bp->b_bcount % DEV_BSIZE != 0) {
420 bp->b_error = EINVAL;
421 goto bad;
422 }
423 /*
424 * Do bounds checking, adjust transfer, set b_cylin and b_pbklno.
425 */
426 if (dscheck(bp, sd->dk_slices) <= 0)
427 goto done; /* XXX check b_resid */
428
429 opri = SPLSD();
430 /*
431 * Use a bounce buffer if necessary
432 */
433 #ifdef BOUNCE_BUFFERS
434 if (sc_link->flags & SDEV_BOUNCE)
435 vm_bounce_alloc(bp);
436 #endif
437
438 /*
439 * Place it in the queue of disk activities for this disk
440 */
441 #ifdef SDDISKSORT
442 bufq_disksort(&sd->buf_queue, bp);
443 #else
444 bufq_insert_tail(&sd->buf_queue, bp);
445 #endif
446
447 /*
448 * Tell the device to get going on the transfer if it's
449 * not doing anything, otherwise just wait for completion
450 */
451 sdstart(unit, 0);
452
453 splx(opri);
454 return /**/;
455 bad:
456 bp->b_flags |= B_ERROR;
457 done:
458
459 /*
460 * Correctly set the buf to indicate a completed xfer
461 */
462 bp->b_resid = bp->b_bcount;
463 biodone(bp);
464 return /**/;
465 }
466
467 static void
468 sdstrategy1(struct buf *bp)
469 {
470 /*
471 * XXX - do something to make sdstrategy() but not this block while
472 * we're doing dsinit() and dsioctl().
473 */
474 sdstrategy(bp);
475 }
476
477 /*
478 * sdstart looks to see if there is a buf waiting for the device
479 * and that the device is not already busy. If both are true,
480 * It dequeues the buf and creates a scsi command to perform the
481 * transfer in the buf. The transfer request will call scsi_done
482 * on completion, which will in turn call this routine again
483 * so that the next queued transfer is performed.
484 * The bufs are queued by the strategy routine (sdstrategy)
485 *
486 * This routine is also called after other non-queued requests
487 * have been made of the scsi driver, to ensure that the queue
488 * continues to be drained.
489 *
490 * must be called at the correct (highish) spl level
491 * sdstart() is called at SPLSD from sdstrategy and scsi_done
492 */
493 static void
494 sdstart(u_int32_t unit, u_int32_t flags)
495 {
496 register struct scsi_link *sc_link = SCSI_LINK(&sd_switch, unit);
497 register struct scsi_data *sd = sc_link->sd;
498 struct buf *bp = NULL;
499 struct scsi_rw_big cmd;
500 u_int32_t blkno, nblk;
501
502 SC_DEBUG(sc_link, SDEV_DB2, ("sdstart "));
503 /*
504 * Check if the device has room for another command
505 */
506 while (sc_link->opennings) {
507
508 /*
509 * there is excess capacity, but a special waits
510 * It'll need the adapter as soon as we clear out of the
511 * way and let it run (user level wait).
512 */
513 if (sc_link->flags & SDEV_WAITING) {
514 return;
515 }
516 /*
517 * See if there is a buf with work for us to do..
518 */
519 bp = bufq_first(&sd->buf_queue);
520 if (bp == NULL) { /* yes, an assign */
521 return;
522 }
523 bufq_remove(&sd->buf_queue, bp);
524
525 /*
526 * If the device has become invalid, abort all the
527 * reads and writes until all files have been closed and
528 * re-openned
529 */
530 if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
531 goto bad;
532 }
533 /*
534 * We have a buf, now we know we are going to go through
535 * With this thing..
536 */
537 blkno = bp->b_pblkno;
538 if (bp->b_bcount & (SECSIZE - 1))
539 {
540 goto bad;
541 }
542 nblk = bp->b_bcount >> 9;
543
544 /*
545 * Fill out the scsi command
546 */
547 cmd.op_code = (bp->b_flags & B_READ)
548 ? READ_BIG : WRITE_BIG;
549 cmd.addr_3 = (blkno & 0xff000000UL) >> 24;
550 cmd.addr_2 = (blkno & 0xff0000) >> 16;
551 cmd.addr_1 = (blkno & 0xff00) >> 8;
552 cmd.addr_0 = blkno & 0xff;
553 cmd.length2 = (nblk & 0xff00) >> 8;
554 cmd.length1 = (nblk & 0xff);
555 cmd.byte2 = cmd.reserved = cmd.control = 0;
556 /*
557 * Call the routine that chats with the adapter.
558 * Note: we cannot sleep as we may be an interrupt
559 */
560 if (scsi_scsi_cmd(sc_link,
561 (struct scsi_generic *) &cmd,
562 sizeof(cmd),
563 (u_char *) bp->b_un.b_addr,
564 bp->b_bcount,
565 SD_RETRIES,
566 10000,
567 bp,
568 flags | ((bp->b_flags & B_READ) ?
569 SCSI_DATA_IN : SCSI_DATA_OUT))
570 == SUCCESSFULLY_QUEUED) {
571 sdqueues++;
572 if(sd->dkunit >= 0) {
573 dk_xfer[sd->dkunit]++;
574 dk_seek[sd->dkunit]++; /* don't know */
575 dk_wds[sd->dkunit] += bp->b_bcount >> 6;
576 }
577 } else {
578 bad:
579 printf("sd%ld: oops not queued\n", unit);
580 bp->b_error = EIO;
581 bp->b_flags |= B_ERROR;
582 biodone(bp);
583 }
584 }
585 }
586
587 /*
588 * Perform special action on behalf of the user
589 * Knows about the internals of this device
590 */
591 static errval
592 sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p,
593 struct scsi_link *sc_link)
594 {
595 /* struct sd_cmd_buf *args; */
596 errval error;
597 struct scsi_data *sd;
598
599 /*
600 * Find the device that the user is talking about
601 */
602 sd = sc_link->sd;
603 SC_DEBUG(sc_link, SDEV_DB1, ("sdioctl (0x%x)", cmd));
604
605 #if 0
606 /* Wait until we have exclusive access to the device. */
607 /* XXX this is how wd does it. How did we work without this? */
608 wdsleep(du->dk_ctrlr, "wdioct");
609 #endif
610
611 /*
612 * If the device is not valid.. abandon ship
613 */
614 if (!(sc_link->flags & SDEV_MEDIA_LOADED))
615 return (EIO);
616
617 if (cmd == DIOCSBAD)
618 return (EINVAL); /* XXX */
619 error = dsioctl("sd", dev, cmd, addr, flag, &sd->dk_slices,
620 sdstrategy1, (ds_setgeom_t *)NULL);
621 if (error != -1)
622 return (error);
623 if (PARTITION(dev) != RAW_PART)
624 return (ENOTTY);
625 return (scsi_do_ioctl(dev, cmd, addr, flag, p, sc_link));
626 }
627
628 /*
629 * Find out from the device what it's capacity is
630 */
631 static u_int32_t
632 sd_size(unit, flags, secsize)
633 int unit, flags;
634 int *secsize;
635 {
636 struct scsi_read_cap_data rdcap;
637 struct scsi_read_capacity scsi_cmd;
638 u_int32_t size;
639 struct scsi_link *sc_link = SCSI_LINK(&sd_switch, unit);
640
641 /*
642 * make up a scsi command and ask the scsi driver to do
643 * it for you.
644 */
645 bzero(&scsi_cmd, sizeof(scsi_cmd));
646 scsi_cmd.op_code = READ_CAPACITY;
647
648 /*
649 * If the command works, interpret the result as a 4 byte
650 * number of blocks
651 */
652 if (scsi_scsi_cmd(sc_link,
653 (struct scsi_generic *) &scsi_cmd,
654 sizeof(scsi_cmd),
655 (u_char *) & rdcap,
656 sizeof(rdcap),
657 SD_RETRIES,
658 2000,
659 NULL,
660 flags | SCSI_DATA_IN) != 0) {
661 printf("sd%d: could not get size\n", unit);
662 *secsize = 0;
663 size = 0;
664 } else {
665 *secsize = scsi_4btou(&rdcap.length_3);
666 size = scsi_4btou(&rdcap.addr_3) + 1;
667 }
668 return (size);
669 }
670
671 /*
672 * Tell the device to map out a defective block
673 */
674 static errval
675 sd_reassign_blocks(unit, block)
676 int unit, block;
677 {
678 struct scsi_reassign_blocks scsi_cmd;
679 struct scsi_reassign_blocks_data rbdata;
680 struct scsi_link *sc_link = SCSI_LINK(&sd_switch, unit);
681
682 bzero(&scsi_cmd, sizeof(scsi_cmd));
683 bzero(&rbdata, sizeof(rbdata));
684 scsi_cmd.op_code = REASSIGN_BLOCKS;
685
686 rbdata.length_msb = 0;
687 rbdata.length_lsb = sizeof(rbdata.defect_descriptor[0]);
688 rbdata.defect_descriptor[0].dlbaddr_3 = ((block >> 24) & 0xff);
689 rbdata.defect_descriptor[0].dlbaddr_2 = ((block >> 16) & 0xff);
690 rbdata.defect_descriptor[0].dlbaddr_1 = ((block >> 8) & 0xff);
691 rbdata.defect_descriptor[0].dlbaddr_0 = ((block) & 0xff);
692
693 return (scsi_scsi_cmd(sc_link,
694 (struct scsi_generic *) &scsi_cmd,
695 sizeof(scsi_cmd),
696 (u_char *) & rbdata,
697 sizeof(rbdata),
698 SD_RETRIES,
699 5000,
700 NULL,
701 SCSI_DATA_OUT));
702 }
703 #define b2tol(a) (((unsigned)(a##_1) << 8) + (unsigned)a##_0 )
704
705 /*
706 * Get the scsi driver to send a full inquiry to the
707 * device and use the results to fill out the disk
708 * parameter structure.
709 */
710 static errval
711 sd_get_parms(unit, flags)
712 int unit, flags;
713 {
714 struct scsi_link *sc_link = SCSI_LINK(&sd_switch, unit);
715 struct scsi_data *sd = sc_link->sd;
716 struct disk_parms *disk_parms = &sd->params;
717 struct scsi_mode_sense scsi_cmd;
718 struct scsi_mode_sense_data {
719 struct scsi_mode_header header;
720 struct blk_desc blk_desc;
721 union disk_pages pages;
722 } scsi_sense;
723 u_int32_t sectors;
724 u_int32_t secsize;
725
726 /*
727 * First check if we have it all loaded
728 */
729 if (sc_link->flags & SDEV_MEDIA_LOADED)
730 return 0;
731
732 sectors = sd_size(unit, flags, &secsize);
733
734 /*
735 * do a "mode sense page 4"
736 */
737 bzero(&scsi_cmd, sizeof(scsi_cmd));
738 scsi_cmd.op_code = MODE_SENSE;
739 scsi_cmd.page = 4;
740 scsi_cmd.length = 0x20;
741 #ifdef PC98
742 if (sd_bios_parms(disk_parms, sc_link)) {
743 } else
744 #endif
745 /*
746 * If the command worked, use the results to fill out
747 * the parameter structure
748 */
749 if (scsi_scsi_cmd(sc_link,
750 (struct scsi_generic *) &scsi_cmd,
751 sizeof(scsi_cmd),
752 (u_char *) & scsi_sense,
753 sizeof(scsi_sense),
754 SD_RETRIES,
755 4000,
756 NULL,
757 flags | SCSI_DATA_IN) != 0) {
758
759 printf("sd%d could not mode sense (4).", unit);
760 printf(" Using fictitious geometry\n");
761 /*
762 * use adaptec standard fictitious geometry
763 * this depends on which controller (e.g. 1542C is
764 * different. but we have to put SOMETHING here..)
765 */
766 disk_parms->heads = 64;
767 disk_parms->sectors = 32;
768 disk_parms->cyls = sectors / (64 * 32);
769 disk_parms->secsiz = secsize;
770 disk_parms->disksize = sectors;
771 } else {
772
773 SC_DEBUG(sc_link, SDEV_DB3,
774 ("%ld cyls, %d heads, %d precomp, %d red_write, %d land_zone\n",
775 scsi_3btou(&scsi_sense.pages.rigid_geometry.ncyl_2),
776 scsi_sense.pages.rigid_geometry.nheads,
777 b2tol(scsi_sense.pages.rigid_geometry.st_cyl_wp),
778 b2tol(scsi_sense.pages.rigid_geometry.st_cyl_rwc),
779 b2tol(scsi_sense.pages.rigid_geometry.land_zone)));
780
781 /*
782 * KLUDGE!!(for zone recorded disks)
783 * give a number of sectors so that sec * trks * cyls
784 * is <= disk_size
785 * can lead to wasted space! THINK ABOUT THIS !
786 */
787 disk_parms->heads = scsi_sense.pages.rigid_geometry.nheads;
788 disk_parms->cyls = scsi_3btou(&scsi_sense.pages.rigid_geometry.ncyl_2);
789 disk_parms->secsiz = scsi_3btou(scsi_sense.blk_desc.blklen);
790
791 sectors = sd_size(unit, flags, &secsize);
792 disk_parms->disksize = sectors;
793 /* Check if none of these values are zero */
794 if(disk_parms->heads && disk_parms->cyls) {
795 sectors /= (disk_parms->heads * disk_parms->cyls);
796 }
797 else {
798 /* set it to something reasonable */
799 disk_parms->heads = 64;
800 disk_parms->cyls = sectors / (64 * 32);
801 sectors = 32;
802 }
803 /* keep secsiz sane too - we may divide by it later */
804 if(disk_parms->secsiz == 0)
805 disk_parms->secsiz = SECSIZE;
806 disk_parms->sectors = sectors; /* dubious on SCSI *//*XXX */
807 }
808 sc_link->flags |= SDEV_MEDIA_LOADED;
809 return 0;
810 }
811
812 static int
813 sdsize(dev_t dev)
814 {
815 struct scsi_data *sd;
816
817 sd = SCSI_DATA(&sd_switch, (u_int32_t) SDUNIT(dev));
818 if (sd == NULL)
819 return (-1);
820 return (dssize(dev, &sd->dk_slices, sdopen, sdclose));
821 }
822
823 /*
824 * sense handler: Called to determine what to do when the
825 * device returns a CHECK CONDITION.
826 *
827 * This will issue a retry when the device returns a
828 * non-media hardware failure. The CDC-WREN IV does this
829 * when you access it during thermal calibrarion, so the drive
830 * is pretty useless without this.
831 *
832 * In general, you probably almost always would like to issue a retry
833 * for your disk I/O. It can't hurt too much (the caller only retries
834 * so many times) and it may save your butt.
835 */
836
837 static int
838 sd_sense_handler(struct scsi_xfer *xs)
839 {
840 struct scsi_sense_data *sense;
841 struct scsi_inquiry_data *inqbuf;
842
843 sense = &(xs->sense);
844
845 /* I don't know what the heck to do with a deferred error,
846 * so I'll just kick it back to the caller.
847 */
848 if ((sense->error_code & SSD_ERRCODE) == 0x71)
849 return SCSIRET_CONTINUE;
850
851 if (((sense->error_code & SSD_ERRCODE) == 0x70) &&
852 ((sense->ext.extended.flags & SSD_KEY) == 0x05))
853 /* No point in retrying Illegal Requests */
854 return SCSIRET_CONTINUE;
855
856 inqbuf = &(xs->sc_link->inqbuf);
857
858 /* It is dangerous to retry on removable drives without
859 * looking carefully at the additional sense code
860 * and sense code qualifier and ensuring the disk hasn't changed:
861 */
862 if (inqbuf->dev_qual2 & SID_REMOVABLE)
863 return SCSIRET_CONTINUE;
864
865 /* Retry all disk errors.
866 */
867 scsi_sense_print(xs);
868 if (xs->retries)
869 printf(", retries:%d\n", xs->retries);
870 else
871 printf(", FAILURE\n");
872
873 return SCSIRET_DO_RETRY;
874 }
875
876 /*
877 * dump all of physical memory into the partition specified, starting
878 * at offset 'dumplo' into the partition.
879 */
880 static errval
881 sddump(dev_t dev)
882 { /* dump core after a system crash */
883 struct disklabel *lp;
884 register struct scsi_data *sd; /* disk unit to do the IO */
885 struct scsi_link *sc_link;
886 int32_t num; /* number of sectors to write */
887 u_int32_t unit, part;
888 int32_t blkoff, blknum, blkcnt = MAXTRANSFER;
889 int32_t nblocks;
890 char *addr;
891 struct scsi_rw_big cmd;
892 static int sddoingadump = 0;
893 struct scsi_xfer *xs = &sx;
894 errval retval;
895
896 addr = (char *) 0; /* starting address */
897
898 /* toss any characters present prior to dump */
899 while (cncheckc() != -1)
900 ;
901
902 /* size of memory to dump */
903 num = Maxmem;
904 unit = SDUNIT(dev); /* eventually support floppies? */
905 part = PARTITION(dev); /* file system */
906
907 sc_link = SCSI_LINK(&sd_switch, unit);
908
909 if (!sc_link)
910 return ENXIO;
911
912 sd = sc_link->sd;
913
914 /* was it ever initialized etc. ? */
915 if (!(sd->flags & SDINIT))
916 return (ENXIO);
917 if ((sc_link->flags & SDEV_MEDIA_LOADED) != SDEV_MEDIA_LOADED)
918 return (ENXIO);
919 if (sd->dk_slices == NULL)
920 Debugger("sddump: no slices");
921 if ((lp = dsgetlabel(dev, sd->dk_slices)) == NULL)
922 return (ENXIO);
923
924 /* Convert to disk sectors */
925 num = (u_int32_t) num * PAGE_SIZE / sd->params.secsiz; /* XXX it must be 512 */
926
927 /* check if controller active */
928 if (sddoingadump)
929 return (EFAULT);
930
931 nblocks = lp->d_partitions[part].p_size;
932 blkoff = lp->d_partitions[part].p_offset;
933 /* XXX */
934 blkoff += sd->dk_slices->dss_slices[dkslice(dev)].ds_offset;
935
936 /* check transfer bounds against partition size */
937 if ((dumplo < 0) || ((dumplo + num) > nblocks))
938 return (EINVAL);
939
940 sddoingadump = 1;
941
942 blknum = dumplo + blkoff;
943 while (num > 0) {
944 if (is_physical_memory((vm_offset_t)addr))
945 pmap_enter(kernel_pmap, (vm_offset_t)CADDR1,
946 trunc_page(addr), VM_PROT_READ, TRUE);
947 else
948 pmap_enter(kernel_pmap, (vm_offset_t)CADDR1,
949 trunc_page(0), VM_PROT_READ, TRUE);
950 /*
951 * Fill out the scsi command
952 */
953 bzero(&cmd, sizeof(cmd));
954 cmd.op_code = WRITE_BIG;
955 cmd.addr_3 = (blknum & 0xff000000) >> 24;
956 cmd.addr_2 = (blknum & 0xff0000) >> 16;
957 cmd.addr_1 = (blknum & 0xff00) >> 8;
958 cmd.addr_0 = blknum & 0xff;
959 cmd.length2 = (blkcnt & 0xff00) >> 8;
960 cmd.length1 = (blkcnt & 0xff);
961 /*
962 * Fill out the scsi_xfer structure
963 * Note: we cannot sleep as we may be an interrupt
964 * don't use scsi_scsi_cmd() as it may want
965 * to wait for an xs.
966 */
967 bzero(xs, sizeof(sx));
968 xs->flags |= SCSI_NOMASK | SCSI_NOSLEEP | INUSE | SCSI_DATA_OUT;
969 xs->sc_link = sc_link;
970 xs->retries = SD_RETRIES;
971 xs->timeout = 10000; /* 10000 millisecs for a disk ! */
972 xs->cmd = (struct scsi_generic *) &cmd;
973 xs->cmdlen = sizeof(cmd);
974 xs->resid = 0;
975 xs->error = XS_NOERROR;
976 xs->bp = 0;
977 xs->data = (u_char *) CADDR1; /* XXX use pmap_enter() */
978 xs->datalen = blkcnt * SECSIZE;
979
980 /*
981 * Pass all this info to the scsi driver.
982 */
983 retval = (*(sc_link->adapter->scsi_cmd)) (xs);
984 switch (retval) {
985 case SUCCESSFULLY_QUEUED:
986 case HAD_ERROR:
987 return (ENXIO); /* we said not to sleep! */
988 case COMPLETE:
989 break;
990 default:
991 return (ENXIO); /* we said not to sleep! */
992 }
993
994 /*
995 * If we are dumping core, it may take a while.
996 * So reassure the user and hold off any watchdogs.
997 */
998 if ((unsigned)addr % (1024 * 1024) == 0) {
999 #ifdef HW_WDOG
1000 if (wdog_tickler)
1001 (*wdog_tickler)();
1002 #endif /* HW_WDOG */
1003 printf("%ld ", num / 2048);
1004 }
1005 /* update block count */
1006 num -= blkcnt;
1007 blknum += blkcnt;
1008 (int) addr += SECSIZE * blkcnt;
1009
1010 /* operator aborting dump? */
1011 if (cncheckc() != -1)
1012 return (EINTR);
1013 }
1014 return (0);
1015 }
1016
1017 static sd_devsw_installed = 0;
1018
1019 static void sd_drvinit(void *unused)
1020 {
1021
1022 if( ! sd_devsw_installed ) {
1023 bdevsw_add_generic(BDEV_MAJOR, CDEV_MAJOR, &sd_bdevsw);
1024 sd_devsw_installed = 1;
1025 }
1026 }
1027
1028 SYSINIT(sddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,sd_drvinit,NULL)
1029
Cache object: 5ad06b2dd84f2313b12a221293265b0d
|