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