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