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