sd.c revision 1.5 1 /*
2 * Written by Julian Elischer (julian (at) tfs.com)
3 * Hacked by Theo de Raadt <deraadt (at) fsa.ca>
4 * for TRW Financial Systems for use under the MACH(2.5) operating system.
5 *
6 * TRW Financial Systems, in accordance with their agreement with Carnegie
7 * Mellon University, makes this software available to CMU to distribute
8 * or use in any manner that they see fit as long as this message is kept with
9 * the software. For this reason TFS also grants any other persons or
10 * organisations permission to use or modify this software.
11 *
12 * TFS supplies this software to be publicly redistributed
13 * on the understanding that TFS is not responsible for the correct
14 * functioning of this software in any circumstances.
15 */
16
17 #include "sd.h"
18
19 #include "sys/types.h"
20 #include "sys/param.h"
21 #include "sys/dkbad.h"
22 #include "sys/systm.h"
23 #include "sys/conf.h"
24 #include "sys/proc.h"
25 #include "sys/file.h"
26 #include "sys/stat.h"
27 #include "sys/ioctl.h"
28 #include "sys/buf.h"
29 #include "sys/uio.h"
30 #include "sys/malloc.h"
31 #include "sys/errno.h"
32 #include "sys/disklabel.h"
33 #include "scsi/scsi_all.h"
34 #include "scsi/scsi_disk.h"
35 #include "scsi/scsiconf.h"
36 #include "scsi/sddefs.h"
37
38 long int sdstrats, sdqueues;
39
40 #define SPLSD splbio
41 #define ESUCCESS 0
42
43 #define SECSIZE 512
44 #define PDLOCATION 29
45 #define BOOTRECORDSIGNATURE (0x55aa & 0x00ff)
46 #define SDOUTSTANDING 2
47 #define SDQSIZE 4
48 #define SD_RETRIES 4
49
50 #define MAKESDDEV(maj, unit, part) (makedev(maj, ((unit<<3)+part)))
51 #define UNITSHIFT 3
52 #define PARTITION(z) (minor(z) & 0x07)
53 #define RAW_PART 3
54 #define UNIT(z) ( (minor(z) >> UNITSHIFT) )
55
56 #define WHOLE_DISK(unit) ( (unit << UNITSHIFT) + RAW_PART )
57
58 struct sd_data *sd_data[NSD];
59 int sd_debug = 0;
60
61 /*
62 * The routine called by the low level scsi routine when it discovers
63 * A device suitable for this driver
64 */
65 int
66 sdattach(int masunit, struct scsi_switch *sw, int physid, int unit)
67 {
68 struct scsi_xfer *sd_scsi_xfer;
69 struct disk_parms *dp;
70 struct sd_data *sd;
71 unsigned char *tbl;
72 long int ad_info;
73 int targ, lun, i;
74
75 targ = physid >> 3;
76 lun = physid & 7;
77
78 /*printf("sdattach: sd%d at %s%d target %d lun %d\n",
79 unit, sw->name, masunit, targ, lun);*/
80
81 if(unit > NSD)
82 return -1;
83 if(sd_data[unit])
84 return -1;
85
86 sd = sd_data[unit] = (struct sd_data *)malloc(sizeof *sd,
87 M_TEMP, M_NOWAIT);
88 if(!sd)
89 return -1;
90 bzero(sd, sizeof *sd);
91
92 /* store information needed to contact our base driver */
93 sd->sc_sw = sw;
94 sd->ctlr = masunit;
95 sd->targ = targ;
96 sd->lu = lun;
97
98 dp = &(sd->params);
99 if(scsi_debug & PRINTROUTINES)
100 printf("sdattach: ");
101
102 if(sd->sc_sw->adapter_info) {
103 sd->ad_info = ( (*(sd->sc_sw->adapter_info))(masunit));
104 sd->cmdscount = sd->ad_info & AD_INF_MAX_CMDS;
105 if(sd->cmdscount > SDOUTSTANDING)
106 sd->cmdscount = SDOUTSTANDING;
107 } else {
108 sd->ad_info = 1;
109 sd->cmdscount = 1;
110 }
111
112 i = sd->cmdscount;
113 sd_scsi_xfer = (struct scsi_xfer *)malloc(sizeof(struct scsi_xfer) * i,
114 M_TEMP, M_NOWAIT);
115 while(i--) {
116 sd_scsi_xfer->next = sd->freexfer;
117 sd->freexfer = sd_scsi_xfer;
118 sd_scsi_xfer++;
119 }
120
121 /*
122 * Use the subdriver to request information regarding
123 * the drive. We cannot use interrupts yet, so the
124 * request must specify this.
125 */
126 sd_get_parms(unit, SCSI_NOSLEEP | SCSI_NOMASK);
127 printf("sd%d at %s%d targ %d lun %d: %dMB cyl %d head %d sec %d byte/sec %d\n",
128 unit, sw->name, masunit, targ, lun,
129 (dp->cyls*dp->heads*dp->sectors*dp->secsiz)/ (1024*1024),
130 dp->cyls, dp->heads, dp->sectors, dp->secsiz);
131
132 sd->flags |= SDINIT;
133 return 0;
134 }
135
136
137 /*
138 * open the device. Make sure the partition info
139 * is a up-to-date as can be.
140 */
141 int
142 sdopen(int dev)
143 {
144 struct disk_parms disk_parms;
145 struct sd_data *sd;
146 int errcode = 0;
147 int unit, part;
148
149 unit = UNIT(dev);
150 part = PARTITION(dev);
151 if(scsi_debug & (PRINTROUTINES | TRACEOPENS))
152 printf("sdopen: dev=0x%x (unit %d (of %d),partition %d)\n",
153 dev, unit, NSD, part);
154
155 if(unit > NSD)
156 return ENXIO;
157 if( !sd_data[unit]) {
158 if(scsi_debug & PRINTROUTINES)
159 printf("nonexistant!\n");
160 return ENXIO;
161 }
162
163 sd = sd_data[unit];
164 if(!sd)
165 return ENXIO;
166 if( !(sd->flags & SDVALID) )
167 return ENXIO;
168
169 /*
170 * Make sure the disk has been initialised.
171 * XXX get the scsi driver to look for a new device if
172 * we are not initted, like SunOS
173 */
174 if( !(sd->flags & SDINIT))
175 return ENXIO;
176
177 /*
178 * If it's been invalidated, and not everybody has
179 * closed it then forbid re-entry.
180 */
181 if( !(sd->flags & SDVALID) && sd->openparts)
182 return ENXIO;
183
184 /*
185 * Check that it is still responding and ok.
186 * "unit attention errors should occur here if the drive
187 * has been restarted or the pack changed
188 */
189 if(scsi_debug & TRACEOPENS)
190 printf("device is ");
191
192 if (sd_test_unit_ready(unit, 0)) {
193 if(scsi_debug & TRACEOPENS)
194 printf("not reponding\n");
195 return ENXIO;
196 }
197 if(scsi_debug & TRACEOPENS)
198 printf("ok\n");
199
200 /*
201 * In case it is a funny one, tell it to start
202 * not needed for most hard drives (ignore failure)
203 */
204 sd_start_unit(unit, SCSI_ERR_OK|SCSI_SILENT);
205 if(scsi_debug & TRACEOPENS)
206 printf("started ");
207
208 /*
209 * Load the physical device parameters
210 */
211 sd_get_parms(unit, 0); /* sets SDVALID */
212 if( sd->params.secsiz != SECSIZE) {
213 printf("sd%d: Can't deal with %d bytes logical blocks\n",
214 unit, sd->params.secsiz);
215 return ENXIO;
216 }
217 if(scsi_debug & TRACEOPENS)
218 printf("Params loaded ");
219
220 /*
221 * Load the partition info if not already loaded
222 */
223 sd_prevent(unit, PR_PREVENT, SCSI_ERR_OK|SCSI_SILENT);
224 if( (errcode=sdgetdisklabel(unit)) && (part != RAW_PART)) {
225 sd_prevent(unit, PR_ALLOW, SCSI_ERR_OK|SCSI_SILENT);
226 return errcode;
227 }
228 if(scsi_debug & TRACEOPENS)
229 printf("Disklabel loaded ");
230
231 /*
232 * Check the partition is legal
233 */
234 if ( part >= MAXPARTITIONS ) {
235 sd_prevent(unit, PR_ALLOW, SCSI_ERR_OK|SCSI_SILENT);
236 return ENXIO;
237 }
238 if(scsi_debug & TRACEOPENS)
239 printf("ok");
240
241 /*
242 * Check that the partition exists
243 */
244 if( sd->disklabel.d_partitions[part].p_size==0 && part!=RAW_PART) {
245 sd_prevent(unit, PR_ALLOW, SCSI_ERR_OK|SCSI_SILENT);
246 return ENXIO;
247 }
248
249 sd->partflags[part] |= SDOPEN;
250 sd->openparts |= (1 << part);
251 if(scsi_debug & TRACEOPENS)
252 printf("open %d %d\n", sdstrats, sdqueues);
253 return 0;
254 }
255
256 /*
257 * Get ownership of a scsi_xfer
258 * If need be, sleep on it, until it comes free
259 */
260 struct scsi_xfer *
261 sd_get_xs(int unit, int flags)
262 {
263 struct sd_data *sd = sd_data[unit];
264 struct scsi_xfer *xs;
265 int s;
266
267 if(flags & (SCSI_NOSLEEP | SCSI_NOMASK)) {
268 if (xs = sd->freexfer) {
269 sd->freexfer = xs->next;
270 xs->flags = 0;
271 }
272 } else {
273 s = SPLSD();
274 while (!(xs = sd->freexfer)) {
275 sd->blockwait++; /* someone waiting! */
276 sleep((caddr_t)&sd->freexfer, PRIBIO+1);
277 sd->blockwait--;
278 }
279 sd->freexfer = xs->next;
280 splx(s);
281 xs->flags = 0;
282 }
283 return xs;
284 }
285
286 /*
287 * Free a scsi_xfer, wake processes waiting for it
288 */
289 void
290 sd_free_xs(int unit, struct scsi_xfer *xs, int flags)
291 {
292 struct sd_data *sd = sd_data[unit];
293 int s;
294
295 if(flags & SCSI_NOMASK) {
296 if (sd->blockwait) {
297 printf("doing a wakeup from NOMASK mode\n");
298 wakeup((caddr_t)&sd->freexfer);
299 }
300 xs->next = sd->freexfer;
301 sd->freexfer = xs;
302 } else {
303 s = SPLSD();
304 if (sd->blockwait)
305 wakeup((caddr_t)&sd->freexfer);
306 xs->next = sd->freexfer;
307 sd->freexfer = xs;
308 splx(s);
309 }
310 }
311
312 /*
313 * trim the size of the transfer if needed, called by physio
314 * basically the smaller of our max and the scsi driver's
315 * minphys (note we have no max)
316 */
317 void
318 sdminphys(struct buf *bp)
319 {
320 (*(sd_data[UNIT(bp->b_dev)]->sc_sw->scsi_minphys))(bp);
321 }
322
323 /*
324 * Actually translate the requested transfer into
325 * one the physical driver can understand
326 * The transfer is described by a buf and will include
327 * only one physical transfer.
328 */
329 int
330 sdstrategy(struct buf *bp)
331 {
332 struct sd_data *sd;
333 unsigned int opri;
334 struct buf *dp;
335 int unit;
336
337 sdstrats++;
338 unit = UNIT((bp->b_dev));
339
340 if(unit > NSD) {
341 printf("sdstrategy bailout: %d %d\n", unit, NSD);
342 bp->b_error = EIO;
343 goto bad;
344 }
345 if( !sd_data[unit]) {
346 printf("sdstrategy bailout\n");
347 bp->b_error = EIO;
348 goto bad;
349 }
350
351 sd = sd_data[unit];
352 if(scsi_debug & PRINTROUTINES)
353 printf("\nsdstrategy ");
354 if(scsi_debug & SHOWREQUESTS)
355 printf("sd%d: %d bytes @ blk%d\n",
356 unit, bp->b_bcount, bp->b_blkno);
357
358 sdminphys(bp);
359
360 /* If the device has been made invalid, error out */
361 if(!(sd->flags & SDVALID)) {
362 bp->b_error = EIO;
363 goto bad;
364 }
365
366 /* "soft" write protect check */
367 if ((sd->flags & SDWRITEPROT) && (bp->b_flags & B_READ) == 0) {
368 bp->b_error = EROFS;
369 goto bad;
370 }
371
372 /* If it's a null transfer, return immediately */
373 if (bp->b_bcount == 0)
374 goto done;
375
376 /*
377 * Decide which unit and partition we are talking about
378 * only raw is ok if no label
379 */
380 if(PARTITION(bp->b_dev) != RAW_PART) {
381 if (!(sd->flags & SDHAVELABEL)) {
382 bp->b_error = EIO;
383 goto bad;
384 }
385
386 /*
387 * do bounds checking, adjust transfer. if error, process.
388 * if end of partition, just return
389 */
390 if (bounds_check_with_label(bp, &sd->disklabel, sd->wlabel) <= 0)
391 goto done;
392 /* otherwise, process transfer request */
393 }
394
395 opri = SPLSD();
396 dp = &(sd_data[unit]->sdbuf);
397
398 /* Place it in the queue of disk activities for this disk */
399 disksort(dp, bp);
400
401 /*
402 * Tell the device to get going on the transfer if it's
403 * not doing anything, otherwise just wait for completion
404 */
405 sdstart(unit);
406
407 splx(opri);
408 return;
409 bad:
410 bp->b_flags |= B_ERROR;
411 done:
412 /* Correctly set the buf to indicate a completed xfer */
413 bp->b_resid = bp->b_bcount;
414 biodone(bp);
415 return;
416 }
417
418 /*
419 * sdstart looks to see if there is a buf waiting for the device
420 * and that the device is not already busy. If both are true,
421 * It deques the buf and creates a scsi command to perform the
422 * transfer in the buf. The transfer request will call sd_done
423 * on completion, which will in turn call this routine again
424 * so that the next queued transfer is performed.
425 * The bufs are queued by the strategy routine (sdstrategy)
426 * This routine is also called after other non-queued requests
427 * have been made of the scsi driver, to ensure that the queue
428 * continues to be drained.
429 * must be called at the correct (highish) spl level
430 * sdstart() is called at SPLSD from sdstrategy and sd_done
431 */
432 void
433 sdstart(int unit)
434 {
435 register struct buf *bp = 0, *dp;
436 struct sd_data *sd = sd_data[unit];
437 struct scsi_rw_big cmd;
438 struct scsi_xfer *xs;
439 struct partition *p;
440 int drivecount, blkno, nblk;
441
442 if(scsi_debug & PRINTROUTINES)
443 printf("sdstart%d ", unit);
444
445 sd = sd_data[unit];
446 if(!sd)
447 return;
448
449 /*
450 * See if there is a buf to do and we are not already
451 * doing one
452 */
453 if(!sd->freexfer)
454 return; /* none for us, unit already underway */
455
456 if(sd->blockwait) /* there is one, but a special waits */
457 return; /* give the special that's waiting a chance to run */
458
459
460 dp = &(sd_data[unit]->sdbuf);
461 if ((bp = dp->b_actf) != NULL) /* yes, an assign */
462 dp->b_actf = bp->av_forw;
463 else
464 return;
465
466 xs=sd_get_xs(unit, 0); /* ok we can grab it */
467 xs->flags = INUSE; /* Now ours */
468
469 /*
470 * If the device has become invalid, abort all the reads
471 * and writes until all files have been closed and re-openned
472 */
473 if( !(sd->flags & SDVALID) ) {
474 xs->error = XS_DRIVER_STUFFUP;
475 sd_done(unit,xs); /* clean up (calls sdstart) */
476 return ;
477 }
478
479 /*
480 * We have a buf, now we should move the data into
481 * a scsi_xfer definition and try start it
482 * First, translate the block to absolute
483 */
484 p = sd->disklabel.d_partitions + PARTITION(bp->b_dev);
485 blkno = bp->b_blkno + p->p_offset;
486 nblk = (bp->b_bcount + 511) >> 9;
487
488 /* Fill out the scsi command */
489 bzero(&cmd, sizeof(cmd));
490 cmd.op_code = (bp->b_flags & B_READ) ? READ_BIG : WRITE_BIG;
491 cmd.addr_3 = (blkno & 0xff000000) >> 24;
492 cmd.addr_2 = (blkno & 0xff0000) >> 16;
493 cmd.addr_1 = (blkno & 0xff00) >> 8;
494 cmd.addr_0 = blkno & 0xff;
495 cmd.length2 = (nblk & 0xff00) >> 8;
496 cmd.length1 = (nblk & 0xff);
497
498 /*
499 * Fill out the scsi_xfer structure
500 * Note: we cannot sleep as we may be an interrupt
501 */
502 xs->flags |= SCSI_NOSLEEP;
503 xs->adapter = sd->ctlr;
504 xs->targ = sd->targ;
505 xs->lu = sd->lu;
506 xs->retries = SD_RETRIES;
507 xs->timeout = 10000; /* 10000 millisecs for a disk !*/
508 xs->cmd = (struct scsi_generic *)&cmd;
509 xs->cmdlen = sizeof(cmd);
510 xs->resid = bp->b_bcount;
511 xs->when_done = sd_done;
512 xs->done_arg = unit;
513 xs->done_arg2 = (int)xs;
514 xs->error = XS_NOERROR;
515 xs->bp = bp;
516 xs->data = (u_char *)bp->b_un.b_addr;
517 xs->datalen = bp->b_bcount;
518
519 /* Pass all this info to the scsi driver */
520 if ( (*(sd->sc_sw->scsi_cmd))(xs) != SUCCESSFULLY_QUEUED) {
521 printf("sd%d: oops not queued",unit);
522 xs->error = XS_DRIVER_STUFFUP;
523 sd_done(unit, xs); /* clean up (calls sdstart) */
524 }
525 sdqueues++;
526 }
527
528 /*
529 * This routine is called by the scsi interrupt when
530 * the transfer is complete.
531 */
532 int
533 sd_done(int unit, struct scsi_xfer *xs)
534 {
535 struct buf *bp;
536 int retval, retries = 0;
537
538 if(scsi_debug & PRINTROUTINES)
539 printf("sd_done%d ",unit);
540 if( !(xs->flags & INUSE))
541 panic("scsi_xfer not in use!");
542 if(bp = xs->bp) {
543 switch(xs->error) {
544 case XS_NOERROR:
545 bp->b_error = 0;
546 bp->b_resid = 0;
547 break;
548 case XS_SENSE:
549 retval = (sd_interpret_sense(unit,xs));
550 if(retval) {
551 bp->b_flags |= B_ERROR;
552 bp->b_error = retval;
553 }
554 break;
555 case XS_TIMEOUT:
556 printf("sd%d timeout\n",unit);
557 case XS_BUSY: /* should retry -- how? */
558 /*
559 * SHOULD put buf back at head of queue
560 * and decrement retry count in (*xs)
561 * HOWEVER, this should work as a kludge
562 */
563 if(xs->retries--) {
564 xs->error = XS_NOERROR;
565 xs->flags &= ~ITSDONE;
566 if( (*(sd_data[unit]->sc_sw->scsi_cmd))(xs)
567 == SUCCESSFULLY_QUEUED) {
568 /* don't wake the job, ok? */
569 return;
570 }
571 xs->flags |= ITSDONE;
572 } /* fall through */
573
574 case XS_DRIVER_STUFFUP:
575 bp->b_flags |= B_ERROR;
576 bp->b_error = EIO;
577 break;
578 default:
579 printf("sd%d: unknown error category from scsi driver\n", unit);
580 }
581 biodone(bp);
582 sd_free_xs(unit, xs, 0);
583 sdstart(unit); /* If there's anything waiting.. do it */
584 } else
585 wakeup(xs);
586 }
587
588 /*
589 * Perform special action on behalf of the user
590 * Knows about the internals of this device
591 */
592 int
593 sdioctl(dev_t dev, int cmd, caddr_t addr, int flag)
594 {
595 /* struct sd_cmd_buf *args;*/
596 struct scsi_format_parms *fparms;
597 extern struct proc *curproc;
598 register struct sd_data *sd;
599 unsigned char unit, part;
600 unsigned int opri;
601 int error = 0, x;
602
603 /* Find the device that the user is talking about */
604 unit = UNIT(dev);
605 part = PARTITION(dev);
606 if(scsi_debug & PRINTROUTINES)
607 printf("sdioctl%d ",unit);
608
609 /* If the device is not valid.. abandon ship */
610 if(unit > NSD)
611 return EIO;
612 sd = sd_data[unit];
613 if(sd==NULL)
614 return EIO;
615
616 if(!(sd->flags & SDVALID))
617 return EIO;
618
619 switch(cmd) {
620 case DIOCWFORMAT:
621 if( suser(curproc->p_ucred, &curproc->p_acflag))
622 return EPERM;
623
624 x = splbio();
625 if(sd->formatting)
626 return EBUSY;
627 sd->formatting = 1;
628 (void)splx(x);
629
630 fparms = (struct scsi_format_parms *)malloc(sizeof *fparms,
631 M_TEMP, M_NOWAIT);
632 if(!fparms) {
633 error = EAGAIN;
634 goto unlock;
635 }
636
637 if(copyin(&addr, fparms, sizeof fparms)!=0) {
638 free(fparms, M_TEMP);
639 error = EFAULT;
640 goto unlock;
641 }
642 error = sd_format(unit, fparms, 0, 0);
643 if(!error && copyout(&addr, fparms, sizeof fparms) )
644 error = EFAULT;
645 free(fparms, M_TEMP);
646 unlock:
647 x = splbio();
648 sd->formatting = 0;
649 (void)splx(x);
650
651 break;
652 case DIOCRFORMAT:
653 error = EINVAL;
654 break;
655 case DIOCSBAD:
656 error = EINVAL;
657 break;
658 case DIOCGDINFO:
659 *(struct disklabel *)addr = sd->disklabel;
660 break;
661 case DIOCGPART:
662 ((struct partinfo *)addr)->disklab = &sd->disklabel;
663 ((struct partinfo *)addr)->part =
664 &sd->disklabel.d_partitions[PARTITION(dev)];
665 break;
666 case DIOCSDINFO:
667 if ((flag & FWRITE) == 0)
668 error = EBADF;
669 else {
670 error = setdisklabel(&sd->disklabel, (struct disklabel *)addr,
671 /*(sd->flags & DKFL_BSDLABEL) ? sd->openparts : */0,
672 sd->dosparts);
673 }
674 if (error == 0)
675 sd->flags |= SDHAVELABEL;
676 break;
677 case DIOCWLABEL:
678 sd->flags &= ~SDWRITEPROT;
679 if ((flag & FWRITE) == 0)
680 error = EBADF;
681 else
682 sd->wlabel = *(int *)addr;
683 break;
684 case DIOCWDINFO:
685 sd->flags &= ~SDWRITEPROT;
686 if ((flag & FWRITE) == 0)
687 error = EBADF;
688 else {
689 if ((error = setdisklabel(&sd->disklabel,
690 (struct disklabel *)addr,
691 /*(sd->flags & SDHAVELABEL) ? sd->openparts :*/0,
692 sd->dosparts)) == 0) {
693 int wlab;
694
695 sd->flags |= SDHAVELABEL; /* ok write will succeed */
696
697 /* simulate opening partition 0 so write succeeds */
698 sd->openparts |= (1 << 0); /* XXX */
699 wlab = sd->wlabel;
700 sd->wlabel = 1;
701 error = writedisklabel(dev, sdstrategy,
702 &sd->disklabel, sd->dosparts);
703 sd->wlabel = wlab;
704 }
705 }
706 break;
707 default:
708 error = ENOTTY;
709 break;
710 }
711 return error;
712 }
713
714
715 /*
716 * Load the label information on the named device
717 */
718 int
719 sdgetdisklabel(u_char unit)
720 {
721 struct dos_partition *dos_partition_p;
722 struct sd_data *sd = sd_data[unit];
723 /*unsigned int n, m;*/
724 char *errstring;
725
726 /* If the inflo is already loaded, use it */
727 if(sd->flags & SDHAVELABEL)
728 return ESUCCESS;
729
730 bzero(&sd->disklabel, sizeof(struct disklabel));
731 /*
732 * make partition 3 the whole disk in case of failure
733 * then get pdinfo
734 */
735 sd->disklabel.d_partitions[0].p_offset = 0;
736 sd->disklabel.d_partitions[0].p_size = sd->params.disksize;
737 sd->disklabel.d_partitions[RAW_PART].p_offset = 0;
738 sd->disklabel.d_partitions[RAW_PART].p_size = sd->params.disksize;
739 sd->disklabel.d_npartitions = MAXPARTITIONS;
740 sd->disklabel.d_secsize = 512; /* as long as it's not 0 */
741 sd->disklabel.d_ntracks = sd->params.heads;
742 sd->disklabel.d_nsectors = sd->params.sectors;
743 sd->disklabel.d_ncylinders = sd->params.cyls;
744 sd->disklabel.d_secpercyl = sd->params.heads * sd->params.sectors;
745 if (sd->disklabel.d_secpercyl == 0) {
746 /* as long as it's not 0 because readdisklabel() divides by it */
747 sd->disklabel.d_secpercyl = 100;
748 }
749
750 /* all the generic disklabel extraction routine */
751 if(errstring = readdisklabel(makedev(0 ,(unit<<UNITSHIFT )+3),
752 sdstrategy, &sd->disklabel, sd->dosparts, 0, 0)) {
753 printf("sd%d: %s\n",unit, errstring);
754 return ENXIO;
755 }
756
757 /* leave partition 2 "open" for raw I/O */
758
759 sd->flags |= SDHAVELABEL; /* WE HAVE IT ALL NOW */
760 return ESUCCESS;
761 }
762
763 /*
764 * Find out from the device what it's capacity is
765 */
766 int
767 sd_size(int unit, int flags)
768 {
769 struct scsi_read_cap_data rdcap;
770 struct scsi_read_capacity scsi_cmd;
771 int size;
772
773 /*
774 * make up a scsi command and ask the scsi driver to do
775 * it for you.
776 */
777 bzero(&scsi_cmd, sizeof(scsi_cmd));
778 scsi_cmd.op_code = READ_CAPACITY;
779
780 /*
781 * If the command works, interpret the result as a 4 byte
782 * number of blocks
783 */
784 if (sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
785 sizeof(scsi_cmd), (u_char *)&rdcap, sizeof(rdcap), 2000, flags) != 0) {
786 printf("could not get size of unit %d\n", unit);
787 return 0;
788 } else {
789 size = rdcap.addr_0 + 1 ;
790 size += rdcap.addr_1 << 8;
791 size += rdcap.addr_2 << 16;
792 size += rdcap.addr_3 << 24;
793 }
794 return size;
795 }
796
797 /*
798 * Get scsi driver to send a "are you ready?" command
799 */
800 int
801 sd_test_unit_ready(int unit, int flags)
802 {
803 struct scsi_test_unit_ready scsi_cmd;
804
805 bzero(&scsi_cmd, sizeof(scsi_cmd));
806 scsi_cmd.op_code = TEST_UNIT_READY;
807
808 return sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
809 sizeof(scsi_cmd), 0, 0, 100000, flags);
810 }
811
812 /*
813 * format disk
814 */
815 int
816 sd_format(int unit, struct scsi_format_parms *f, int flags, int type)
817 {
818 struct scsi_prevent scsi_cmd;
819
820 bzero(&scsi_cmd, sizeof(scsi_cmd));
821 scsi_cmd.op_code = FORMAT_DISK;
822 scsi_cmd.prevent= type;
823 return sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
824 sizeof(scsi_cmd), (u_char *)f, sizeof *f, 500000000, flags);
825 }
826
827 /*
828 * Prevent or allow the user to remove the tape
829 */
830 int
831 sd_prevent(int unit, int type, int flags)
832 {
833 struct scsi_prevent scsi_cmd;
834
835 bzero(&scsi_cmd, sizeof(scsi_cmd));
836 scsi_cmd.op_code = PREVENT_ALLOW;
837 scsi_cmd.prevent=type;
838 return sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
839 sizeof(scsi_cmd), 0, 0, 5000, flags);
840 }
841
842 /*
843 * Get scsi driver to send a "start up" command
844 */
845 int
846 sd_start_unit(int unit, int flags)
847 {
848 struct scsi_start_stop scsi_cmd;
849
850 bzero(&scsi_cmd, sizeof(scsi_cmd));
851 scsi_cmd.op_code = START_STOP;
852 scsi_cmd.start = 1;
853
854 return sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
855 sizeof(scsi_cmd), 0, 0, 2000, flags);
856 }
857
858 /*
859 * Tell the device to map out a defective block
860 */
861 int
862 sd_reassign_blocks(int unit, int block)
863 {
864 struct scsi_reassign_blocks_data rbdata;
865 struct scsi_reassign_blocks scsi_cmd;
866
867 bzero(&scsi_cmd, sizeof(scsi_cmd));
868 bzero(&rbdata, sizeof(rbdata));
869 scsi_cmd.op_code = REASSIGN_BLOCKS;
870
871 rbdata.length_msb = 0;
872 rbdata.length_lsb = sizeof(rbdata.defect_descriptor[0]);
873 rbdata.defect_descriptor[0].dlbaddr_3 = ((block >> 24) & 0xff);
874 rbdata.defect_descriptor[0].dlbaddr_2 = ((block >> 16) & 0xff);
875 rbdata.defect_descriptor[0].dlbaddr_1 = ((block >> 8) & 0xff);
876 rbdata.defect_descriptor[0].dlbaddr_0 = ((block ) & 0xff);
877
878 return sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
879 sizeof(scsi_cmd), (u_char *)&rbdata, sizeof(rbdata), 5000, 0);
880 }
881
882 #define b2tol(a) (((unsigned)(a##_1) << 8) + (unsigned)a##_0 )
883
884 /*
885 * Get the scsi driver to send a full inquiry to the
886 * device and use the results to fill out the disk
887 * parameter structure.
888 */
889 int
890 sd_get_parms(int unit, int flags)
891 {
892 struct sd_data *sd = sd_data[unit];
893 struct disk_parms *disk_parms = &sd->params;
894 struct scsi_mode_sense scsi_cmd;
895 struct scsi_mode_sense_data {
896 struct scsi_mode_header header;
897 struct blk_desc blk_desc;
898 union disk_pages pages;
899 } scsi_sense;
900 int sectors;
901
902 /* First check if we have it all loaded */
903 if(!sd)
904 return 0;
905 if(sd->flags & SDVALID)
906 return 0;
907
908 /* First do a mode sense page 3 */
909 if (sd_debug) {
910 bzero(&scsi_cmd, sizeof(scsi_cmd));
911 scsi_cmd.op_code = MODE_SENSE;
912 scsi_cmd.page_code = 3;
913 scsi_cmd.length = 0x24;
914
915 /*
916 * do the command, but we don't need the results
917 * just print them for our interest's sake
918 */
919 if (sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
920 sizeof(scsi_cmd), (u_char *)&scsi_sense, sizeof(scsi_sense),
921 2000, flags) != 0) {
922 printf("could not mode sense (3) for unit %d\n", unit);
923 return ENXIO;
924 }
925 printf("unit %d: %d trk/zn, %d altsec/zn, %d alttrk/zn, %d alttrk/lun\n",
926 unit, b2tol(scsi_sense.pages.disk_format.trk_z),
927 b2tol(scsi_sense.pages.disk_format.alt_sec),
928 b2tol(scsi_sense.pages.disk_format.alt_trk_z),
929 b2tol(scsi_sense.pages.disk_format.alt_trk_v));
930 printf(" %d sec/trk, %d byte/sec, %d interleave, %d %d bytes/log_blk\n",
931 b2tol(scsi_sense.pages.disk_format.ph_sec_t),
932 b2tol(scsi_sense.pages.disk_format.bytes_s),
933 b2tol(scsi_sense.pages.disk_format.interleave),
934 sd_size(unit, flags),
935 _3btol((u_char *)scsi_sense.blk_desc.blklen));
936 }
937
938
939 /* do a "mode sense page 4" */
940 bzero(&scsi_cmd, sizeof(scsi_cmd));
941 scsi_cmd.op_code = MODE_SENSE;
942 scsi_cmd.page_code = 4;
943 scsi_cmd.length = 0x20;
944
945 /*
946 * If the command worked, use the results to fill out
947 * the parameter structure
948 */
949 if (sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
950 sizeof(scsi_cmd), (u_char *)&scsi_sense, sizeof(scsi_sense),
951 2000, flags) != 0) {
952 printf("could not mode sense (4) for unit %d\n", unit);
953 printf(" using ficticious geometry\n");
954 sectors = sd_size(unit, flags);
955 disk_parms->heads = 64;
956 disk_parms->sectors = 32;
957 disk_parms->cyls = sectors/(64 * 32);
958 disk_parms->secsiz = SECSIZE;
959 } else {
960 if (sd_debug) {
961 printf(" %d cyl, %d head, %d precomp, %d redwrite, %d land\n",
962 _3btol((u_char *)&scsi_sense.pages.rigid_geometry.ncyl_2),
963 scsi_sense.pages.rigid_geometry.nheads,
964 b2tol(scsi_sense.pages.rigid_geometry.st_cyl_wp),
965 b2tol(scsi_sense.pages.rigid_geometry.st_cyl_rwc),
966 b2tol(scsi_sense.pages.rigid_geometry.land_zone));
967 }
968
969 /*
970 * KLUDGE!!(for zone recorded disks)
971 * give a number of sectors so that sec * trks * cyls
972 * is <= disk_size
973 */
974 disk_parms->heads = scsi_sense.pages.rigid_geometry.nheads;
975 disk_parms->cyls =
976 _3btol((u_char *)&scsi_sense.pages.rigid_geometry.ncyl_2);
977 disk_parms->secsiz = _3btol((u_char *)&scsi_sense.blk_desc.blklen);
978
979 sectors = sd_size(unit, flags);
980 sectors /= disk_parms->cyls;
981 sectors /= disk_parms->heads;
982 disk_parms->sectors = sectors; /* dubious on SCSI*/
983 }
984
985 disk_parms->disksize = disk_parms->sectors * disk_parms->heads *
986 disk_parms->cyls;
987 sd->flags |= SDVALID;
988 return 0;
989 }
990
991 /*
992 * close the device.. only called if we are the LAST
993 * occurence of an open device
994 */
995 int
996 sdclose(dev_t dev)
997 {
998 struct sd_data *sd;
999 unsigned char unit, part;
1000 unsigned int old_priority;
1001
1002 unit = UNIT(dev);
1003 part = PARTITION(dev);
1004 sd = sd_data[unit];
1005 sd->partflags[part] &= ~SDOPEN;
1006 sd->openparts &= ~(1 << part);
1007 if(sd->openparts == 0)
1008 sd_prevent(unit, PR_ALLOW, SCSI_SILENT|SCSI_ERR_OK);
1009 return 0;
1010 }
1011
1012 /*
1013 * ask the scsi driver to perform a command for us.
1014 * Call it through the switch table, and tell it which
1015 * sub-unit we want, and what target and lu we wish to
1016 * talk to. Also tell it where to find the command
1017 * how long int is.
1018 * Also tell it where to read/write the data, and how
1019 * long the data is supposed to be
1020 */
1021 int
1022 sd_scsi_cmd(int unit, struct scsi_generic *scsi_cmd, int cmdlen,
1023 u_char *data_addr, int datalen, int timeout, int flags)
1024 {
1025 struct sd_data *sd = sd_data[unit];
1026 struct scsi_xfer *xs;
1027 int retval, s;
1028
1029 if(scsi_debug & PRINTROUTINES)
1030 printf("\nsd_scsi_cmd%d ",unit);
1031 if(!sd->sc_sw) {
1032 printf("sd%d: not set up\n",unit);
1033 return EINVAL;
1034 }
1035
1036 xs = sd_get_xs(unit,flags); /* should wait unless booting */
1037 if(!xs) {
1038 printf("sd_scsi_cmd%d: controller busy"
1039 " (this should never happen)\n",unit);
1040 return EBUSY;
1041 }
1042
1043 xs->flags |= INUSE;
1044 xs->flags |= flags;
1045 xs->adapter = sd->ctlr;
1046 xs->targ = sd->targ;
1047 xs->lu = sd->lu;
1048 xs->retries = SD_RETRIES;
1049 xs->timeout = timeout;
1050 xs->cmd = scsi_cmd;
1051 xs->cmdlen = cmdlen;
1052 xs->data = data_addr;
1053 xs->datalen = datalen;
1054 xs->resid = datalen;
1055 xs->when_done = (flags & SCSI_NOMASK) ?(int (*)())0 : sd_done;
1056 xs->done_arg = unit;
1057 xs->done_arg2 = (int)xs;
1058
1059 retry:
1060 xs->error = XS_NOERROR;
1061 xs->bp = 0;
1062 retval = (*(sd->sc_sw->scsi_cmd))(xs);
1063 switch(retval) {
1064 case SUCCESSFULLY_QUEUED:
1065 s = splbio();
1066 while(!(xs->flags & ITSDONE))
1067 sleep(xs,PRIBIO+1);
1068 splx(s);
1069 case HAD_ERROR:
1070 /*printf("err = %d ", xs->error);*/
1071 switch(xs->error) {
1072 case XS_NOERROR:
1073 retval = ESUCCESS;
1074 break;
1075 case XS_SENSE:
1076 retval = sd_interpret_sense(unit, xs);
1077 break;
1078 case XS_DRIVER_STUFFUP:
1079 retval = EIO;
1080 break;
1081 case XS_TIMEOUT:
1082 case XS_BUSY:
1083 if(xs->retries-- ) {
1084 xs->flags &= ~ITSDONE;
1085 goto retry;
1086 }
1087 retval = EIO;
1088 break;
1089 default:
1090 retval = EIO;
1091 printf("sd%d: unknown error category from scsi driver\n", unit);
1092 }
1093 break;
1094 case COMPLETE:
1095 retval = ESUCCESS;
1096 break;
1097 case TRY_AGAIN_LATER:
1098 if(xs->retries-- ) {
1099 xs->flags &= ~ITSDONE;
1100 goto retry;
1101 }
1102 retval = EIO;
1103 break;
1104 default:
1105 retval = EIO;
1106 }
1107
1108 sd_free_xs(unit, xs, flags);
1109 sdstart(unit); /* check if anything is waiting fr the xs */
1110 return retval;
1111 }
1112
1113 /*
1114 * Look at the returned sense and act on the error and detirmine
1115 * The unix error number to pass back... (0 = report no error)
1116 */
1117 int
1118 sd_interpret_sense(int unit, struct scsi_xfer *xs)
1119 {
1120 struct sd_data *sd = sd_data[unit];
1121 struct scsi_sense_data *sense;
1122 int key, silent;
1123
1124 /* If the flags say errs are ok, then always return ok. */
1125 if (xs->flags & SCSI_ERR_OK)
1126 return ESUCCESS;
1127 silent = (xs->flags & SCSI_SILENT);
1128
1129 sense = &(xs->sense);
1130 switch(sense->error_class) {
1131 case 7:
1132 key = sense->ext.extended.sense_key;
1133 switch(key) {
1134 case 0x0:
1135 return ESUCCESS;
1136 case 0x1:
1137 if(!silent) {
1138 printf("sd%d: soft error(corrected) ", unit);
1139 if(sense->valid) {
1140 printf("block no. %d (decimal)",
1141 (sense->ext.extended.info[0] <<24),
1142 (sense->ext.extended.info[1] <<16),
1143 (sense->ext.extended.info[2] <<8),
1144 (sense->ext.extended.info[3] ));
1145 }
1146 printf("\n");
1147 }
1148 return ESUCCESS;
1149 case 0x2:
1150 if(!silent)
1151 printf("sd%d: not ready\n ", unit);
1152 return ENODEV;
1153 case 0x3:
1154 if(!silent) {
1155 printf("sd%d: medium error ", unit);
1156 if(sense->valid) {
1157 printf("block no. %d (decimal)",
1158 (sense->ext.extended.info[0] <<24),
1159 (sense->ext.extended.info[1] <<16),
1160 (sense->ext.extended.info[2] <<8),
1161 (sense->ext.extended.info[3] ));
1162 }
1163 printf("\n");
1164 }
1165 return EIO;
1166 case 0x4:
1167 if(!silent)
1168 printf("sd%d: non-media hardware failure\n ", unit);
1169 return EIO;
1170 case 0x5:
1171 if(!silent)
1172 printf("sd%d: illegal request\n ", unit);
1173 return EINVAL;
1174 case 0x6:
1175 /*
1176 * If we are not open, then this is not an error
1177 * as we don't have state yet. Either way, make
1178 * sure that we don't have any residual state
1179 */
1180 if(!silent)
1181 printf("sd%d: Unit attention.\n ", unit);
1182 sd->flags &= ~(SDVALID | SDHAVELABEL);
1183 if (sd->openparts)
1184 return EIO;
1185 return ESUCCESS; /* not an error if nothing's open */
1186 case 0x7:
1187 if(!silent) {
1188 printf("sd%d: attempted protection violation ", unit);
1189 if(sense->valid) {
1190 printf("block no. %d (decimal)\n",
1191 (sense->ext.extended.info[0] <<24),
1192 (sense->ext.extended.info[1] <<16),
1193 (sense->ext.extended.info[2] <<8),
1194 (sense->ext.extended.info[3] ));
1195 }
1196 printf("\n");
1197 }
1198 return EACCES;
1199 case 0x8:
1200 if(!silent) {
1201 printf("sd%d: block wrong state (worm)\n ", unit);
1202 if(sense->valid) {
1203 printf("block no. %d (decimal)\n",
1204 (sense->ext.extended.info[0] <<24),
1205 (sense->ext.extended.info[1] <<16),
1206 (sense->ext.extended.info[2] <<8),
1207 (sense->ext.extended.info[3] ));
1208 }
1209 printf("\n");
1210 }
1211 return EIO;
1212 case 0x9:
1213 if(!silent)
1214 printf("sd%d: vendor unique\n", unit);
1215 return EIO;
1216 case 0xa:
1217 if(!silent)
1218 printf("sd%d: copy aborted\n ", unit);
1219 return EIO;
1220 case 0xb:
1221 if(!silent)
1222 printf("sd%d: command aborted\n ", unit);
1223 return EIO;
1224 case 0xc:
1225 if(!silent) {
1226 printf("sd%d: search returned\n ", unit);
1227 if(sense->valid) {
1228 printf("block no. %d (decimal)\n",
1229 (sense->ext.extended.info[0] <<24),
1230 (sense->ext.extended.info[1] <<16),
1231 (sense->ext.extended.info[2] <<8),
1232 (sense->ext.extended.info[3] ));
1233 }
1234 printf("\n");
1235 }
1236 return ESUCCESS;
1237 case 0xd:
1238 if(!silent)
1239 printf("sd%d: volume overflow\n ", unit);
1240 return ENOSPC;
1241 case 0xe:
1242 if(!silent) {
1243 printf("sd%d: verify miscompare\n ", unit);
1244 if(sense->valid) {
1245 printf("block no. %d (decimal)\n",
1246 (sense->ext.extended.info[0] <<24),
1247 (sense->ext.extended.info[1] <<16),
1248 (sense->ext.extended.info[2] <<8),
1249 (sense->ext.extended.info[3] ));
1250 }
1251 printf("\n");
1252 }
1253 return EIO;
1254 case 0xf:
1255 if(!silent)
1256 printf("sd%d: unknown error key\n ", unit);
1257 return EIO;
1258 }
1259 break;
1260 case 0:
1261 case 1:
1262 case 2:
1263 case 3:
1264 case 4:
1265 case 5:
1266 case 6:
1267 if(!silent)printf("sd%d: error class %d code %d\n", unit,
1268 sense->error_class, sense->error_code);
1269 if(sense->valid)
1270 if(!silent)
1271 printf("block no. %d (decimal)\n",
1272 (sense->ext.unextended.blockhi <<16),
1273 + (sense->ext.unextended.blockmed <<8),
1274 + (sense->ext.unextended.blocklow ));
1275 return EIO;
1276 }
1277 return 0; /* XXX? */
1278 }
1279
1280 int
1281 sdsize(dev_t dev)
1282 {
1283 int unit = UNIT(dev), part = PARTITION(dev), val;
1284 struct sd_data *sd;
1285
1286 if (unit >= NSD)
1287 return -1;
1288 if(!sd_data[unit])
1289 return -1;
1290
1291 sd = sd_data[unit];
1292 if((sd->flags & SDINIT) == 0)
1293 return -1;
1294
1295 if( sd==0 || (sd->flags & SDHAVELABEL)==0 )
1296 val = sdopen(MAKESDDEV(major(dev), unit, RAW_PART));
1297 if ( val!=0 || sd->flags & SDWRITEPROT)
1298 return -1;
1299
1300 return (int)sd->disklabel.d_partitions[part].p_size;
1301 }
1302
1303 sddump()
1304 {
1305 printf("sddump() -- not implemented\n");
1306 return -1;
1307 }
1308