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.18 1993/08/01 19:26:21 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 #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[i]==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 tsleep((caddr_t)&sd->freexfer, PRIBIO+1, "sd_get_xs",0); 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 /* Reject non block-aligned transfers */ 371 if (bp->b_bcount % SECSIZE) { 372 bp->b_error = EINVAL; 373 goto bad; 374 } 375 376 sdminphys(bp); 377 378 /* If the device has been made invalid, error out */ 379 if(!(sd->flags & SDVALID)) { 380 bp->b_error = EIO; 381 goto bad; 382 } 383 384 /* "soft" write protect check */ 385 if ((sd->flags & SDWRITEPROT) && (bp->b_flags & B_READ) == 0) { 386 bp->b_error = EROFS; 387 goto bad; 388 } 389 390 /* If it's a null transfer, return immediately */ 391 if (bp->b_bcount == 0) 392 goto done; 393 394 /* 395 * Decide which unit and partition we are talking about 396 * only raw is ok if no label 397 */ 398 if(PARTITION(bp->b_dev) != RAW_PART) { 399 if (!(sd->flags & SDHAVELABEL)) { 400 bp->b_error = EIO; 401 goto bad; 402 } 403 404 /* 405 * do bounds checking, adjust transfer. if error, process. 406 * if end of partition, just return 407 */ 408 if (bounds_check_with_label(bp, &sd->disklabel, sd->wlabel) <= 0) 409 goto done; 410 /* otherwise, process transfer request */ 411 } 412 413 opri = SPLSD(); 414 dp = &(sd_data[unit]->sdbuf); 415 416 /* Place it in the queue of disk activities for this disk */ 417 disksort(dp, bp); 418 419 /* 420 * Tell the device to get going on the transfer if it's 421 * not doing anything, otherwise just wait for completion 422 */ 423 sdstart(unit); 424 425 splx(opri); 426 return; 427 bad: 428 bp->b_flags |= B_ERROR; 429 done: 430 /* Correctly set the buf to indicate a completed xfer */ 431 bp->b_resid = bp->b_bcount; 432 biodone(bp); 433 return; 434 } 435 436 /* 437 * sdstart looks to see if there is a buf waiting for the device 438 * and that the device is not already busy. If both are true, 439 * It deques the buf and creates a scsi command to perform the 440 * transfer in the buf. The transfer request will call sd_done 441 * on completion, which will in turn call this routine again 442 * so that the next queued transfer is performed. 443 * The bufs are queued by the strategy routine (sdstrategy) 444 * This routine is also called after other non-queued requests 445 * have been made of the scsi driver, to ensure that the queue 446 * continues to be drained. 447 * must be called at the correct (highish) spl level 448 * sdstart() is called at SPLSD from sdstrategy and sd_done 449 */ 450 void 451 sdstart(int unit) 452 { 453 register struct buf *bp = 0, *dp; 454 struct sd_data *sd = sd_data[unit]; 455 struct scsi_rw_big cmd; 456 struct scsi_xfer *xs; 457 struct partition *p; 458 int drivecount, blkno, nblk; 459 460 if(scsi_debug & PRINTROUTINES) 461 printf("sdstart%d ", unit); 462 463 sd = sd_data[unit]; 464 if(!sd) 465 return; 466 467 /* 468 * See if there is a buf to do and we are not already 469 * doing one 470 */ 471 if(!sd->freexfer) 472 return; /* none for us, unit already underway */ 473 474 if(sd->blockwait) /* there is one, but a special waits */ 475 return; /* give the special that's waiting a chance to run */ 476 477 478 dp = &(sd_data[unit]->sdbuf); 479 if ((bp = dp->b_actf) != NULL) /* yes, an assign */ 480 dp->b_actf = bp->av_forw; 481 else 482 return; 483 484 xs=sd_get_xs(unit, 0); /* ok we can grab it */ 485 xs->flags = INUSE; /* Now ours */ 486 487 /* 488 * If the device has become invalid, abort all the reads 489 * and writes until all files have been closed and re-openned 490 */ 491 if( !(sd->flags & SDVALID) ) { 492 xs->error = XS_DRIVER_STUFFUP; 493 sd_done(unit,xs); /* clean up (calls sdstart) */ 494 return ; 495 } 496 497 /* 498 * We have a buf, now we should move the data into 499 * a scsi_xfer definition and try start it 500 * First, translate the block to absolute 501 */ 502 p = sd->disklabel.d_partitions + PARTITION(bp->b_dev); 503 blkno = bp->b_blkno + p->p_offset; 504 nblk = (bp->b_bcount + 511) >> 9; 505 506 /* Fill out the scsi command */ 507 bzero(&cmd, sizeof(cmd)); 508 cmd.op_code = (bp->b_flags & B_READ) ? READ_BIG : WRITE_BIG; 509 cmd.addr_3 = (blkno & 0xff000000) >> 24; 510 cmd.addr_2 = (blkno & 0xff0000) >> 16; 511 cmd.addr_1 = (blkno & 0xff00) >> 8; 512 cmd.addr_0 = blkno & 0xff; 513 cmd.length2 = (nblk & 0xff00) >> 8; 514 cmd.length1 = (nblk & 0xff); 515 516 /* 517 * Fill out the scsi_xfer structure 518 * Note: we cannot sleep as we may be an interrupt 519 */ 520 xs->flags |= SCSI_NOSLEEP; 521 xs->adapter = sd->ctlr; 522 xs->targ = sd->targ; 523 xs->lu = sd->lu; 524 xs->retries = SD_RETRIES; 525 xs->timeout = 10000; /* 10000 millisecs for a disk !*/ 526 xs->cmd = (struct scsi_generic *)&cmd; 527 xs->cmdlen = sizeof(cmd); 528 xs->resid = bp->b_bcount; 529 xs->when_done = sd_done; 530 xs->done_arg = unit; 531 xs->done_arg2 = (int)xs; 532 xs->error = XS_NOERROR; 533 xs->bp = bp; 534 xs->data = (u_char *)bp->b_un.b_addr; 535 xs->datalen = bp->b_bcount; 536 537 /* Pass all this info to the scsi driver */ 538 if ( (*(sd->sc_sw->scsi_cmd))(xs) != SUCCESSFULLY_QUEUED) { 539 printf("sd%d: oops not queued",unit); 540 xs->error = XS_DRIVER_STUFFUP; 541 sd_done(unit, xs); /* clean up (calls sdstart) */ 542 } 543 sdqueues++; 544 } 545 546 /* 547 * This routine is called by the scsi interrupt when 548 * the transfer is complete. 549 */ 550 int 551 sd_done(int unit, struct scsi_xfer *xs) 552 { 553 struct buf *bp; 554 int retval, retries = 0; 555 556 if(scsi_debug & PRINTROUTINES) 557 printf("sd_done%d ",unit); 558 if( !(xs->flags & INUSE)) 559 panic("scsi_xfer not in use!"); 560 if(bp = xs->bp) { 561 switch(xs->error) { 562 case XS_NOERROR: 563 bp->b_error = 0; 564 bp->b_resid = 0; 565 break; 566 case XS_SENSE: 567 retval = (sd_interpret_sense(unit,xs)); 568 if(retval) { 569 bp->b_flags |= B_ERROR; 570 bp->b_error = retval; 571 } 572 break; 573 case XS_TIMEOUT: 574 printf("sd%d timeout\n",unit); 575 case XS_BUSY: /* should retry -- how? */ 576 /* 577 * SHOULD put buf back at head of queue 578 * and decrement retry count in (*xs) 579 * HOWEVER, this should work as a kludge 580 */ 581 if(xs->retries--) { 582 xs->error = XS_NOERROR; 583 xs->flags &= ~ITSDONE; 584 if( (*(sd_data[unit]->sc_sw->scsi_cmd))(xs) 585 == SUCCESSFULLY_QUEUED) { 586 /* don't wake the job, ok? */ 587 return; 588 } 589 xs->flags |= ITSDONE; 590 } /* fall through */ 591 592 case XS_DRIVER_STUFFUP: 593 bp->b_flags |= B_ERROR; 594 bp->b_error = EIO; 595 break; 596 default: 597 printf("sd%d: unknown error category from scsi driver\n", unit); 598 } 599 biodone(bp); 600 sd_free_xs(unit, xs, 0); 601 sdstart(unit); /* If there's anything waiting.. do it */ 602 } else 603 wakeup((caddr_t)xs); 604 } 605 606 /* 607 * Perform special action on behalf of the user 608 * Knows about the internals of this device 609 */ 610 int 611 sdioctl(dev_t dev, int cmd, caddr_t addr, int flag) 612 { 613 /* struct sd_cmd_buf *args;*/ 614 struct scsi_format_parms *fparms; 615 struct cpu_disklabel osdep; 616 extern struct proc *curproc; 617 register struct sd_data *sd; 618 unsigned char unit, part; 619 unsigned int opri; 620 int error = 0, x; 621 622 /* Find the device that the user is talking about */ 623 unit = UNIT(dev); 624 part = PARTITION(dev); 625 if(scsi_debug & PRINTROUTINES) 626 printf("sdioctl%d ",unit); 627 628 /* If the device is not valid.. abandon ship */ 629 if(unit > NSD) 630 return EIO; 631 sd = sd_data[unit]; 632 if(sd==NULL) 633 return EIO; 634 635 if(!(sd->flags & SDVALID)) 636 return EIO; 637 638 switch(cmd) { 639 case DIOCWFORMAT: 640 if( suser(curproc->p_ucred, &curproc->p_acflag)) 641 return EPERM; 642 643 x = splbio(); 644 if(sd->formatting) 645 return EBUSY; 646 sd->formatting = 1; 647 (void)splx(x); 648 649 fparms = (struct scsi_format_parms *)malloc(sizeof *fparms, 650 M_TEMP, M_NOWAIT); 651 if(!fparms) { 652 error = EAGAIN; 653 goto unlock; 654 } 655 656 if(copyin(&addr, fparms, sizeof fparms)!=0) { 657 free(fparms, M_TEMP); 658 error = EFAULT; 659 goto unlock; 660 } 661 error = sd_format(unit, fparms, 0, 0); 662 if(!error && copyout(&addr, fparms, sizeof fparms) ) 663 error = EFAULT; 664 free(fparms, M_TEMP); 665 unlock: 666 x = splbio(); 667 sd->formatting = 0; 668 (void)splx(x); 669 670 break; 671 case DIOCRFORMAT: 672 error = EINVAL; 673 break; 674 case DIOCSBAD: 675 error = EINVAL; 676 break; 677 case DIOCGDINFO: 678 *(struct disklabel *)addr = sd->disklabel; 679 break; 680 case DIOCGPART: 681 ((struct partinfo *)addr)->disklab = &sd->disklabel; 682 ((struct partinfo *)addr)->part = 683 &sd->disklabel.d_partitions[PARTITION(dev)]; 684 break; 685 case DIOCSDINFO: 686 if ((flag & FWRITE) == 0) 687 error = EBADF; 688 else { 689 error = setdisklabel(&sd->disklabel, (struct disklabel *)addr, 690 /*(sd->flags & DKFL_BSDLABEL) ? sd->openparts : */0, 691 &sd->cpudisklabel); 692 } 693 if (error == 0) 694 sd->flags |= SDHAVELABEL; 695 break; 696 case DIOCWLABEL: 697 sd->flags &= ~SDWRITEPROT; 698 if ((flag & FWRITE) == 0) 699 error = EBADF; 700 else 701 sd->wlabel = *(int *)addr; 702 break; 703 case DIOCWDINFO: 704 sd->flags &= ~SDWRITEPROT; 705 if ((flag & FWRITE) == 0) 706 error = EBADF; 707 else { 708 if ((error = setdisklabel(&sd->disklabel, 709 (struct disklabel *)addr, 710 /*(sd->flags & SDHAVELABEL) ? sd->openparts :*/0, 711 &sd->cpudisklabel)) == 0) { 712 int wlab; 713 714 sd->flags |= SDHAVELABEL; /* ok write will succeed */ 715 716 /* simulate opening partition 0 so write succeeds */ 717 sd->openparts |= (1 << 0); /* XXX */ 718 wlab = sd->wlabel; 719 sd->wlabel = 1; 720 error = writedisklabel(dev, sdstrategy, 721 &sd->disklabel, &sd->cpudisklabel); 722 sd->wlabel = wlab; 723 } 724 } 725 break; 726 default: 727 error = ENOTTY; 728 break; 729 } 730 return error; 731 } 732 733 734 /* 735 * Load the label information on the named device 736 */ 737 int 738 sdgetdisklabel(u_char unit) 739 { 740 struct sd_data *sd = sd_data[unit]; 741 /*unsigned int n, m;*/ 742 char *errstring; 743 struct cpu_disklabel osdep; 744 745 /* If the inflo is already loaded, use it */ 746 if(sd->flags & SDHAVELABEL) 747 return ESUCCESS; 748 749 bzero(&sd->disklabel, sizeof(struct disklabel)); 750 /* 751 * make partition 3 the whole disk in case of failure 752 * then get pdinfo 753 */ 754 sd->disklabel.d_partitions[0].p_offset = 0; 755 sd->disklabel.d_partitions[0].p_size = sd->params.disksize; 756 sd->disklabel.d_partitions[RAW_PART].p_offset = 0; 757 sd->disklabel.d_partitions[RAW_PART].p_size = sd->params.disksize; 758 sd->disklabel.d_npartitions = MAXPARTITIONS; 759 sd->disklabel.d_secsize = SECSIZE; /* as long as it's not 0 */ 760 sd->disklabel.d_ntracks = sd->params.heads; 761 sd->disklabel.d_nsectors = sd->params.sectors; 762 sd->disklabel.d_ncylinders = sd->params.cyls; 763 sd->disklabel.d_secpercyl = sd->params.heads * sd->params.sectors; 764 if (sd->disklabel.d_secpercyl == 0) { 765 /* as long as it's not 0 because readdisklabel() divides by it */ 766 sd->disklabel.d_secpercyl = 100; 767 } 768 769 /* all the generic disklabel extraction routine */ 770 if(errstring = readdisklabel(makedev(0 ,(unit<<UNITSHIFT )+3), 771 sdstrategy, &sd->disklabel, &sd->cpudisklabel)) { 772 printf("sd%d: %s\n",unit, errstring); 773 return ENXIO; 774 } 775 776 /* leave partition 2 "open" for raw I/O */ 777 778 sd->flags |= SDHAVELABEL; /* WE HAVE IT ALL NOW */ 779 return ESUCCESS; 780 } 781 782 /* 783 * Find out from the device what it's capacity is 784 */ 785 int 786 sd_size(int unit, int flags) 787 { 788 struct scsi_read_cap_data rdcap; 789 struct scsi_read_capacity scsi_cmd; 790 int size; 791 792 /* 793 * make up a scsi command and ask the scsi driver to do 794 * it for you. 795 */ 796 bzero(&scsi_cmd, sizeof(scsi_cmd)); 797 scsi_cmd.op_code = READ_CAPACITY; 798 799 /* 800 * If the command works, interpret the result as a 4 byte 801 * number of blocks 802 */ 803 if (sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd, 804 sizeof(scsi_cmd), (u_char *)&rdcap, sizeof(rdcap), 2000, flags) != 0) { 805 printf("could not get size of unit %d\n", unit); 806 return 0; 807 } else { 808 size = rdcap.addr_0 + 1 ; 809 size += rdcap.addr_1 << 8; 810 size += rdcap.addr_2 << 16; 811 size += rdcap.addr_3 << 24; 812 } 813 return size; 814 } 815 816 /* 817 * Get scsi driver to send a "are you ready?" command 818 */ 819 int 820 sd_test_unit_ready(int unit, int flags) 821 { 822 struct scsi_test_unit_ready scsi_cmd; 823 824 bzero(&scsi_cmd, sizeof(scsi_cmd)); 825 scsi_cmd.op_code = TEST_UNIT_READY; 826 827 return sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd, 828 sizeof(scsi_cmd), 0, 0, 100000, flags); 829 } 830 831 /* 832 * format disk 833 */ 834 int 835 sd_format(int unit, struct scsi_format_parms *f, int flags, int type) 836 { 837 struct scsi_prevent scsi_cmd; 838 839 bzero(&scsi_cmd, sizeof(scsi_cmd)); 840 scsi_cmd.op_code = FORMAT_DISK; 841 scsi_cmd.prevent= type; 842 return sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd, 843 sizeof(scsi_cmd), (u_char *)f, sizeof *f, 500000000, flags); 844 } 845 846 /* 847 * Prevent or allow the user to remove the tape 848 */ 849 int 850 sd_prevent(int unit, int type, int flags) 851 { 852 struct scsi_prevent scsi_cmd; 853 854 bzero(&scsi_cmd, sizeof(scsi_cmd)); 855 scsi_cmd.op_code = PREVENT_ALLOW; 856 scsi_cmd.prevent=type; 857 return sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd, 858 sizeof(scsi_cmd), 0, 0, 5000, flags); 859 } 860 861 /* 862 * Get scsi driver to send a "start up" command 863 */ 864 int 865 sd_start_unit(int unit, int flags) 866 { 867 struct scsi_start_stop scsi_cmd; 868 869 bzero(&scsi_cmd, sizeof(scsi_cmd)); 870 scsi_cmd.op_code = START_STOP; 871 scsi_cmd.start = 1; 872 873 return sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd, 874 sizeof(scsi_cmd), 0, 0, 2000, flags); 875 } 876 877 /* 878 * Tell the device to map out a defective block 879 */ 880 int 881 sd_reassign_blocks(int unit, int block) 882 { 883 struct scsi_reassign_blocks_data rbdata; 884 struct scsi_reassign_blocks scsi_cmd; 885 886 bzero(&scsi_cmd, sizeof(scsi_cmd)); 887 bzero(&rbdata, sizeof(rbdata)); 888 scsi_cmd.op_code = REASSIGN_BLOCKS; 889 890 rbdata.length_msb = 0; 891 rbdata.length_lsb = sizeof(rbdata.defect_descriptor[0]); 892 rbdata.defect_descriptor[0].dlbaddr_3 = ((block >> 24) & 0xff); 893 rbdata.defect_descriptor[0].dlbaddr_2 = ((block >> 16) & 0xff); 894 rbdata.defect_descriptor[0].dlbaddr_1 = ((block >> 8) & 0xff); 895 rbdata.defect_descriptor[0].dlbaddr_0 = ((block ) & 0xff); 896 897 return sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd, 898 sizeof(scsi_cmd), (u_char *)&rbdata, sizeof(rbdata), 5000, 0); 899 } 900 901 #define b2tol(a) (((unsigned)(a##_1) << 8) + (unsigned)a##_0 ) 902 903 /* 904 * Get the scsi driver to send a full inquiry to the 905 * device and use the results to fill out the disk 906 * parameter structure. 907 */ 908 int 909 sd_get_parms(int unit, int flags) 910 { 911 struct sd_data *sd = sd_data[unit]; 912 struct disk_parms *disk_parms = &sd->params; 913 struct scsi_mode_sense scsi_cmd; 914 struct scsi_mode_sense_data { 915 struct scsi_mode_header header; 916 struct blk_desc blk_desc; 917 union disk_pages pages; 918 } scsi_sense; 919 int sectors; 920 921 /* First check if we have it all loaded */ 922 if(!sd) 923 return 0; 924 if(sd->flags & SDVALID) 925 return 0; 926 927 /* First do a mode sense page 3 */ 928 if (sd_debug) { 929 bzero(&scsi_cmd, sizeof(scsi_cmd)); 930 scsi_cmd.op_code = MODE_SENSE; 931 scsi_cmd.page_code = 3; 932 scsi_cmd.length = 0x24; 933 934 /* 935 * do the command, but we don't need the results 936 * just print them for our interest's sake 937 */ 938 if (sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd, 939 sizeof(scsi_cmd), (u_char *)&scsi_sense, sizeof(scsi_sense), 940 2000, flags) != 0) { 941 printf("could not mode sense (3) for unit %d\n", unit); 942 return ENXIO; 943 } 944 printf("unit %d: %d trk/zn, %d altsec/zn, %d alttrk/zn, %d alttrk/lun\n", 945 unit, b2tol(scsi_sense.pages.disk_format.trk_z), 946 b2tol(scsi_sense.pages.disk_format.alt_sec), 947 b2tol(scsi_sense.pages.disk_format.alt_trk_z), 948 b2tol(scsi_sense.pages.disk_format.alt_trk_v)); 949 printf(" %d sec/trk, %d byte/sec, %d interleave, %d %d bytes/log_blk\n", 950 b2tol(scsi_sense.pages.disk_format.ph_sec_t), 951 b2tol(scsi_sense.pages.disk_format.bytes_s), 952 b2tol(scsi_sense.pages.disk_format.interleave), 953 sd_size(unit, flags), 954 _3btol((u_char *)scsi_sense.blk_desc.blklen)); 955 } 956 957 958 /* do a "mode sense page 4" */ 959 bzero(&scsi_cmd, sizeof(scsi_cmd)); 960 scsi_cmd.op_code = MODE_SENSE; 961 scsi_cmd.page_code = 4; 962 scsi_cmd.length = 0x20; 963 964 /* 965 * If the command worked, use the results to fill out 966 * the parameter structure 967 */ 968 if (sd_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd, 969 sizeof(scsi_cmd), (u_char *)&scsi_sense, sizeof(scsi_sense), 970 2000, flags) != 0) { 971 printf("could not mode sense (4) for unit %d\n", unit); 972 printf(" using ficticious geometry\n"); 973 sectors = sd_size(unit, flags); 974 disk_parms->heads = 64; 975 disk_parms->sectors = 32; 976 disk_parms->cyls = sectors/(64 * 32); 977 disk_parms->secsiz = SECSIZE; 978 } else { 979 if (sd_debug) { 980 printf(" %d cyl, %d head, %d precomp, %d redwrite, %d land\n", 981 _3btol((u_char *)&scsi_sense.pages.rigid_geometry.ncyl_2), 982 scsi_sense.pages.rigid_geometry.nheads, 983 b2tol(scsi_sense.pages.rigid_geometry.st_cyl_wp), 984 b2tol(scsi_sense.pages.rigid_geometry.st_cyl_rwc), 985 b2tol(scsi_sense.pages.rigid_geometry.land_zone)); 986 } 987 988 /* 989 * KLUDGE!!(for zone recorded disks) 990 * give a number of sectors so that sec * trks * cyls 991 * is <= disk_size 992 */ 993 disk_parms->heads = scsi_sense.pages.rigid_geometry.nheads; 994 disk_parms->cyls = 995 _3btol((u_char *)&scsi_sense.pages.rigid_geometry.ncyl_2); 996 disk_parms->secsiz = _3btol((u_char *)&scsi_sense.blk_desc.blklen); 997 998 sectors = sd_size(unit, flags); 999 sectors /= disk_parms->cyls; 1000 sectors /= disk_parms->heads; 1001 disk_parms->sectors = sectors; /* dubious on SCSI*/ 1002 } 1003 1004 disk_parms->disksize = disk_parms->sectors * disk_parms->heads * 1005 disk_parms->cyls; 1006 sd->flags |= SDVALID; 1007 return 0; 1008 } 1009 1010 /* 1011 * close the device.. only called if we are the LAST 1012 * occurence of an open device 1013 */ 1014 int 1015 sdclose(dev_t dev) 1016 { 1017 struct sd_data *sd; 1018 unsigned char unit, part; 1019 unsigned int old_priority; 1020 1021 unit = UNIT(dev); 1022 part = PARTITION(dev); 1023 sd = sd_data[unit]; 1024 sd->partflags[part] &= ~SDOPEN; 1025 sd->openparts &= ~(1 << part); 1026 if(sd->openparts == 0) 1027 sd_prevent(unit, PR_ALLOW, SCSI_SILENT|SCSI_ERR_OK); 1028 return 0; 1029 } 1030 1031 /* 1032 * ask the scsi driver to perform a command for us. 1033 * Call it through the switch table, and tell it which 1034 * sub-unit we want, and what target and lu we wish to 1035 * talk to. Also tell it where to find the command 1036 * how long int is. 1037 * Also tell it where to read/write the data, and how 1038 * long the data is supposed to be 1039 */ 1040 int 1041 sd_scsi_cmd(int unit, struct scsi_generic *scsi_cmd, int cmdlen, 1042 u_char *data_addr, int datalen, int timeout, int flags) 1043 { 1044 struct sd_data *sd = sd_data[unit]; 1045 struct scsi_xfer *xs; 1046 int retval, s; 1047 1048 if(scsi_debug & PRINTROUTINES) 1049 printf("\nsd_scsi_cmd%d ",unit); 1050 if(!sd->sc_sw) { 1051 printf("sd%d: not set up\n",unit); 1052 return EINVAL; 1053 } 1054 1055 xs = sd_get_xs(unit,flags); /* should wait unless booting */ 1056 if(!xs) { 1057 printf("sd_scsi_cmd%d: controller busy" 1058 " (this should never happen)\n",unit); 1059 return EBUSY; 1060 } 1061 1062 xs->flags |= INUSE; 1063 xs->flags |= flags; 1064 xs->adapter = sd->ctlr; 1065 xs->targ = sd->targ; 1066 xs->lu = sd->lu; 1067 xs->retries = SD_RETRIES; 1068 xs->timeout = timeout; 1069 xs->cmd = scsi_cmd; 1070 xs->cmdlen = cmdlen; 1071 xs->data = data_addr; 1072 xs->datalen = datalen; 1073 xs->resid = datalen; 1074 xs->when_done = (flags & SCSI_NOMASK) ?(int (*)())0 : sd_done; 1075 xs->done_arg = unit; 1076 xs->done_arg2 = (int)xs; 1077 1078 retry: 1079 xs->error = XS_NOERROR; 1080 xs->bp = 0; 1081 retval = (*(sd->sc_sw->scsi_cmd))(xs); 1082 switch(retval) { 1083 case SUCCESSFULLY_QUEUED: 1084 s = splbio(); 1085 while(!(xs->flags & ITSDONE)) 1086 tsleep((caddr_t)xs, PRIBIO+1, "sd_cmd", 0); 1087 splx(s); 1088 case HAD_ERROR: 1089 /*printf("err = %d ", xs->error);*/ 1090 switch(xs->error) { 1091 case XS_NOERROR: 1092 retval = ESUCCESS; 1093 break; 1094 case XS_SENSE: 1095 retval = sd_interpret_sense(unit, xs); 1096 break; 1097 case XS_DRIVER_STUFFUP: 1098 retval = EIO; 1099 break; 1100 case XS_TIMEOUT: 1101 case XS_BUSY: 1102 if(xs->retries-- ) { 1103 xs->flags &= ~ITSDONE; 1104 goto retry; 1105 } 1106 retval = EIO; 1107 break; 1108 default: 1109 retval = EIO; 1110 printf("sd%d: unknown error category from scsi driver\n", unit); 1111 } 1112 break; 1113 case COMPLETE: 1114 retval = ESUCCESS; 1115 break; 1116 case TRY_AGAIN_LATER: 1117 if(xs->retries-- ) { 1118 xs->flags &= ~ITSDONE; 1119 goto retry; 1120 } 1121 retval = EIO; 1122 break; 1123 default: 1124 retval = EIO; 1125 } 1126 1127 sd_free_xs(unit, xs, flags); 1128 sdstart(unit); /* check if anything is waiting fr the xs */ 1129 return retval; 1130 } 1131 1132 /* 1133 * Look at the returned sense and act on the error and detirmine 1134 * The unix error number to pass back... (0 = report no error) 1135 */ 1136 int 1137 sd_interpret_sense(int unit, struct scsi_xfer *xs) 1138 { 1139 struct sd_data *sd = sd_data[unit]; 1140 struct scsi_sense_data *sense; 1141 int key, silent; 1142 1143 /* If the flags say errs are ok, then always return ok. */ 1144 if (xs->flags & SCSI_ERR_OK) 1145 return ESUCCESS; 1146 silent = (xs->flags & SCSI_SILENT); 1147 1148 sense = &(xs->sense); 1149 switch(sense->error_class) { 1150 case 7: 1151 key = sense->ext.extended.sense_key; 1152 switch(key) { 1153 case 0x0: 1154 return ESUCCESS; 1155 case 0x1: 1156 if(!silent) { 1157 printf("sd%d: soft error(corrected) ", unit); 1158 if(sense->valid) { 1159 printf("block no. %d (decimal)", 1160 (sense->ext.extended.info[0] <<24) | 1161 (sense->ext.extended.info[1] <<16) | 1162 (sense->ext.extended.info[2] <<8) | 1163 (sense->ext.extended.info[3] )); 1164 } 1165 printf("\n"); 1166 } 1167 return ESUCCESS; 1168 case 0x2: 1169 if(!silent) 1170 printf("sd%d: not ready\n ", unit); 1171 return ENODEV; 1172 case 0x3: 1173 if(!silent) { 1174 printf("sd%d: medium error ", unit); 1175 if(sense->valid) { 1176 printf("block no. %d (decimal)", 1177 (sense->ext.extended.info[0] <<24) | 1178 (sense->ext.extended.info[1] <<16) | 1179 (sense->ext.extended.info[2] <<8) | 1180 (sense->ext.extended.info[3] )); 1181 } 1182 printf("\n"); 1183 } 1184 return EIO; 1185 case 0x4: 1186 if(!silent) 1187 printf("sd%d: non-media hardware failure\n ", unit); 1188 return EIO; 1189 case 0x5: 1190 if(!silent) 1191 printf("sd%d: illegal request\n ", unit); 1192 return EINVAL; 1193 case 0x6: 1194 /* 1195 * If we are not open, then this is not an error 1196 * as we don't have state yet. Either way, make 1197 * sure that we don't have any residual state 1198 */ 1199 if(!silent) 1200 printf("sd%d: reset\n", unit); 1201 sd->flags &= ~(SDVALID | SDHAVELABEL); 1202 if (sd->openparts) 1203 return EIO; 1204 return ESUCCESS; /* not an error if nothing's open */ 1205 case 0x7: 1206 if(!silent) { 1207 printf("sd%d: attempted protection violation ", unit); 1208 if(sense->valid) { 1209 printf("block no. %d (decimal)\n", 1210 (sense->ext.extended.info[0] <<24) | 1211 (sense->ext.extended.info[1] <<16) | 1212 (sense->ext.extended.info[2] <<8) | 1213 (sense->ext.extended.info[3] )); 1214 } 1215 printf("\n"); 1216 } 1217 return EACCES; 1218 case 0x8: 1219 if(!silent) { 1220 printf("sd%d: block wrong state (worm)\n ", unit); 1221 if(sense->valid) { 1222 printf("block no. %d (decimal)\n", 1223 (sense->ext.extended.info[0] <<24) | 1224 (sense->ext.extended.info[1] <<16) | 1225 (sense->ext.extended.info[2] <<8) | 1226 (sense->ext.extended.info[3] )); 1227 } 1228 printf("\n"); 1229 } 1230 return EIO; 1231 case 0x9: 1232 if(!silent) 1233 printf("sd%d: vendor unique\n", unit); 1234 return EIO; 1235 case 0xa: 1236 if(!silent) 1237 printf("sd%d: copy aborted\n ", unit); 1238 return EIO; 1239 case 0xb: 1240 if(!silent) 1241 printf("sd%d: command aborted\n ", unit); 1242 return EIO; 1243 case 0xc: 1244 if(!silent) { 1245 printf("sd%d: search returned\n ", unit); 1246 if(sense->valid) { 1247 printf("block no. %d (decimal)\n", 1248 (sense->ext.extended.info[0] <<24) | 1249 (sense->ext.extended.info[1] <<16) | 1250 (sense->ext.extended.info[2] <<8) | 1251 (sense->ext.extended.info[3] )); 1252 } 1253 printf("\n"); 1254 } 1255 return ESUCCESS; 1256 case 0xd: 1257 if(!silent) 1258 printf("sd%d: volume overflow\n ", unit); 1259 return ENOSPC; 1260 case 0xe: 1261 if(!silent) { 1262 printf("sd%d: verify miscompare\n ", unit); 1263 if(sense->valid) { 1264 printf("block no. %d (decimal)\n", 1265 (sense->ext.extended.info[0] <<24) | 1266 (sense->ext.extended.info[1] <<16) | 1267 (sense->ext.extended.info[2] <<8) | 1268 (sense->ext.extended.info[3] )); 1269 } 1270 printf("\n"); 1271 } 1272 return EIO; 1273 case 0xf: 1274 if(!silent) 1275 printf("sd%d: unknown error key\n ", unit); 1276 return EIO; 1277 } 1278 break; 1279 case 0: 1280 case 1: 1281 case 2: 1282 case 3: 1283 case 4: 1284 case 5: 1285 case 6: 1286 if(!silent)printf("sd%d: error class %d code %d\n", unit, 1287 sense->error_class, sense->error_code); 1288 if(sense->valid) 1289 if(!silent) 1290 printf("block no. %d (decimal)\n", 1291 (sense->ext.unextended.blockhi <<16) 1292 + (sense->ext.unextended.blockmed <<8) 1293 + (sense->ext.unextended.blocklow )); 1294 return EIO; 1295 } 1296 return 0; /* XXX? */ 1297 } 1298 1299 int 1300 sdsize(dev_t dev) 1301 { 1302 int unit = UNIT(dev), part = PARTITION(dev), val; 1303 struct sd_data *sd; 1304 1305 if (unit >= NSD) 1306 return -1; 1307 if(!sd_data[unit]) 1308 return -1; 1309 1310 sd = sd_data[unit]; 1311 if((sd->flags & SDINIT) == 0) 1312 return -1; 1313 1314 if( sd==0 || (sd->flags & SDHAVELABEL)==0 ) 1315 val = sdopen(MAKESDDEV(major(dev), unit, RAW_PART)); 1316 if ( val!=0 || sd->flags & SDWRITEPROT) 1317 return -1; 1318 1319 return (int)sd->disklabel.d_partitions[part].p_size; 1320 } 1321 1322 sddump() 1323 { 1324 printf("sddump() -- not implemented\n"); 1325 return -1; 1326 } 1327