1 /* 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 7 * 8 * %sccs.include.redist.c% 9 * 10 * from: $Hdr: sd.c,v 4.300 91/06/27 20:42:56 root Rel41 $ SONY 11 * 12 * @(#)sd.c 7.3 (Berkeley) 12/17/92 13 */ 14 #define dkblock(bp) bp->b_blkno 15 16 /* 17 * Copyright (c) 1987-1991 by SONY Corporation. 18 */ 19 20 #include "sd.h" 21 #if NSD > 0 22 23 #include <machine/fix_machine_type.h> 24 25 #include <sys/param.h> 26 #include <sys/buf.h> 27 #include <sys/proc.h> 28 #include <sys/user.h> 29 #include <sys/dkstat.h> 30 #include <sys/uio.h> 31 #include <sys/kernel.h> 32 #include <sys/reboot.h> 33 #include <sys/ioctl.h> 34 #include <sys/systm.h> 35 #include <sys/mtio.h> 36 #include <sys/stat.h> 37 #include <sys/disklabel.h> 38 #include <vm/vm.h> 39 #include <sys/syslog.h> 40 41 #include <ufs/ffs/fs.h> 42 43 # include <machine/cpu.h> 44 45 #ifdef IPC_MRX 46 # include "../iop/iopvar.h" 47 # include "../ipc/newsipc.h" 48 #endif 49 50 #ifdef CPU_SINGLE 51 # include <news3400/hbdev/hbvar.h> 52 # include <news3400/iodev/ioptohb.h> 53 #endif 54 55 #include <news3400/iodev/scsireg.h> 56 #include <news3400/iodev/scu.h> 57 #include <news3400/iodev/dkio.h> 58 #include <news3400/iodev/sdreg.h> 59 /* #ifdef DISKINFO KU:XXX */ 60 #include <news3400/iodev/diskinfo.h> 61 /* #endif /* DISKINFO */ 62 63 #define sce_sdecode sce_hdecode 64 65 #define dev2unit(x) ((minor(x) & ~0x80) >> 3) 66 #define dev2part(x) (minor(x) & 0x7) 67 68 /* /sys/sys/file.h */ 69 #define FREAD 00001 /* descriptor read/receive'able */ 70 #define FWRITE 00002 /* descriptor write/send'able */ 71 72 #define PART_A 0 73 #define PART_B 1 74 #define PART_C 2 75 #define PART_D 3 76 #define PART_E 4 77 #define PART_F 5 78 #define PART_G 6 79 #define PART_H 7 80 81 #define MAXPROBERETRY 100 82 #define NRETRY 10 83 #define MAXHRDERR 100 84 #define MAXRETRYCNT 16 85 86 #define SDBSIZE1K (DEV_BSIZE * 2) 87 #define MAXSDPHYS ((NSCMAP - 1) * NBPG) 88 89 #define D100MSEC 100000 90 91 #if OD_STOPTIME < 1 92 # define OD_STOPTIME 5 93 #endif /* OD_STOPTIME < 1 */ 94 95 #define FORMAT_MODE_CORRUPTED 0x31 96 #define ONLY_ONE 1 97 98 /************** PARTITIONS *************************************/ 99 100 #define PART_UNUSED (0) 101 #define PART_SPEC (-1) 102 #define PART_CALCF (-2) 103 #define PART_CALCG (-3) 104 105 struct defpart { 106 int range_min; 107 int range_max; 108 int partsize[PNUM]; 109 }; 110 111 struct defpart defpart_std[] = { 112 { 113 0, /* range_min */ 114 20, /* range_max */ 115 116 PART_SPEC, /* A: */ 117 PART_UNUSED, /* B: */ 118 PART_SPEC, /* C: */ 119 PART_UNUSED, /* D: */ 120 PART_UNUSED, /* E: */ 121 PART_UNUSED, /* F: */ 122 PART_UNUSED, /* G: */ 123 PART_UNUSED, /* H: */ 124 }, 125 { 126 20, /* range_min */ 127 61, /* range_max */ 128 129 15884, /* A: */ 130 10032, /* B: */ 131 PART_SPEC, /* C: */ 132 15884, /* D: */ 133 PART_UNUSED, /* E: */ 134 PART_CALCF, /* F: */ 135 PART_CALCG, /* G: */ 136 PART_UNUSED, /* H: */ 137 }, 138 { 139 61, /* range_min */ 140 206, /* range_max */ 141 142 15884, /* A: */ 143 33440, /* B: */ 144 PART_SPEC, /* C: */ 145 15884, /* D: */ 146 55936, /* E: */ 147 PART_CALCF, /* F: */ 148 PART_CALCG, /* G: */ 149 PART_UNUSED, /* H: */ 150 }, 151 { 152 206, /* range_min */ 153 356, /* range_max */ 154 155 15884, /* A: */ 156 33440, /* B: */ 157 PART_SPEC, /* C: */ 158 15884, /* D: */ 159 55936, /* E: */ 160 PART_CALCF, /* F: */ 161 PART_CALCG, /* G: */ 162 291346, /* H: */ 163 }, 164 { 165 356, /* range_min */ 166 99999999, /* range_max */ 167 168 15884, /* A: */ 169 66880, /* B: */ 170 PART_SPEC, /* C: */ 171 15884, /* D: */ 172 307200, /* E: */ 173 PART_CALCF, /* F: */ 174 PART_CALCG, /* G: */ 175 291346, /* H: */ 176 }, 177 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 178 }; 179 180 181 182 /************* ADDITIONAL SENSE ERROR CODES *************************/ 183 184 struct msg_list { 185 int ml_code; /* message code */ 186 int ml_msglvl; /* message level */ 187 char *ml_msgstr; /* message string */ 188 }; 189 190 #define sdskeylist skeylist 191 192 struct msg_list ecodelist_mo[] = { 193 { 0x80, 0, NULL }, 194 { 0x81, 0, NULL }, 195 { 0x82, 0, NULL }, 196 { 0x83, 0, NULL }, 197 198 { -1, 0, NULL } 199 }; 200 201 /************** Ref. sd_var.c ********************************/ 202 203 extern struct iop/**/_ctlr *sdminfo[]; 204 extern struct iop/**/_device *sddinfo[]; 205 extern struct iop/**/_device *sdip[][MAXSLAVE]; 206 207 extern struct buf rsdbuf[]; /* buffer for raw I/O */ 208 extern struct buf csdbuf[]; /* buffer for controll */ 209 extern struct buf sdutab[]; /* per drive buffers */ 210 211 extern struct sdc_softc sdc_softc[]; 212 extern struct sdd_softc sdd_softc[]; 213 extern u_char sd_b_openf[][PNUM]; 214 extern u_char sd_c_openf[][PNUM]; 215 216 extern struct scsi kernscsi[]; 217 extern struct sdst sdstdrv[]; 218 extern struct disklabel sdlabel[]; 219 extern struct size sdsizedrv[][PNUM]; 220 221 extern u_char sdc_rsense[][RSEN_CNT]; 222 223 extern struct sync_param sd_sync_param[]; 224 225 extern int nsd; 226 extern int nsdc; 227 228 /************** Ref. sddefs.c *********************************/ 229 230 extern struct sddevinfo sddevinfo[]; 231 232 /**************************************************************/ 233 234 extern struct msg_list skeylist[]; 235 extern struct msg_list ecodelist[]; 236 237 extern int boothowto; 238 extern int rsense_msg_disp; /* RSENSE-message display flag */ 239 extern int mo_disp_format; /* MO format mode display flag */ 240 241 int sd_ignore_error; 242 243 static int re_init_done; 244 245 static u_char sdwork[2340]; /* buffer for error recovery */ 246 static u_char sdtmp[DEV_BSIZE]; /* buffer for temporary */ 247 #ifdef mips 248 volatile static int sdtmp_stat = 0; /* status of sdtmp */ 249 #else 250 static int sdtmp_stat = 0; /* status of sdtmp */ 251 #endif 252 253 char pname[] = "abcdefgh"; 254 255 struct scsi *get_scsi(); 256 struct sc_map *get_sc_map(); 257 struct sc_inq *get_sc_inq(); 258 259 int sdprobe(), sdslave(), sdattach(), sddgo(), sdintr(); 260 int sdwstart, sdwatch(), sdstop(); /* Have started guardian */ 261 void sdexec(); 262 263 static sd_check(), sd_tstdrv(), sd_other_pages(), sd_err_rcv(), sd_synctr_on(); 264 static disklabel2sdst(), sdst2disklabel(), sd_scu_exec(); 265 266 #ifdef CPU_SINGLE 267 struct hb_driver sdcdriver = 268 {sdprobe, sdslave, sdattach, sddgo, sdintr, "sd", sddinfo, "sdc", sdminfo}; 269 #else 270 struct iop_driver sdcdriver = 271 {sdprobe, sdslave, sdattach, sddgo, "sd", sddinfo, "sdc", sdminfo}; 272 #endif 273 274 /*ARGSUSED*/ 275 sdprobe(im) 276 struct iop/**/_ctlr *im; 277 { 278 static int sdd_init = 0; 279 register struct sc_inq *sci; 280 register int ctlr; 281 register int fw; 282 int i; 283 284 if (sdd_init == 0) { 285 sdd_init++; 286 for (i = 0; i < nsd; i++) 287 sdd_softc[i].sdd_start = -2; 288 } 289 290 sci = get_sc_inq(im->im_intr); 291 ctlr = im->im_ctlr; 292 /* 293 * Check device type 294 * 0x00: Direct access device. 295 * 0x01: Sequential access device. 296 * 0x04: Write-once read-multiple device. 297 * 0x05: Read-only Direct-access device. 298 * 0x7f: Specified device is nonexistent. 299 */ 300 fw = sdc_softc[ctlr].sdc_firmware & ~SDCFW_DEVMASK; 301 302 switch (sci->sci_devtype) { 303 304 case 0x00: 305 /* 306 * Assumed that the device is HD. 307 * Later, distinguish MO from HD. 308 */ 309 sdc_softc[ctlr].sdc_firmware = fw | SDCFW_HD; 310 break; 311 312 default: 313 /* 314 * device type mis-match 315 */ 316 return (0); 317 } 318 319 /* 320 * Set interrupt handler routine 321 */ 322 if (set_inthandler(im, sdintr) == 0) 323 return (0); 324 325 return (1); 326 } 327 328 329 /*ARGSUSED*/ 330 sdslave(ii, reg, intr) 331 register struct iop/**/_device *ii; 332 caddr_t reg; 333 int intr; 334 { 335 register struct scsi *sc; 336 337 sc = get_scsi(intr); 338 sdip[ii->ii_ctlr][ii->ii_slave] = ii; 339 ii->ii_intr = intr; 340 341 /* 342 * check what the device is. 343 */ 344 if ((ii->ii_type = sd_check(ii, sc)) < 0) 345 goto bad_slave; 346 347 /* 348 * set up ERROR RECOVERY PARAMETERS 349 */ 350 if (sd_err_rcv(ii, sc) < 0) 351 goto bad_slave; 352 353 /* 354 * set up OTHER PARAMETERS 355 */ 356 if (sd_other_pages(ii, sc) < 0) 357 goto bad_slave; 358 359 /* 360 * set up Synchronous Transfer 361 */ 362 sd_synctr_on(ii, sc); 363 364 return (1); 365 366 bad_slave: 367 /* 368 * no such slave 369 */ 370 ii->ii_intr = -1; 371 return (0); 372 } 373 374 identity_check(sci, capacity, unit) 375 register struct sc_inq *sci; 376 int capacity; 377 int unit; 378 { 379 register struct sddevinfo *sdi; 380 register u_char *id_name; 381 register int index; 382 register int i; 383 int id_pass; 384 385 id_name = sci->sci_vendid; 386 while (*id_name == ' ') 387 id_name++; 388 389 index = UNKNOWN_DISK; 390 id_pass = 0; 391 for (sdi = sddevinfo; sdi->id_len >= 0; sdi++) { 392 /* 393 * check vendor & product ID 394 */ 395 if (strncmp(id_name, sdi->id_name, sdi->id_len) != 0) 396 continue; 397 id_pass = sdi - sddevinfo; 398 399 /* 400 * check revision 401 */ 402 if (strncmp(sdi->revs, sci->sci_revision, 4) == 0) 403 index = id_pass; 404 else { 405 for (i = 0; i < 4; i++) { 406 if (*(sdi->revs + i) == '?') 407 continue; 408 if (*(sdi->revs + i) != sci->sci_revision[i]) 409 break; 410 } 411 if (i < 4) 412 continue; 413 } 414 415 /* 416 * check capacity 417 */ 418 if (capacity == -1) 419 break; 420 if (sdi->capacity == -1) { 421 printf("sd%d: capacity=0x%x(%d)\n", 422 unit, capacity, capacity); 423 break; 424 } 425 if (capacity == sdi->capacity) 426 break; 427 } 428 if (index == 0) 429 index = id_pass; 430 431 return (index); 432 } 433 434 search_index(type) 435 register int type; 436 { 437 register struct sddevinfo *sdi; 438 register int i; 439 int index; 440 441 index = UNKNOWN_DISK; 442 i = 0; 443 for (sdi = sddevinfo; sdi->id_len > 0; sdi++) { 444 if (sdi->type == type) { 445 index = i; 446 break; 447 } 448 i++; 449 } 450 return (index); 451 } 452 453 static 454 sd_check(ii, sc) 455 register struct iop/**/_device *ii; 456 register struct scsi *sc; 457 { 458 register struct sc_inq *sci; 459 register struct sc_rcap *scr; 460 register int intr; 461 register int slave; 462 register int unit; 463 struct sdc_softc *sdc; 464 struct sdd_softc *sdd; 465 struct sc_extnd *sce; 466 int retrycnt; 467 int index; 468 int media_in; 469 470 intr = ii->ii_intr; 471 slave = ii->ii_slave; 472 unit = ii->ii_unit; 473 sdc = &sdc_softc[ii->ii_ctlr]; 474 sdd = &sdd_softc[unit]; 475 scr = (struct sc_rcap *)sc->sc_param; 476 sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0]; 477 478 /* 479 * check if the logical unit is ready. 480 * (by TEST UNIT READY command) 481 */ 482 media_in = sd_tstdrv(ii, sc); 483 if (media_in < 0) 484 return (-3); 485 486 /* 487 * Get controller and drive information. 488 * (by INQUIRY command) 489 */ 490 retrycnt = 0; 491 sci = get_sc_inq(intr); 492 loop_inq: 493 if (retrycnt++ > MAXPROBERETRY) 494 return (-1); 495 496 scop_inquiry(intr, sc, slave, SCSI_INTDIS, sizeof(struct sc_inq), sci); 497 sc->sc_tstatus &= TGSTMASK; 498 499 if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) { 500 501 bzero((caddr_t)sce, RSEN_CNT); 502 scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT, 503 (caddr_t)sce); 504 sc->sc_tstatus &= TGSTMASK; 505 if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) 506 return (-1); 507 if (sce->sce_extend != 0x70) 508 goto loop_inq; 509 510 switch (sce->sce_sdecode) { 511 512 case 0x04: /* Drive Not Ready */ 513 case 0x28: /* Medium Changed */ 514 case 0x29: /* Power On or Reset or Bus Device Reset */ 515 case 0x2a: /* Mode Select Parameter Changed */ 516 break; 517 518 default: 519 return (-1); 520 } 521 DELAY(D100MSEC); /* wait 100 ms. */ 522 goto loop_inq; 523 } 524 525 index = identity_check(sci, -1, unit); 526 527 switch (sddevinfo[index].type) { 528 529 case SMO_S501: 530 case SMO_S501_ISO: 531 case SMO_S501_ISO2: 532 sdc->sdc_firmware = 533 SDCFW_MO | (sdc->sdc_firmware & ~SDCFW_DEVMASK); 534 break; 535 536 defaults: 537 break; 538 } 539 540 if (sci->sci_qual & 0x80) { 541 /* 542 * removable medium device 543 */ 544 sdc->sdc_firmware |= SDCFW_RMB; 545 if ((media_in == 0) || ((sdc->sdc_firmware & SDCFW_MO) == 0)) 546 return (index); 547 } 548 549 /****************/ 550 /* HD & MO only */ 551 /****************/ 552 /* 553 * Get drive capacity 554 * (by READ CAPACITY command) 555 */ 556 retrycnt = 0; 557 loop_rcap: 558 if (retrycnt++ > MAXPROBERETRY) 559 return (-4); 560 561 scop_rcap(intr, sc, slave, SCSI_INTDIS, 8, (caddr_t)0); 562 sc->sc_tstatus &= TGSTMASK; 563 if (sc->sc_istatus != INST_EP) 564 return (-5); 565 if (sc->sc_tstatus == TGST_CC) { 566 bzero((caddr_t)sce, RSEN_CNT); 567 scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT, 568 (caddr_t)sce); 569 sc->sc_tstatus &= TGSTMASK; 570 if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) 571 return (-6); 572 if (sderrordisp((caddr_t)sce, ii) == FORMAT_MODE_CORRUPTED) { 573 scr->scr_nblock = 0; 574 scr->scr_blocklen = DEV_BSIZE; 575 sdd->sdd_flags |= SDDF_NONFMT; 576 } else { 577 DELAY(D100MSEC); /* wait 100 ms. */ 578 goto loop_rcap; 579 } 580 } 581 else if (sc->sc_tstatus != TGST_GOOD) { 582 DELAY(D100MSEC); /* wait 100 ms. */ 583 goto loop_rcap; 584 } 585 586 sdd->sdd_nsect = scr->scr_nblock + 1; 587 sdd->sdd_sectsize = scr->scr_blocklen; 588 589 index = identity_check(sci, scr->scr_nblock +1, unit); 590 591 return (index); 592 } 593 594 static 595 sd_tstdrv(ii, sc) 596 register struct iop/**/_device *ii; 597 register struct scsi *sc; 598 { 599 register struct sc_extnd *sce; 600 register int intr; 601 register int slave; 602 register int retrycnt; 603 struct sdc_softc *sdc; 604 struct sdd_softc *sdd; 605 606 sdc = &sdc_softc[ii->ii_ctlr]; 607 sdd = &sdd_softc[ii->ii_unit]; 608 609 intr = ii->ii_intr; 610 slave = ii->ii_slave; 611 sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0]; 612 retrycnt = 0; 613 loop_tst: 614 if (retrycnt++ > MAXPROBERETRY) 615 return (-1); 616 617 scop_tst(intr, sc, slave, SCSI_INTDIS); 618 sc->sc_tstatus &= TGSTMASK; 619 if (sc->sc_istatus != INST_EP) { 620 DELAY(D100MSEC); /* wait 100 ms. */ 621 goto loop_tst; 622 } 623 624 switch (sc->sc_tstatus) { 625 626 case TGST_CC: 627 /* Get error code */ 628 bzero((caddr_t)sce, RSEN_CNT); 629 scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT, 630 (caddr_t)sce); 631 sc->sc_tstatus &= TGSTMASK; 632 if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) { 633 DELAY(D100MSEC); /* wait 100 ms. */ 634 goto loop_tst; 635 } 636 637 if (sce->sce_extend != 0x70) 638 goto loop_tst; 639 640 switch (sce->sce_skey) { 641 642 case 0x0: /* No Sense */ 643 case 0x4: /* Hardware error */ 644 case 0x6: /* Unit attention */ 645 goto loop_tst; 646 647 case 0x2: /* Not ready */ 648 switch (sce->sce_sdecode) { 649 650 case 0x04: /* Not ready */ 651 /* 652 * Drive not ready... so start.. 653 */ 654 scop_stst(intr, sc, slave, SCSI_INTDIS, SDSS_START); 655 DELAY(D100MSEC * 10); /* wait 1 sec. */ 656 goto loop_tst; 657 658 case 0x0a: /* No Disk *//*MO*/ 659 default: 660 DELAY(D100MSEC); 661 goto loop_tst; 662 } 663 break; 664 665 case 0x03: 666 if (sce->sce_sdecode == FORMAT_MODE_CORRUPTED) 667 return (1); /* ignore error */ 668 /* fall through */ 669 670 default: 671 return (-2); 672 } 673 break; 674 675 case TGST_BUSY: 676 goto loop_tst; 677 678 case TGST_GOOD: 679 break; 680 681 default: 682 return (-3); 683 } 684 685 return (1); 686 } 687 688 #ifdef NEWSOS4 689 static 690 sd_setup_cmds(ii, sc) 691 register struct iop/**/_device *ii; 692 register struct scsi *sc; 693 { 694 register struct sddevinfo *sdi; 695 register struct sc_extnd *sce; 696 struct sc_ureq **p; 697 struct sc_ureq *scu; 698 int error; 699 extern struct sc_ureq scu_rsense; 700 701 if ((p = sddevinfo[ii->ii_type].setup_cmds) == NULL) 702 return (0); 703 704 /* 705 * Do setup commands 706 */ 707 while (scu = *p) { 708 bcopy((caddr_t)scu, sdtmp, sizeof(struct sc_ureq)); 709 scu = (struct sc_ureq *)sdtmp; 710 scu->scu_cdb[1] |= (ii->ii_slave & 0x07) << 5; 711 error = sd_scu_exec((ii->ii_unit << 3), scu, sc); 712 if (error != 0) 713 return (-1); 714 if ((scu->scu_istatus != INST_EP) 715 || (scu->scu_tstatus != TGST_GOOD)) { 716 bcopy((caddr_t)&scu_rsense, sdtmp, sizeof(struct sc_ureq)); 717 scu = (struct sc_ureq *)sdtmp; 718 scu->scu_cdb[1] |= (ii->ii_slave & 0x07) << 5; 719 sce = (scu->scu_addr == NULL) ? 720 (struct sc_extnd *)scu->scu_param : 721 (struct sc_extnd *)scu->scu_addr; 722 if (sd_scu_exec((ii->ii_unit << 3), scu, sc) == 0) { 723 /* UNIT ATTENTION */ 724 /* retry same command */ 725 if (sce->sce_skey == 0x06) 726 continue; 727 } 728 } 729 p++; 730 } 731 return (1); 732 } 733 #endif /* NEWSOS4 */ 734 735 static 736 sd_other_pages(ii, sc) 737 register struct iop/**/_device *ii; 738 register struct scsi *sc; 739 { 740 register struct sddevinfo *sdi; 741 char **p; 742 char *page; 743 int length; 744 int retrycnt; 745 int len; 746 747 sdi = &sddevinfo[ii->ii_type]; 748 if ((p = sdi->other_pages) == NULL) 749 return (0); 750 751 /* 752 * set other parameters 753 */ 754 while (page = *p++) { 755 retrycnt = 0; 756 loop_other_pages: 757 bzero((caddr_t)sdtmp, 4); 758 length = *(page + 1) + 2; 759 bcopy(page, &sdtmp[4], length); 760 if (retrycnt++ > MAXPROBERETRY) 761 return (-1); 762 763 scop_mselect(ii->ii_intr, sc, ii->ii_slave, SCSI_INTDIS, 764 (SDM_PF<<24) + length +4, (caddr_t)sdtmp); 765 sc->sc_tstatus &= TGSTMASK; 766 if ((sc->sc_istatus != INST_EP) 767 || (sc->sc_tstatus != TGST_GOOD)) { 768 struct sc_extnd *sce; 769 770 sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0]; 771 scop_rsense(ii->ii_intr, sc, ii->ii_slave, SCSI_INTDIS, 772 RSEN_CNT, (caddr_t)sce); 773 switch (sce->sce_skey) { 774 775 case 0x00: 776 case 0x02: 777 case 0x04: 778 case 0x06: 779 DELAY(D100MSEC); /* 100 ms. */ 780 goto loop_other_pages; 781 782 default: 783 return (-1); 784 } 785 } 786 } 787 788 if (sdi->firm_flags & FIRM_CACHE_ON) 789 sdc_softc[ii->ii_ctlr].sdc_firmware |= SDCFW_CACHE; 790 else 791 sdc_softc[ii->ii_ctlr].sdc_firmware &= ~SDCFW_CACHE; 792 793 return (1); 794 } 795 796 static 797 sd_err_rcv(ii, sc) 798 register struct iop/**/_device *ii; 799 register struct scsi *sc; 800 { 801 register struct sdc_softc *sdc; 802 register int intr; 803 register int slave; 804 register int len; 805 struct sc_extnd *sce; 806 struct sdd_softc *sdd; 807 struct sddevinfo *sdi; 808 int retrycnt; 809 char *erp_page; 810 811 intr = ii->ii_intr; 812 slave = ii->ii_slave; 813 sdc = &sdc_softc[ii->ii_ctlr]; 814 sdd = &sdd_softc[ii->ii_unit]; 815 sdi = &sddevinfo[ii->ii_type]; 816 sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0]; 817 818 /* 819 * set Default DISK sector size 820 */ 821 if (sdd->sdd_sectsize == 0) 822 sdd->sdd_sectsize = DEV_BSIZE; 823 824 825 if (sdi->ERP_page == NULL) { 826 /* 827 * use default error recovery parameters 828 */ 829 sdc->sdc_firmware |= SDCFW_DEFMODE; 830 return (0); 831 } 832 833 if (sdi->firm_flags & FIRM_AWRE) 834 sdc->sdc_firmware |= SDCFW_AWRE; 835 if (sdi->firm_flags & FIRM_ARRE) 836 sdc->sdc_firmware |= SDCFW_ARRE; 837 /* 838 * set ERROR RECOVERY PARAMETERS 839 */ 840 loop_err_rcv: 841 bzero((caddr_t)sdtmp, 4); 842 erp_page = sdi->ERP_page; 843 len = *(erp_page + 1) + 2; 844 bcopy(erp_page, &sdtmp[4], len); 845 846 scop_mselect(intr, sc, slave, SCSI_INTDIS, 847 (SDM_PF<<24) + len +4, (caddr_t)sdtmp); 848 sc->sc_tstatus &= TGSTMASK; 849 if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) { 850 if (sc->sc_tstatus == TGST_CC) { 851 bzero((caddr_t)sce, RSEN_CNT); 852 scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT, 853 (caddr_t)sce); 854 if (sce->sce_sdecode == 0x2a) { 855 /* mode select parameter changed */ 856 goto ercv_done; 857 } else if (sce->sce_skey == 0x6) { 858 /* unit attention */ 859 goto loop_err_rcv; 860 } 861 } 862 /* 863 * use default ERROR RECOVERY mode 864 */ 865 sdc->sdc_firmware |= SDCFW_DEFMODE; 866 sdc->sdc_firmware &= ~(SDCFW_AWRE|SDCFW_ARRE); 867 } 868 869 ercv_done: 870 871 return (1); 872 } 873 874 static 875 sd_synctr_on(ii, sc) 876 register struct iop/**/_device *ii; 877 register struct scsi *sc; 878 { 879 register struct sddevinfo *sdi; 880 register struct sync_param *syncp; 881 882 sdi = &sddevinfo[ii->ii_type]; 883 884 if (sdi->firm_flags & FIRM_SYNCTR) { 885 scinit(sc, ii->ii_slave, DEV_BSIZE); 886 sc->sc_opcode = SCOP_TST; 887 sc->sc_message = MSG_EXTND; /* extended message */ 888 sc->sc_param[0] = MSG_EXTND; 889 sc->sc_param[1] = 0x03; 890 sc->sc_param[2] = 0x01; /* synchronous transfer */ 891 sc->sc_param[3] = sdi->tr_period; /* transfer period */ 892 sc->sc_param[4] = sdi->tr_offset; /* REQ offset */ 893 894 if (sdc_softc[ii->ii_ctlr].sdc_firmware & SDCFW_CACHE) 895 sc->sc_tstatus |= TS_CONTR_ON; /* contiguous TR ON */ 896 else 897 sc->sc_tstatus |= TS_CONTR_OFF; /* contiguous TR OFF */ 898 899 #ifdef news1800 900 if (scsi_berr_bug() != 0) { 901 sc->sc_tstatus &= ~TS_CONTR_ON; 902 sc->sc_tstatus |= TS_CONTR_OFF; 903 } 904 #endif 905 906 if (sc->sc_tstatus & TS_CONTR_OFF) 907 sdc_softc[ii->ii_ctlr].sdc_firmware &= ~SDCFW_CONTR; 908 else 909 sdc_softc[ii->ii_ctlr].sdc_firmware |= SDCFW_CONTR; 910 911 sc_go(ii->ii_intr, sc, SCSI_INTDIS); 912 913 syncp = &sd_sync_param[ii->ii_unit]; 914 syncp->tr_period = sc->sc_param[3]; 915 syncp->tr_offset = sc->sc_param[4]; 916 if (sc->sc_param[4]) 917 sdd_softc[ii->ii_unit].sdd_flags |= SDDF_SYNCTR; 918 } 919 } 920 921 922 sdattach(ii) 923 register struct iop/**/_device *ii; 924 { 925 register int unit; 926 register int i; 927 struct sdc_softc *sdc; 928 struct sdd_softc *sdd; 929 int dummy; 930 931 sdc = &sdc_softc[ii->ii_ctlr]; 932 sdc->sdc_timeo = 60; /* timeout 60 sec */ 933 934 unit = ii->ii_unit; 935 sdd = &sdd_softc[unit]; 936 sdd->sdd_stoptime = OD_STOPTIME; /* REMOVABLE MEDIA */ 937 sdd->sdd_start = -2; 938 939 sdmaptype(ii); 940 941 if (sdwstart == 0) { 942 sdwstart++; 943 timeout(sdwatch, (caddr_t)0, hz); 944 timeout(sdstop, (caddr_t)0, hz); 945 } 946 947 #ifdef NEWSOS4 948 /* 949 * Do setup commands 950 */ 951 if (sd_setup_cmds(ii, get_scsi(ii->ii_intr)) < 0) 952 printf("sd%d: setup failure\n", ii->ii_unit); 953 #endif 954 955 /* 956 * initialize open flag 957 */ 958 for (i = 0; i < PNUM; i++) { 959 sd_b_openf[unit][i] = 0; 960 sd_c_openf[unit][i] = 0; 961 } 962 963 if (re_init_done > 0) 964 return; 965 966 if (sdc->sdc_firmware & SDCFW_HD) { 967 /* 968 * If device is Hard Disk, 969 * then get partition information. 970 */ 971 sdrpartinfo(ii); 972 dummy = DEV_BSIZE * sdstdrv[unit].rps * sdstdrv[unit].nsect; 973 } else 974 dummy = DEV_BSIZE * 40 * 31; 975 976 if (ii->ii_dk >= 0 && dummy) 977 dk_wpms[ii->ii_dk] = dummy / (2 * 1000000); 978 } 979 980 sdmaptype(ii) 981 register struct iop/**/_device *ii; 982 { 983 printf("sd%d: %s\n", ii->ii_unit, sddevinfo[ii->ii_type].call_name); 984 } 985 986 int sd_b_major = -1; 987 988 sd_b_open(dev, flag) 989 dev_t dev; 990 int flag; 991 { 992 sd_b_major = major(dev); 993 return (_sdopen(dev, flag, S_IFBLK)); 994 } 995 996 int sd_c_major = -1; 997 998 sd_c_open(dev, flag) 999 dev_t dev; 1000 int flag; 1001 { 1002 sd_c_major = major(dev); 1003 return (_sdopen(dev, flag, S_IFCHR)); 1004 } 1005 1006 _sdopen(dev, flag, fmt) 1007 register dev_t dev; 1008 int flag; 1009 int fmt; 1010 { 1011 register struct iop/**/_device *ii; 1012 register struct sdd_softc *sdd; 1013 register struct sdc_softc *sdc; 1014 register struct sddevinfo *sdi; 1015 register int unit; 1016 register int i; 1017 u_char *sdopfp; 1018 u_char old_sdopf; 1019 int media_changed; 1020 int s; 1021 int stat; 1022 struct scsi uscsi; 1023 1024 unit = dev2unit(dev); 1025 if (unit >= nsd || (ii = sddinfo[unit]) == 0 || ii->ii_alive == 0) 1026 return (ENXIO); 1027 1028 sdd = &sdd_softc[unit]; 1029 sdc = &sdc_softc[ii->ii_ctlr]; 1030 sdi = &sddevinfo[ii->ii_type]; 1031 1032 if (sdd->sdd_flags & SDDF_XUSE) 1033 return (EBUSY); 1034 1035 /* 1036 * LOCK while sdstop() running. 1037 */ 1038 s = splclock(); 1039 while (sdc->sdc_state & SDCS_SCUNLOCK) { 1040 sdc->sdc_state |= SDCS_OPEN_WAIT; 1041 sleep((caddr_t)sdc, PRIBIO); 1042 } 1043 splx(s); 1044 1045 /* 1046 * LOCK sdtmp buffer 1047 */ 1048 s = splclock(); 1049 while (sdtmp_stat & B_BUSY) { 1050 sdtmp_stat |= B_WANTED; 1051 sleep((caddr_t)sdtmp, PRIBIO); 1052 } 1053 sdtmp_stat |= B_BUSY; 1054 splx(s); 1055 sdd->sdd_flags |= SDDF_GETTMP; 1056 1057 if ((fmt & S_IFMT) == S_IFBLK) 1058 sdopfp = &sd_b_openf[unit][dev2part(dev)]; 1059 else 1060 sdopfp = &sd_c_openf[unit][dev2part(dev)]; 1061 old_sdopf = *sdopfp; 1062 if (old_sdopf <= 1) 1063 *sdopfp += 1; /* 1: 1st open (ONLY_ONE) */ 1064 /* 2: already opened */ 1065 stat = 0; 1066 media_changed = 0; 1067 1068 /* 1069 * From here on until pre_open_done is only for removable devices 1070 */ 1071 if ((sdc->sdc_firmware & SDCFW_RMB) == 0) 1072 goto pre_open_done; 1073 1074 if ((minor(dev) & 0x80) || (dev == rootdev)) 1075 sdd->sdd_stoptime = 0x7fffffff; /*XXX*/ 1076 1077 /* 1078 * Start Unit 1079 */ 1080 s = splclock(); /* inhibit clock interrupt */ 1081 i = sdd->sdd_start; 1082 sdd->sdd_start = sdd->sdd_stoptime; 1083 splx(s); 1084 if (i <= 0) { 1085 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 1086 uscsi.sc_opcode = SCOP_STST; 1087 uscsi.sc_count = SDSS_START; 1088 1089 if (sdcmd(dev, &uscsi)) { 1090 sdd->sdd_start = i; 1091 if ((flag & FWRITE) == 0) 1092 goto sdopen_setup; 1093 stat = EIO; 1094 goto pre_open_done; 1095 } 1096 } 1097 1098 /* 1099 * prevent medium removal 1100 */ 1101 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 1102 uscsi.sc_opcode = SCOP_MEDRMV; 1103 uscsi.sc_count = SDRMV_PREV; 1104 if (sdcmd(dev, &uscsi)) { 1105 stat = EIO; 1106 goto pre_open_done; 1107 } 1108 sdd->sdd_flags |= SDDF_INHRMV; 1109 1110 sdopen_setup: 1111 if ((sdd->sdd_flags & SDDF_SAMEDSK) == SDDF_DSKCHGD) { 1112 sdd->sdd_flags |= SDDF_SAMEDSK; 1113 media_changed = 1; 1114 1115 /* 1116 * From here on until mo_check_done is only for MO device 1117 */ 1118 if ((sdc->sdc_firmware & SDCFW_MO) == 0) 1119 goto mo_check_done; 1120 1121 /* 1122 * Mode Sense 1123 */ 1124 bzero(sdtmp, 36); 1125 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 1126 uscsi.sc_cpoint = sdtmp; 1127 uscsi.sc_ctrnscnt = 36; 1128 uscsi.sc_opcode = SCOP_MSENSE; 1129 uscsi.sc_lad = (SDM_PF << 16)|((SDM_PC_CUR|SDM_PCODE_ALL) << 8); 1130 uscsi.sc_count = 36; 1131 1132 if (sdcmd(dev, &uscsi) == 0) { 1133 /* 1134 * check Write Protect mode 1135 */ 1136 if (sdtmp[2] & 0x80) 1137 sdd->sdd_flags |= SDDF_WPROTECT; 1138 else 1139 sdd->sdd_flags &= ~SDDF_WPROTECT; 1140 /* 1141 * check Format Mode 1142 */ 1143 if (sdtmp[26] == 2) { 1144 ii->ii_type = search_index(SMO_S501); 1145 if (mo_disp_format) 1146 printf("sd%d: format mode 2 (original format)\n", unit); 1147 } else if (sdtmp[26] == 3) { 1148 int spare; 1149 1150 spare = *(short *)&sdtmp[32]; 1151 if (spare == 2048) 1152 ii->ii_type = 1153 search_index(SMO_S501_ISO2); 1154 else 1155 ii->ii_type = 1156 search_index(SMO_S501_ISO); 1157 if (mo_disp_format) 1158 printf("sd%d: format mode 3 (ISO format) spare=%d\n", unit, spare); 1159 } else { 1160 sdd->sdd_flags |= SDDF_NONFMT; 1161 if (mo_disp_format) 1162 printf("sd%d: Non format\n", unit); 1163 } 1164 sdi = &sddevinfo[ii->ii_type]; 1165 } 1166 1167 /* 1168 * Mode Select 1169 * Error Recovery Parameters set 1170 */ 1171 i = *(sdi->ERP_page +1) + 2; /* page length */ 1172 bzero(sdtmp, i + 4); 1173 bcopy(sdi->ERP_page, (caddr_t)&sdtmp[4], i); 1174 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 1175 uscsi.sc_cpoint = sdtmp; 1176 uscsi.sc_ctrnscnt = i + 4; 1177 uscsi.sc_opcode = SCOP_MSELECT; 1178 uscsi.sc_lad = (SDM_PF << 16); 1179 uscsi.sc_count = i + 4; 1180 1181 (void) sdcmd(dev, &uscsi); 1182 1183 /* 1184 * Read Grown Defect list 1185 */ 1186 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 1187 uscsi.sc_cpoint = sdtmp; 1188 uscsi.sc_ctrnscnt = 4; 1189 uscsi.sc_opcode = SCOP_RDL; 1190 uscsi.sc_cdb.un_type1.t1_ladhi = (SDDL_GLIST|SDDL_PHYSFMT) << 8; 1191 uscsi.sc_cdb.un_type1.t1_p3 = 4; 1192 1193 (void) sdcmd(dev, &uscsi); 1194 i = *(short *)&sdtmp[2] / 8; 1195 if (i > (1024*9/10)) 1196 printf("sd%d: WARNING: DEFECT SPARE LOCATION < 10%\n", 1197 unit); 1198 mo_check_done: 1199 /* 1200 * Read Capacity 1201 */ 1202 bzero((caddr_t)sdtmp, 8); 1203 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 1204 uscsi.sc_cpoint = sdtmp; 1205 uscsi.sc_ctrnscnt = 8; 1206 uscsi.sc_opcode = SCOP_RCAP; 1207 1208 (void) sdcmd(dev, &uscsi); 1209 sdd->sdd_nsect = *(int *)&sdtmp[0] + 1; 1210 sdd->sdd_sectsize = *(int *)&sdtmp[4]; 1211 1212 if ((sdd->sdd_sectsize != DEV_BSIZE) 1213 && (sdd->sdd_sectsize != SDBSIZE1K)) 1214 sdd->sdd_sectsize = DEV_BSIZE; 1215 } 1216 1217 if ((sdd->sdd_flags & SDDF_WPROTECT) && (flag & FWRITE)) 1218 stat = EROFS; 1219 1220 pre_open_done: 1221 1222 if (stat == 0) { 1223 if ((isalone(unit) == ONLY_ONE) || media_changed) { 1224 /* 1225 * read partition information from sector zero. 1226 */ 1227 sdrpartinfo(ii); 1228 if (ii->ii_dk >= 0) { 1229 dk_wpms[ii->ii_dk] = 1230 sdd->sdd_sectsize * sdstdrv[unit].rps 1231 * sdstdrv[unit].nsect / (2 * 1000000); 1232 } 1233 } 1234 } else { 1235 /* 1236 * open error 1237 */ 1238 *sdopfp = old_sdopf; 1239 if ((sdd->sdd_flags & SDDF_INHRMV) && (isalone(unit) == 0)) { 1240 sdd->sdd_flags &= ~SDDF_INHRMV; 1241 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 1242 uscsi.sc_opcode = SCOP_MEDRMV; 1243 uscsi.sc_count = SDRMV_ALLOW; 1244 (void) sdcmd(dev, &uscsi); 1245 } 1246 } 1247 1248 /* 1249 * UNLOCK open 1250 */ 1251 s = splclock(); 1252 sdd->sdd_flags &= ~SDDF_GETTMP; 1253 if (sdtmp_stat & B_WANTED) 1254 wakeup((caddr_t)sdtmp); 1255 sdtmp_stat &= ~(B_BUSY|B_WANTED); 1256 splx(s); 1257 return (stat); 1258 } 1259 1260 int sd_access_check_on; /* Common flags for sd_access_check() */ 1261 1262 sd_access_check(bp) 1263 register struct buf *bp; 1264 { 1265 register struct iop/**/_device *ii; 1266 register struct sdd_softc *sdd; 1267 int unit; 1268 int check_part; 1269 int limit; 1270 int over; 1271 register struct size *sizes; 1272 register int lba; /* logical block address */ 1273 register int sz; 1274 register int i; 1275 1276 check_part = 0; 1277 unit = dev2unit(bp->b_dev); 1278 ii = sddinfo[unit]; 1279 sdd = &sdd_softc[unit]; 1280 sizes = sdstdrv[unit].sizes; 1281 1282 lba = sizes[dev2part(bp->b_dev)].sd_blkoff + dkblock(bp); 1283 sz = howmany(bp->b_bcount, sdd->sdd_sectsize); 1284 1285 /* 1286 * When block device is used, 1287 * inhibit raw device write operation. 1288 */ 1289 if ((major(bp->b_dev) == sd_c_major) /* RAW I/O */ 1290 && ((bp->b_flags & B_READ) == 0) /* WRITE */ 1291 && ((ii->ii_flags & SD_F_ENW) == 0) /* INHIBIT */ 1292 && ((sd_access_check_on & SD_F_ENW) == 0)) { 1293 1294 for (i = 0; i < PNUM; i++) { 1295 if (sd_b_openf[unit][i] == 0) 1296 continue; 1297 /* 1298 * |----|========|---|======|-------| 1299 * 1 |---+++--------------------------| CUT OFF 1300 * 2 |---++++++++++++-----------------| CUT OFF 1301 * 3 |---++++++++++++++++-------------| CUT OFF 1302 * 4 |---++++++++++++++++++++++++-----| CUT OFF 1303 * 5 |-------+++----------------------| ERROR 1304 * 6 |------------+++-----------------| ERROR 1305 * 7 |------------+++++++-------------| ERROR 1306 * 8 |------------+++++++++++++++-----| ERROR 1307 */ 1308 if ((lba < (sizes[i].sd_blkoff + sizes[i].sd_nblocks)) 1309 && ((lba + sz) > sizes[i].sd_blkoff)) 1310 check_part |= (1 << i); 1311 } 1312 } 1313 1314 if (check_part) { 1315 limit = 0x7fffffff; /* XXX */ 1316 for (i = 0; i < PNUM; i++) { 1317 if ((check_part & (1 << i)) == 0) 1318 continue; 1319 1320 if (lba >= sizes[i].sd_blkoff) { 1321 bp->b_flags |= B_ERROR; 1322 bp->b_error = EIO; 1323 bp->b_resid = bp->b_bcount; 1324 1325 printf("sd%d%c: RAW DEVICE WRITE PROTECTED: ", 1326 unit, pname[dev2part(bp->b_dev)]); 1327 printf("sn = 0x%x(%d), off = 0x%x(%d)\n", 1328 dkblock(bp)*DEV_BSIZE/sdd->sdd_sectsize, 1329 dkblock(bp)*DEV_BSIZE/sdd->sdd_sectsize, 1330 sizes[dev2part(bp->b_dev)].sd_blkoff, 1331 sizes[dev2part(bp->b_dev)].sd_blkoff); 1332 1333 return (-1); 1334 } 1335 1336 if (sizes[i].sd_blkoff < limit) 1337 limit = sizes[i].sd_blkoff; 1338 } 1339 } else { 1340 limit = sizes[dev2part(bp->b_dev)].sd_blkoff 1341 + sizes[dev2part(bp->b_dev)].sd_nblocks; 1342 } 1343 1344 if ((over = (lba + sz) - limit) > 0) { 1345 /* 1346 * Logical Block Address is outside the valid area. 1347 */ 1348 if (((ii->ii_flags & SD_F_EOLBA) != 0) 1349 || ((sd_access_check_on & SD_F_EOLBA) != 0)) { 1350 /* 1351 * error if outside LBA 1352 */ 1353 return(-1); 1354 } 1355 bp->b_resid = bp->b_bcount - (sz - over) * sdd->sdd_sectsize; 1356 if (bp->b_resid >= bp->b_bcount) { 1357 bp->b_resid = bp->b_bcount; 1358 return(-1); 1359 } 1360 } 1361 1362 return (0); 1363 } 1364 1365 sd_b_close(dev, flag) 1366 dev_t dev; 1367 int flag; 1368 { 1369 return (_sdclose(dev, flag, S_IFBLK)); 1370 } 1371 1372 sd_c_close(dev, flag) 1373 dev_t dev; 1374 int flag; 1375 { 1376 return (_sdclose(dev, flag, S_IFCHR)); 1377 } 1378 1379 _sdclose(dev, flag, fmt) 1380 register dev_t dev; 1381 int flag; 1382 int fmt; 1383 { 1384 register struct iop/**/_device *ii; 1385 register struct sdd_softc *sdd; 1386 register int unit; 1387 struct sdc_softc *sdc; 1388 struct scsi uscsi; 1389 struct sc_extnd *sce; 1390 1391 unit = dev2unit(dev); 1392 if (unit >= nsd || (ii = sddinfo[unit]) == 0 || ii->ii_alive == 0) 1393 return (ENXIO); 1394 1395 sdd = &sdd_softc[unit]; 1396 sdc = &sdc_softc[ii->ii_ctlr]; 1397 sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0]; 1398 1399 /* 1400 * still remain jobs 1401 * sleep about 10ms -> 1sec 1402 */ 1403 while (ii->ii_mi->im_tab.b_actf != NULL) 1404 sleep((caddr_t)&lbolt, PRIBIO); 1405 1406 if ((fmt & S_IFMT) == S_IFBLK) 1407 sd_b_openf[unit][dev2part(dev)] = 0; 1408 else 1409 sd_c_openf[unit][dev2part(dev)] = 0; 1410 sdd->sdd_flags &= ~SDDF_XUSE; 1411 1412 if ((sdc->sdc_firmware & SDCFW_RMB) && (isalone(unit) == 0)) { 1413 sdd->sdd_flags &= ~SDDF_INHRMV; 1414 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 1415 uscsi.sc_opcode = SCOP_MEDRMV; 1416 uscsi.sc_count = SDRMV_ALLOW; 1417 (void) sdcmd(dev, &uscsi); 1418 } 1419 return (0); 1420 } 1421 1422 sdcmd(dev, usc) 1423 dev_t dev; 1424 struct scsi *usc; 1425 { 1426 register struct buf *bp; 1427 register struct scsi *ksc; 1428 register u_char *point; 1429 register int unit; 1430 int error; 1431 int s; 1432 int cnt; 1433 1434 if (usc == 0) 1435 return (ENXIO); 1436 1437 error = 0; 1438 unit = dev2unit(dev); 1439 bp = &csdbuf[unit]; 1440 1441 /* 1442 * LOCK csdbuf 1443 */ 1444 s = splclock(); 1445 while (bp->b_flags & B_BUSY) { 1446 bp->b_flags |= B_WANTED; 1447 sleep((caddr_t)bp, PRIBIO); 1448 } 1449 bzero((caddr_t)bp, sizeof(struct buf)); 1450 bp->b_flags = B_BUSY|B_READ; 1451 splx(s); 1452 1453 ksc = &kernscsi[unit]; 1454 bcopy((caddr_t)usc, (caddr_t)ksc, sizeof(struct scsi)); 1455 /* 1456 * setup command buffer 1457 */ 1458 bp->b_dev = dev; 1459 bp->b_proc = curproc; 1460 cnt = ksc->sc_ctrnscnt; 1461 bp->b_bcount = cnt; 1462 1463 point = ksc->sc_cpoint; 1464 bp->b_un.b_addr = (caddr_t)point; 1465 if (cnt > 0) { 1466 if (point == NULL) { 1467 ksc->sc_cpoint = point = get_scsi(unit)->sc_param; 1468 if (cnt > 20) { 1469 error = EFAULT; 1470 goto done; 1471 } 1472 } 1473 if (point < (u_char *)KERNBASE) { 1474 if (useracc(point, cnt, B_WRITE) == NULL) { 1475 error = EFAULT; 1476 goto done; 1477 } 1478 curproc->p_flag |= SPHYSIO; 1479 vslock(point, cnt); 1480 bp->b_flags |= B_PHYS; 1481 } 1482 #ifndef mips 1483 else { 1484 if (kernacc(point, cnt, B_WRITE) == NULL) { 1485 error = EFAULT; 1486 goto done; 1487 } 1488 } 1489 #endif 1490 ksc->sc_tstatus = TS_MAPPED_PIO; /* XXX */ 1491 } 1492 1493 /* 1494 * call strategy entry, and wait command done. 1495 */ 1496 sdstrategy(bp); 1497 iowait(bp); 1498 1499 if ((cnt > 0) && (point < (u_char *)KERNBASE)) { 1500 vsunlock(point, cnt, B_READ); 1501 curproc->p_flag &= ~SPHYSIO; 1502 } 1503 if ((bp->b_flags & B_ERROR) == 0) 1504 error = 0; 1505 else { 1506 if (bp->b_error) 1507 error = bp->b_error; 1508 else 1509 error = EIO; 1510 } 1511 bcopy((caddr_t)ksc, (caddr_t)usc, sizeof(struct scsi)); 1512 1513 done: 1514 /* 1515 * UNLOCK csdbuf 1516 */ 1517 s = splclock(); 1518 if (bp->b_flags & B_WANTED) 1519 wakeup((caddr_t)bp); 1520 bp->b_flags = 0; 1521 splx(s); 1522 return (error); 1523 } 1524 1525 /* 1526 * read partition information from sector zero. 1527 */ 1528 sdrpartinfo(ii) 1529 register struct iop/**/_device *ii; 1530 { 1531 register struct disklabel *dlp; 1532 register struct sdst *hsp; 1533 register struct sdst *st; 1534 register int unit; 1535 register int i; 1536 struct firstsector *fsp; 1537 struct sdc_softc *sdc; 1538 struct sdd_softc *sdd; 1539 struct sddevinfo *sdi; 1540 #ifdef DISKINFO 1541 struct diskinfo *dip; 1542 #endif 1543 struct scsi uscsi; 1544 int s; 1545 1546 sdi = &sddevinfo[ii->ii_type]; 1547 unit = ii->ii_unit; 1548 1549 sdd = &sdd_softc[unit]; 1550 sdc = &sdc_softc[ii->ii_ctlr]; 1551 1552 if ((sdd->sdd_flags & (SDDF_NONFMT|SDDF_FMTDONE)) == 0) { 1553 register struct sc_rcap *scr = (struct sc_rcap *)sdtmp; 1554 1555 sdd->sdd_flags |= SDDF_FMTDONE; 1556 1557 bzero((caddr_t)sdtmp, 8); 1558 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 1559 uscsi.sc_cpoint = (u_char *)scr; 1560 uscsi.sc_ctrnscnt = 8; 1561 uscsi.sc_opcode = SCOP_RCAP; 1562 (void) sdcmd(unit << 3, &uscsi); 1563 1564 sdd->sdd_nsect = scr->scr_nblock + 1; 1565 sdd->sdd_sectsize = scr->scr_blocklen; 1566 if (sdd->sdd_sectsize == 0) 1567 sdd->sdd_sectsize = SDBSIZE1K; 1568 } 1569 1570 bzero(sdtmp, DEV_BSIZE); 1571 1572 if ((sdd->sdd_flags & SDDF_NONFMT) == 0) { 1573 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 1574 uscsi.sc_cpoint = sdtmp; 1575 uscsi.sc_ctrnscnt = DEV_BSIZE; 1576 uscsi.sc_opcode = SCOP_READ; 1577 uscsi.sc_lad = 0; 1578 uscsi.sc_count = 1; 1579 1580 (void) sdcmd(unit << 3, &uscsi); 1581 sdd->sdd_flags &= ~SDDF_SKIPCHECK; 1582 } 1583 1584 fsp = (struct firstsector *)sdtmp; 1585 dlp = (struct disklabel *)(sdtmp + LABELOFFSET); 1586 #ifdef DISKINFO 1587 dip = &fsp->diskinfo; 1588 #endif 1589 1590 s = splclock(); 1591 hsp = &sdstdrv[unit]; 1592 bzero((caddr_t)hsp, sizeof (struct sdst)); 1593 bzero(&sdlabel[unit], sizeof (struct disklabel)); 1594 1595 if ((dlp->d_magic == DISKMAGIC) 1596 && ((ii->ii_flags & SD_F_IGNLABEL) == 0)) { 1597 sdlabel[unit] = *dlp; 1598 disklabel2sdst(unit, dlp, hsp); 1599 #ifdef DISKINFO 1600 } else if ((dip->di_magic == DISKINFO_MAGIC) 1601 && ((ii->ii_flags & SD_F_IGNLABEL) == 0)) { 1602 diskinfo2sdst(unit, dip, hsp); 1603 diskinfo2disklabel(unit, dip, &sdlabel[unit]); 1604 #endif 1605 } else { 1606 if ((ii->ii_type == UNKNOWN_DISK) 1607 || (sdi->sdstp->sizes == calc_disk_sizes)) { 1608 /* 1609 * If device is UNKNOWN PARTITION SIZE, 1610 * calculate default partition from capacity. 1611 */ 1612 st = sdi->sdstp; 1613 hsp->nsect = st->nsect; /* # sectors/track */ 1614 hsp->ntrak = st->ntrak; /* # tracks/cylinder */ 1615 hsp->nspc = st->nspc; /* # sectors/cylinder */ 1616 hsp->ncyl = st->ncyl; /* # cylinders */ 1617 hsp->rps = st->rps; /* # revolutions/sec */ 1618 hsp->sizes = sdsizedrv[unit]; /* partition table */ 1619 1620 sd_calcpart(ii, hsp->sizes, 1621 sdd->sdd_nsect, sdd->sdd_sectsize); 1622 sdst2disklabel(unit, hsp, &sdlabel[unit]); 1623 } else { 1624 /* 1625 * If device is support disk, 1626 * copy default partition from size table. 1627 */ 1628 st = sdi->sdstp; 1629 1630 hsp->nsect = st->nsect; /* # sectors/track */ 1631 hsp->ntrak = st->ntrak; /* # tracks/cylinder */ 1632 hsp->nspc = st->nspc; /* # sectors/cylinder */ 1633 hsp->ncyl = st->ncyl; /* # cylinders */ 1634 hsp->rps = st->rps; /* # revolutions / second */ 1635 hsp->sizes = sdsizedrv[unit]; /* partition table */ 1636 1637 for (i = 0; i < PNUM; i++) { 1638 hsp->sizes[i].sd_nblocks = st->sizes[i].sd_nblocks; 1639 hsp->sizes[i].sd_blkoff = st->sizes[i].sd_blkoff; 1640 } 1641 sdst2disklabel(unit, hsp, &sdlabel[unit]); 1642 } 1643 } 1644 1645 /* BEGIN XXX*/ 1646 if (hsp->rps == 0) { 1647 /* 1648 * If device is support disk, 1649 * copy default partition from size table. 1650 */ 1651 st = sdi->sdstp; 1652 1653 hsp->nsect = st->nsect; /* # sectors/track */ 1654 hsp->ntrak = st->ntrak; /* # tracks/cylinder */ 1655 hsp->nspc = st->nspc; /* # sectors/cylinder */ 1656 hsp->ncyl = st->ncyl; /* # cylinders */ 1657 hsp->rps = st->rps; /* # revolutions / second */ 1658 sdst2disklabel(unit, hsp, &sdlabel[unit]); 1659 } 1660 /* END XXX*/ 1661 (void)splx(s); 1662 } 1663 1664 static char Warn_Part[] = "sd%d: PARTITION TABLE CHANGED\n"; 1665 static char Pr_Part_Fmt[] = "sd%d%c: nblk=%d, off=%d\n"; 1666 1667 #define stsz(N) st->sizes[(N)].sd_nblocks 1668 #define stof(N) st->sizes[(N)].sd_blkoff 1669 #define dlsz(N) dlp->d_partitions[(N)].p_size 1670 #define dlof(N) dlp->d_partitions[(N)].p_offset 1671 #define disz(N) dip->di_part[(N)].dp_nblocks 1672 #define diof(N) dip->di_part[(N)].dp_blkoff 1673 1674 #ifndef BBSIZE 1675 #define BBSIZE 8192 1676 #endif 1677 1678 static 1679 check_sdst(unit, st) 1680 int unit; 1681 struct sdst *st; 1682 { 1683 if (st->nsect == 0) { 1684 st->nsect = 1; 1685 printf("sd%d: nsect SHOULD BE != 0, 1 assumed\n", unit); 1686 } 1687 1688 if (st->rps == 0) { 1689 st->rps = 60; 1690 printf("sd%d: rps SHOULD BE != 0, 60 assumed\n", unit); 1691 } 1692 } 1693 1694 static 1695 disklabel2sdst(unit, dlp, st) 1696 int unit; 1697 register struct disklabel *dlp; 1698 register struct sdst *st; 1699 { 1700 register int i; 1701 int msg_header_printed; 1702 1703 msg_header_printed = 0; 1704 1705 st->nsect = dlp->d_nsectors; /* # sectors/track */ 1706 st->ntrak = dlp->d_ntracks; /* # tracks/cylinder */ 1707 st->nspc = dlp->d_secpercyl; /* # sectors/cylinder */ 1708 st->ncyl = dlp->d_ncylinders; /* # cylinders */ 1709 st->rps = dlp->d_rpm / 60; /* # revolutions / second */ 1710 st->sizes = sdsizedrv[unit]; /* partition table */ 1711 1712 check_sdst(unit, st); 1713 1714 for (i = 0; i < PNUM; i++) { 1715 if (msg_header_printed == 0) { 1716 if (((stsz(i) != 0) || (stof(i) != 0)) 1717 && ((stsz(i) != dlsz(i)) || (stof(i) != dlof(i)))) { 1718 msg_header_printed = 1; 1719 } 1720 } 1721 } 1722 1723 for (i = 0; i < PNUM; i++) { 1724 stsz(i) = dlsz(i); 1725 stof(i) = dlof(i); 1726 } 1727 1728 if (msg_header_printed) { 1729 printf(Warn_Part, unit); 1730 for (i = 0; i < PNUM; i++) 1731 printf(Pr_Part_Fmt, unit, pname[i], stsz(i), stof(i)); 1732 } 1733 } 1734 1735 #ifdef DISKINFO 1736 static 1737 diskinfo2sdst(unit, dip, st) 1738 int unit; 1739 register struct diskinfo *dip; 1740 register struct sdst *st; 1741 { 1742 register int i; 1743 int msg_header_printed; 1744 1745 msg_header_printed = 0; 1746 1747 st->nsect = dip->di_dkst.dks_nsect; /* # sectors/track */ 1748 st->ntrak = dip->di_dkst.dks_ntrak; /* # tracks/cylinder */ 1749 st->nspc = dip->di_dkst.dks_nsect * dip->di_dkst.dks_ntrak; 1750 /* # sectors/cylinder */ 1751 st->ncyl = dip->di_dkst.dks_ncyl; /* # cylinders */ 1752 st->rps = dip->di_dkst.dks_rps; /* # revolutions / second */ 1753 st->sizes = sdsizedrv[unit]; /* partition table */ 1754 1755 check_sdst(unit, st); 1756 1757 for (i = 0; i < PNUM; i++) { 1758 if (msg_header_printed == 0) { 1759 if (((stsz(i) != 0) || (stof(i) != 0)) 1760 && ((stsz(i) != disz(i)) || (stof(i) != diof(i)))) { 1761 msg_header_printed = 1; 1762 } 1763 } 1764 } 1765 1766 for (i = 0; i < PNUM; i++) { 1767 stsz(i) = disz(i); 1768 stof(i) = diof(i); 1769 } 1770 1771 if (msg_header_printed) { 1772 printf(Warn_Part, unit); 1773 for (i = 0; i < PNUM; i++) 1774 printf(Pr_Part_Fmt, unit, pname[i], stsz(i), stof(i)); 1775 } 1776 } 1777 1778 static 1779 diskinfo2disklabel(unit, dip, dlp) 1780 int unit; 1781 register struct diskinfo *dip; 1782 register struct disklabel *dlp; 1783 { 1784 register int i; 1785 1786 dlp->d_type = DTYPE_SCSI; /* drive type */ 1787 dlp->d_secsize = sdd_softc[unit].sdd_sectsize; /* # of bytes per sector */ 1788 dlp->d_nsectors = dip->di_dkst.dks_nsect; /* # sectors/track */ 1789 dlp->d_ntracks = dip->di_dkst.dks_ntrak; /* # tracks/cylinder */ 1790 dlp->d_ncylinders = dip->di_dkst.dks_ncyl; /* # cylinders */ 1791 dlp->d_secpercyl = dip->di_dkst.dks_nsect * dip->di_dkst.dks_ntrak; 1792 /* # sectors/cylinder */ 1793 dlp->d_rpm = dip->di_dkst.dks_rps * 60; /* # revolutions / second */ 1794 dlp->d_bbsize = BBSIZE; /*XXX*/ /* size of boot area at sn0, bytes */ 1795 dlp->d_sbsize = SBSIZE; /*XXX*/ /* max size of fs superblock, bytes */ 1796 1797 for (i = 0; i < PNUM; i++) { 1798 dlsz(i) = disz(i); 1799 dlof(i) = diof(i); 1800 } 1801 } 1802 #endif /* DISKINFO */ 1803 1804 /* #ifdef DISKINFO KU:XXX */ 1805 static 1806 disklabel2diskinfo(unit, dlp, dip) 1807 int unit; 1808 register struct disklabel *dlp; 1809 register struct diskinfo *dip; 1810 { 1811 register int i; 1812 1813 dip->di_magic = DISKINFO_MAGIC; 1814 dip->di_dkst.dks_nsect = dlp->d_nsectors; /* # sectors/track */ 1815 dip->di_dkst.dks_ntrak = dlp->d_ntracks; /* # tracks/cylinder */ 1816 dip->di_dkst.dks_ncyl = dlp->d_ncylinders; /* # cylinders */ 1817 dip->di_dkst.dks_rps = dlp->d_rpm / 60; /* # revolutions/second */ 1818 1819 for (i = 0; i < PNUM; i++) { 1820 disz(i) = dlsz(i); 1821 diof(i) = dlof(i); 1822 } 1823 } 1824 /* #endif /* DISKINFO */ 1825 1826 static 1827 sdst2disklabel(unit, st, dlp) 1828 int unit; /*XXX*/ 1829 register struct sdst *st; 1830 register struct disklabel *dlp; 1831 { 1832 register int i; 1833 1834 dlp->d_type = DTYPE_SCSI; /* drive type */ 1835 dlp->d_secsize = sdd_softc[unit].sdd_sectsize; /* # of bytes per sector */ 1836 dlp->d_nsectors = st->nsect; /* # sectors/track */ 1837 dlp->d_ntracks = st->ntrak; /* # tracks/cylinder */ 1838 dlp->d_ncylinders = st->ncyl; /* # cylinders */ 1839 dlp->d_secpercyl = st->nspc; /* # sectors/cylinder */ 1840 dlp->d_rpm = st->rps * 60; /* # revolutions / minute */ 1841 dlp->d_bbsize = BBSIZE; /*XXX*/ /* size of boot area at sn0, bytes */ 1842 dlp->d_sbsize = SBSIZE; /*XXX*/ /* max size of fs superblock, bytes */ 1843 1844 for (i = 0; i < PNUM; i++) { 1845 dlsz(i) = stsz(i); 1846 dlof(i) = stof(i); 1847 } 1848 } 1849 1850 #undef stsz 1851 #undef stof 1852 #undef dlsz 1853 #undef dlof 1854 #undef disz 1855 #undef diof 1856 1857 sd_calcpart(ii, disk_sizes, nsect, sectsize) 1858 register struct iop/**/_device *ii; 1859 register struct size disk_sizes[]; 1860 int nsect; 1861 int sectsize; 1862 { 1863 register struct defpart *dp; 1864 register int size_mb; 1865 register int i; 1866 int psize; 1867 1868 size_mb = nsect * sectsize / (1024 * 1024); 1869 1870 for (dp = defpart_std; dp->range_max; dp++) 1871 if ((dp->range_min <= size_mb) && (size_mb < dp->range_max)) 1872 break; 1873 1874 /* PASS1 */ 1875 for (i = 0; i < PNUM; i++) { 1876 psize = dp->partsize[i]; 1877 1878 switch (psize) { 1879 1880 case PART_UNUSED: 1881 disk_sizes[i].sd_nblocks = 0; 1882 break; 1883 1884 case PART_SPEC: 1885 disk_sizes[i].sd_nblocks = nsect * sectsize / DEV_BSIZE; 1886 break; 1887 1888 case PART_CALCF: 1889 case PART_CALCG: 1890 break; 1891 1892 default: 1893 disk_sizes[i].sd_nblocks = psize; 1894 break; 1895 } 1896 } 1897 1898 /* PASS2 */ 1899 for (i = 0; i < PNUM; i++) { 1900 psize = dp->partsize[i]; 1901 1902 switch (psize) { 1903 1904 case PART_UNUSED: 1905 case PART_SPEC: 1906 break; 1907 1908 case PART_CALCF: 1909 disk_sizes[i].sd_nblocks = 1910 disk_sizes[PART_C].sd_nblocks - 1911 (disk_sizes[PART_A].sd_nblocks + 1912 disk_sizes[PART_B].sd_nblocks + 1913 disk_sizes[PART_D].sd_nblocks + 1914 disk_sizes[PART_E].sd_nblocks + 1915 disk_sizes[PART_H].sd_nblocks); 1916 break; 1917 1918 case PART_CALCG: 1919 disk_sizes[i].sd_nblocks = 1920 disk_sizes[PART_C].sd_nblocks - 1921 (disk_sizes[PART_A].sd_nblocks + 1922 disk_sizes[PART_B].sd_nblocks + 1923 disk_sizes[PART_H].sd_nblocks); 1924 break; 1925 1926 default: 1927 break; 1928 } 1929 } 1930 1931 /* OFFSET */ 1932 disk_sizes[PART_A].sd_blkoff = 0; 1933 disk_sizes[PART_B].sd_blkoff = disk_sizes[PART_A].sd_nblocks; 1934 disk_sizes[PART_C].sd_blkoff = 0; 1935 disk_sizes[PART_D].sd_blkoff = disk_sizes[PART_A].sd_nblocks 1936 + disk_sizes[PART_B].sd_nblocks 1937 + disk_sizes[PART_H].sd_nblocks; 1938 disk_sizes[PART_E].sd_blkoff = disk_sizes[PART_D].sd_blkoff 1939 + disk_sizes[PART_D].sd_nblocks; 1940 disk_sizes[PART_F].sd_blkoff = disk_sizes[PART_E].sd_blkoff 1941 + disk_sizes[PART_E].sd_nblocks; 1942 disk_sizes[PART_G].sd_blkoff = disk_sizes[PART_D].sd_blkoff; 1943 1944 if (disk_sizes[PART_H].sd_nblocks == 0) 1945 disk_sizes[PART_H].sd_blkoff = 0; 1946 else { 1947 disk_sizes[PART_H].sd_blkoff = 1948 disk_sizes[PART_A].sd_nblocks + 1949 disk_sizes[PART_B].sd_nblocks; 1950 } 1951 1952 for (i = 0; i < PNUM; i++) 1953 if (disk_sizes[i].sd_nblocks == 0) 1954 disk_sizes[i].sd_blkoff = 0; 1955 } 1956 1957 int sd_str_pr = 0; 1958 1959 sdstrategy(bp) 1960 register struct buf *bp; 1961 { 1962 register struct iop/**/_device *ii; 1963 register struct sdst *st; 1964 register struct buf *dp; 1965 register int unit; 1966 register int ssize; 1967 struct sdd_softc *sdd; 1968 struct sdc_softc *sdc; 1969 long bn; 1970 int xunit; 1971 int s; 1972 1973 xunit = dev2part(bp->b_dev); 1974 unit = dev2unit(bp->b_dev); 1975 if (unit >= nsd || (ii = sddinfo[unit]) == 0 || ii->ii_alive == 0) 1976 goto bad; 1977 1978 if (bp != &csdbuf[unit]) { 1979 /* 1980 * READ / WRITE command 1981 */ 1982 sdd = &sdd_softc[unit]; 1983 if (sdd->sdd_flags & SDDF_NONFMT) 1984 goto bad; 1985 sdc = &sdc_softc[ii->ii_ctlr]; 1986 ssize = sdd->sdd_sectsize; 1987 if ((ssize != DEV_BSIZE) 1988 && ((((dkblock(bp) * DEV_BSIZE) % ssize) != 0) 1989 || (((bp->b_flags & B_READ) == 0) && 1990 ((bp->b_bcount % ssize) != 0)))) { 1991 goto bad; 1992 } 1993 1994 st = &sdstdrv[unit]; 1995 bn = dkblock(bp); 1996 bp->b_resid = 0; 1997 if ((bn < 0) || (bn >= st->sizes[xunit].sd_nblocks)) 1998 goto bad2; 1999 if (sd_access_check(bp) < 0) 2000 goto bad2; 2001 2002 #ifdef notdef /* KU: XXX */ 2003 bp->b_cylin = (bn + st->sizes[xunit].sd_blkoff) / st->nspc; 2004 } else { 2005 bp->b_cylin = 0; 2006 #endif 2007 } 2008 2009 s = splsc(); 2010 dp = &sdutab[ii->ii_unit]; 2011 disksort(dp, bp); 2012 if (dp->b_active == 0) { 2013 sdustart(ii); 2014 bp = &ii->ii_mi->im_tab; 2015 if (bp->b_actf && bp->b_active == 0) 2016 sdstart(ii->ii_mi); 2017 } 2018 splx(s); 2019 return; 2020 2021 bad: 2022 bp->b_flags |= B_ERROR; 2023 goto done; 2024 bad2: 2025 bp->b_resid = bp->b_bcount; 2026 done: 2027 iodone(bp); 2028 } 2029 2030 /* 2031 * Unit start routine. 2032 */ 2033 sdustart(ii) 2034 register struct iop/**/_device *ii; 2035 { 2036 register struct iop/**/_ctlr *im; 2037 register struct buf *dp; 2038 2039 if (ii == NULL) 2040 return; 2041 im = ii->ii_mi; 2042 dk_busy &= ~(1 << ii->ii_dk); 2043 dp = &sdutab[ii->ii_unit]; 2044 if (dp->b_actf == NULL) 2045 return; 2046 /* 2047 * If the controller is active, just remember 2048 * that this device would like to be positioned ... 2049 * if we tried to position now we would confuse the SD. 2050 */ 2051 if (im->im_tab.b_active) { 2052 sdc_softc[im->im_ctlr].sdc_softas |= (1 << ii->ii_slave); 2053 return; 2054 } 2055 /* 2056 * If we have already positioned this drive, 2057 * then just put it on the ready queue. 2058 */ 2059 if (dp->b_active == 0) 2060 dp->b_active = 1; 2061 /* 2062 * Device is ready to go 2063 * put it on the ready queue for the controller 2064 * (unless its already there.) 2065 */ 2066 if (dp->b_active != 2) { 2067 dp->b_forw = NULL; 2068 if (im->im_tab.b_actf == NULL) 2069 im->im_tab.b_actf = dp; 2070 else 2071 im->im_tab.b_actl->b_forw = dp; 2072 im->im_tab.b_actl = dp; 2073 dp->b_active = 2; 2074 } 2075 } 2076 2077 /* 2078 * Start up a transfer on a drive. 2079 */ 2080 sdstart(im) 2081 register struct iop/**/_ctlr *im; 2082 { 2083 register struct buf *bp; 2084 register struct buf *dp; 2085 register struct sdc_softc *sdc; 2086 2087 loop: 2088 /* 2089 * Pull a request off the controller queue. 2090 */ 2091 if ((dp = im->im_tab.b_actf) == NULL) 2092 return; 2093 if ((bp = dp->b_actf) == NULL) { 2094 im->im_tab.b_actf = dp->b_forw; 2095 goto loop; 2096 } 2097 /* 2098 * Mark controller busy, and 2099 * determine destination of this request. 2100 */ 2101 im->im_tab.b_active++; 2102 2103 sdexec(bp); 2104 } 2105 2106 void 2107 sdexec(bp) 2108 register struct buf *bp; 2109 { 2110 register struct iop/**/_device *ii; 2111 register struct buf_stat *bs; 2112 register struct scsi *sc; 2113 register int ssize; 2114 register int unit; 2115 register int intr; 2116 register int bn; 2117 struct sdc_softc *sdc; 2118 struct sdd_softc *sdd; 2119 struct sdst *st; 2120 int sz; 2121 int over; 2122 struct sc_map *map; 2123 2124 unit = dev2unit(bp->b_dev); 2125 ii= sddinfo[unit]; 2126 intr = ii->ii_intr; 2127 sdd = &sdd_softc[unit]; 2128 sdc = &sdc_softc[ii->ii_ctlr]; 2129 2130 sc = get_scsi(intr); 2131 2132 if (bp == &csdbuf[unit]) { /* do sdcmd() */ 2133 bcopy((caddr_t)&kernscsi[unit], 2134 (caddr_t)sc, sizeof(struct scsi)); 2135 if (bp->b_un.b_addr == NULL) { 2136 map = 0; 2137 } else { 2138 map = get_sc_map(intr); 2139 sc->sc_map = (struct sc_map *)ipc_phys(map); 2140 } 2141 } else { /* R/W */ 2142 ssize = sdd->sdd_sectsize; 2143 2144 st = &sdstdrv[unit]; 2145 bn = dkblock(bp); 2146 if (sdd->sdd_lastblk / st->nspc != bn / st->nspc) 2147 dk_seek[ii->ii_dk]++; 2148 2149 st = &sdstdrv[unit]; 2150 bn = dkblock(bp); 2151 2152 /* 2153 * Setup for the transfer, and get in the IOP queue. 2154 */ 2155 scinit(sc, ii->ii_slave, ssize); 2156 sc->sc_ctrnscnt = bp->b_bcount - bp->b_resid; 2157 map = get_sc_map(intr); 2158 sc->sc_map = (struct sc_map *)ipc_phys(map); 2159 2160 /* cdb */ 2161 sc->sc_cdb.un_type1.t1_opcode = 2162 (bp->b_flags & B_READ) ? SCOP_EREAD : 2163 (ii->ii_flags & SD_F_WRTVRFY) ? SCOP_WRTVRFY : 2164 SCOP_EWRITE; 2165 #ifdef mips 2166 { 2167 int v; 2168 2169 v = (bn + st->sizes[dev2part(bp->b_dev)].sd_blkoff) 2170 * DEV_BSIZE / sdd->sdd_sectsize; 2171 sc->sc_ladhi = v >> 16; 2172 sc->sc_ladlo = v; 2173 2174 v = (sc->sc_ctrnscnt + ssize - 1) / ssize; 2175 sc->sc_cdb.un_type1.t1_p2 = v >> 8; 2176 sc->sc_cdb.un_type1.t1_p3 = v; 2177 } 2178 #else 2179 *(u_int *)(&sc->sc_cdb.un_type1.t1_ladhi) = 2180 (bn + st->sizes[dev2part(bp->b_dev)].sd_blkoff) 2181 * DEV_BSIZE / sdd->sdd_sectsize; 2182 *(u_short *)(&sc->sc_cdb.un_type1.t1_p2) = 2183 (sc->sc_ctrnscnt + ssize -1) / ssize; 2184 #endif 2185 if ((sdd->sdd_flags & SDDF_ERASEOFF) 2186 && ((bp->b_flags & B_READ) == 0)) { 2187 sc->sc_ctrl = 0x40; 2188 } 2189 } 2190 2191 sdc->sdc_firmware |= SDCFW_BUSY; 2192 iop/**/go(ii, map); 2193 } 2194 2195 /* 2196 * Now all ready to go. 2197 */ 2198 sddgo(im) 2199 register struct iop/**/_ctlr *im; 2200 { 2201 register int intr; 2202 2203 im->im_tab.b_active = 2; 2204 intr = im->im_intr; 2205 2206 sc_go(intr, get_scsi(intr), SCSI_INTEN); 2207 } 2208 2209 /* 2210 * copyin(), copyout() can't use in the interrupt routine. 2211 * because user process is changed. 2212 */ 2213 /* 2214 * Handle a disk interrupt. 2215 * d: controller number 2216 */ 2217 sdintr(d) 2218 int d; 2219 { 2220 register struct iop/**/_ctlr *im; 2221 register struct sdc_softc *sdc; 2222 register struct sdd_softc *sdd; 2223 register struct scsi *sc; 2224 register int intr; 2225 register int unit; 2226 register int slave; 2227 register int as; 2228 struct iop/**/_device *ii; 2229 struct sddevinfo *sdi; 2230 struct sc_extnd *sce; 2231 struct sdst *st; 2232 struct buf *bp; 2233 struct buf *dp; 2234 char *erp_page; 2235 int code; 2236 int len; 2237 int tstatus; 2238 int delay_start(); 2239 int delay_medrmv(); 2240 int wait_re_init_done(); 2241 2242 im = sdminfo[d]; 2243 sdc = &sdc_softc[im->im_ctlr]; 2244 intr = im->im_intr; 2245 as = sdc->sdc_softas; 2246 2247 sdc->sdc_wticks = 0; 2248 sc = get_scsi(intr); 2249 /* 2250 * If SDCS_IOCTL bit is set, then don't check error. 2251 */ 2252 if (sdc->sdc_state & SDCS_IOCTL) { 2253 sdc->sdc_state &= ~SDCS_IOCTL; 2254 sdd = &sdd_softc[(sdip[d][sc->sc_identify & IDT_DRMASK])->ii_unit]; 2255 2256 if (sdc->sdc_state & SDCS_SCUNLOCK) { 2257 int s; 2258 2259 sdc->sdc_state &= ~SDCS_SCUNLOCK; 2260 s = splclock(); 2261 if (sdc->sdc_state & SDCS_OPEN_WAIT) { 2262 sdc->sdc_state &= ~SDCS_OPEN_WAIT; 2263 wakeup((caddr_t)sdc); 2264 } 2265 splx(s); 2266 /* 2267 * UNLOCK SCSI access 2268 */ 2269 sdc->sdc_firmware &= ~SDCFW_BUSY; 2270 } 2271 return; 2272 } 2273 2274 im->im_tab.b_active = 1; 2275 /* 2276 * Get device and block structures, and a pointer 2277 * to the iop_device for the drive. 2278 */ 2279 dp = im->im_tab.b_actf; 2280 bp = dp->b_actf; 2281 unit = dev2unit(bp->b_dev); 2282 2283 ii = sddinfo[unit]; 2284 slave = ii->ii_slave; 2285 st = &sdstdrv[unit]; 2286 dk_busy &= ~(1 << ii->ii_dk); 2287 sdd = &sdd_softc[unit]; 2288 sdi = &sddevinfo[ii->ii_type]; 2289 sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0]; 2290 2291 /* 2292 * Check error on the drive. 2293 */ 2294 tstatus = sc->sc_tstatus & TGSTMASK; 2295 if (sc->sc_istatus != INST_EP) { 2296 /* 2297 * initiator status is bad. 2298 * check & retry !! 2299 */ 2300 if ((sc->sc_istatus&(INST_EP|INST_PRE)) == (INST_EP|INST_PRE)) { 2301 /* detect parity error or abnormal terminate */ 2302 if ((sc->sc_istatus & INST_LB) == 0) 2303 printf("sd%d: SCSI bus parity error\n", unit); 2304 sdc->sdc_countcc--; 2305 goto sdintr_exec; 2306 } 2307 if ((sc->sc_istatus & INST_EP) == 0) { 2308 if (sc->sc_istatus & (INST_WAIT | INST_IP | INST_WR)) { 2309 if (++sdc->sdc_retrycnt < NRETRY) { 2310 im->im_tab.b_active = 2; 2311 /* 2312 * Konomama return sitemo, 2313 * lost interrupt ni narudake deha 2314 * naidarou ka ? 2315 * Isso error ni sitahou ga 2316 * ii nodeha naidarou ka ? 2317 */ 2318 return; 2319 } 2320 } 2321 printf("SCSI%d: abnormal termination\n", intr); 2322 printf("ISTAT = 0x%x, TSTAT = 0x%x\n", 2323 sc->sc_istatus, sc->sc_tstatus); 2324 if (++sdc->sdc_nhrderr >= MAXHRDERR) { 2325 printf("SCSI%d: too many hard errors\n", intr); 2326 sdc->sdc_nhrderr = 0; 2327 goto sdintr_error; 2328 } 2329 screset(intr); 2330 goto sdintr_exec; 2331 } 2332 if ((sc->sc_istatus & (INST_TO|INST_HE)) != 0) { 2333 if (sc->sc_istatus & INST_HE) { 2334 /* 2335 * SCSI bus reset is occured. 2336 * to be continue --> hdreset() 2337 */ 2338 re_init_done = 0; 2339 timeout(wait_re_init_done, bp, 10*hz); 2340 return; 2341 } 2342 if (++sdc->sdc_nhrderr >= MAXHRDERR) { 2343 printf("SCSI%d: too many hard errors (ISTAT=0x%x)\n", 2344 intr, sc->sc_istatus); 2345 sdc->sdc_nhrderr = 0; 2346 goto sdintr_error; 2347 } 2348 if (++sdc->sdc_retrycnt >= NRETRY) { 2349 printf("SCSI%d: too many initiator errors (ISTAT=0x%x)\n", 2350 intr, sc->sc_istatus); 2351 goto sdintr_error; 2352 } 2353 DELAY(D100MSEC * 10); 2354 goto sdintr_exec; 2355 } 2356 } 2357 2358 if (sdd->sdd_flags & SDDF_SKIPCHECK) 2359 goto sdintr_done; 2360 2361 check_target_status: 2362 /* 2363 * check target status 2364 */ 2365 switch (sdc->sdc_state) { 2366 2367 /********************************/ 2368 /* */ 2369 /* NORMAL OPERATION */ 2370 /* */ 2371 /********************************/ 2372 case SDCS_NORMAL: 2373 switch (tstatus) { 2374 2375 case TGST_GOOD: 2376 break; 2377 2378 case TGST_CC: 2379 sdc->sdc_state |= SDCS_RSENSE; 2380 sdintr_rsense: 2381 im->im_tab.b_active = 2; 2382 bzero((caddr_t)sce, RSEN_CNT); 2383 scop_rsense(intr, sc, slave, 2384 SCSI_INTEN, RSEN_CNT, (caddr_t)sce); 2385 return; 2386 2387 case TGST_BUSY: 2388 if (++sdc->sdc_retrycnt > MAXRETRYCNT) { 2389 goto sdintr_error; 2390 } 2391 timeout(sdexec, (caddr_t)bp, hz); 2392 return; 2393 2394 default: 2395 printf("sd%d: bad target status 0x%x\n", 2396 unit, sc->sc_tstatus); 2397 goto sdintr_error; 2398 } 2399 break; 2400 2401 /****************************************/ 2402 /* */ 2403 /* REQUEST SENSE analysis */ 2404 /* */ 2405 /****************************************/ 2406 case SDCS_RSENSE: 2407 case SDCS_PREVRMB|SDCS_RSENSE: 2408 case SDCS_ECC|SDCS_RASREAD|SDCS_RSENSE: 2409 case SDCS_ECC|SDCS_RASWRITE|SDCS_RSENSE: 2410 case SDCS_ECCOFF|SDCS_RSENSE: 2411 case SDCS_ECCOFF|SDCS_RASBLK|SDCS_RSENSE: 2412 case SDCS_ECCOFF|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE: 2413 case SDCS_ECC|SDCS_RASBLK|SDCS_RSENSE: 2414 case SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE: 2415 if (tstatus != TGST_GOOD) { 2416 printf("sd%d: bad target status 0x%x\n", 2417 unit, sc->sc_tstatus); 2418 goto sdintr_error; 2419 } 2420 /* 2421 * error message print out 2422 */ 2423 code = sderrordisp(sce, ii); 2424 2425 2426 if ((sdc->sdc_state == (SDCS_ECC|SDCS_RASBLK|SDCS_RSENSE)) || 2427 (sdc->sdc_state == (SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE))) { 2428 printf("sd%d: cannot reassign block %d\n", 2429 unit, sdd->sdd_badsect); 2430 goto sdintr_error; 2431 } 2432 if (sdc->sdc_state == (SDCS_PREVRMB|SDCS_RSENSE)) { 2433 if (sce->sce_skey == 0x2) { 2434 /* 2435 * Not ready 2436 */ 2437 sdc->sdc_state = SDCS_PREVRMB; 2438 timeout(delay_medrmv, (caddr_t)ii, hz); 2439 return; 2440 } 2441 } 2442 2443 /* */ 2444 /* RSENSE error handler */ 2445 /* */ 2446 switch (code) { 2447 2448 /********************************/ 2449 /* continue */ 2450 /********************************/ 2451 /* NO SENSE */ 2452 case 0x00: /* No Additional Sense Information */ 2453 /* RECOVERED ERROR */ 2454 case 0x38: /* Recovered with Auto-Reallocation */ 2455 sdc->sdc_state &= ~SDCS_RSENSE; 2456 goto check_target_status; 2457 2458 /********************************/ 2459 /* continue or error */ 2460 /********************************/ 2461 /* ILLEGAL REQUEST */ 2462 2463 case 0x21: /* illegal Logical Block Address */ 2464 if (&st->sizes[dev2part(bp->b_dev)] == NULL) 2465 goto sdintr_error; 2466 if (bp->b_bcount > 0) { 2467 bp->b_resid = bp->b_bcount 2468 - (sdd->sdd_badsect * sdd->sdd_sectsize 2469 - (st->sizes[dev2part(bp->b_dev)].sd_blkoff 2470 + dkblock(bp)) * DEV_BSIZE); 2471 } 2472 if (bp->b_resid >= bp->b_bcount || bp->b_resid <= 0) { 2473 /* 2474 * all I/O failure 2475 */ 2476 bp->b_resid = bp->b_bcount; 2477 goto sdintr_error; 2478 } 2479 /* Ignore error */ 2480 break; 2481 2482 /* MEDIUM ERROR */ 2483 case 0x31: /* Medium Format Corrupted */ 2484 sdd->sdd_flags |= SDDF_NONFMT; 2485 /* Ignore error */ 2486 break; 2487 2488 /********************************/ 2489 /* more retry */ 2490 /********************************/ 2491 /* MEDIUM or RECOVERED ERROR */ 2492 case 0x10: /* ID CRC Error */ 2493 case 0x12: /* No Address Mark found in ID field */ 2494 case 0x13: /* No Address Mark found in Data field */ 2495 case 0x14: /* No recode found */ 2496 /* H/W or MEDIUM or RECOVERED ERROR */ 2497 case 0x15: /* Seek Positioning Error */ 2498 if (sd_ignore_error) { 2499 sdc->sdc_state = SDCS_NORMAL; 2500 goto check_target_status; 2501 } 2502 /* fall through */ 2503 2504 /* H/W ERROR */ 2505 case 0x01: /* No Index/Address Mark Found signal */ 2506 case 0x02: /* No Seek Complete */ 2507 case 0x06: /* No Track Zero found */ 2508 /* H/W ERROR or RECOVERED ERROR */ 2509 case 0x03: /* Write Fault */ 2510 case 0x08: /* Logical Unit Communication Failure */ 2511 case 0x09: /* Track Following Error */ 2512 case 0x0b: /* Load/Unload Failure */ 2513 case 0x0c: /* Spindle Failure */ 2514 case 0x0d: /* Focus Failure */ 2515 case 0x0e: /* Tracking Failure */ 2516 case 0x0f: /* Drive Initialization Failure */ 2517 sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD|SDCS_REZERO; 2518 2519 scinit(sc, slave, sdd->sdd_sectsize); 2520 /* sc_cdb */ 2521 sc->sc_opcode = SCOP_REZERO; 2522 2523 sddgo(im); 2524 return; 2525 2526 /********************************/ 2527 /* re-allocate & retry */ 2528 /********************************/ 2529 /* MEDIUM or RECOVERED ERROR */ 2530 case 0x11: /* Unrecovered Read Error */ 2531 if (sdc->sdc_state & SDCS_RASREAD) { 2532 sdintr_lostdata: 2533 sdc->sdc_state = 2534 SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA; 2535 im->im_tab.b_active = 2; 2536 scop_rasblk(intr, sc, slave, 2537 SCSI_INTEN, sdd->sdd_badsect); 2538 sdd->sdd_flags &= ~SDDF_VBADSECT; 2539 return; 2540 } 2541 /* fall through */ 2542 2543 /* RECOVERED ERROR */ 2544 case 0x17: /* Recovered read data with retries */ 2545 case 0x18: /* Recovered read data with ECC */ 2546 /* 2547 * set ECC ON & more retry 2548 */ 2549 if (sdc->sdc_firmware & SDCFW_DEFMODE) 2550 goto sdintr_ecc; 2551 2552 if (sdc->sdc_state & SDCS_RASREAD) 2553 goto sdintr_rasblk; 2554 2555 sdc->sdc_state = SDCS_ECC; 2556 goto sdintr_msel_set; 2557 2558 /********************************/ 2559 /* unit start & retry */ 2560 /********************************/ 2561 /* NOT READY */ 2562 case 0x04: /* Drive Not Ready */ 2563 if (sdc->sdc_state & SDCS_ECC) 2564 sdc->sdc_state = SDCS_ECCOFF|SDCS_RETRY; 2565 else 2566 sdc->sdc_state = SDCS_RETRY; 2567 goto sdintr_stst; 2568 2569 /********************************/ 2570 /* retry */ 2571 /********************************/ 2572 /* UNIT ATTENTION */ 2573 case 0x28: /* Medium Changed */ 2574 sdd->sdd_flags &= ~(SDDF_NONFMT 2575 |SDDF_SAMEDSK 2576 |SDDF_REQ_EJECT 2577 |SDDF_XUSE 2578 |SDDF_INHRMV 2579 |SDDF_ERASEOFF); 2580 /* fall through */ 2581 2582 case 0x29: /* Power On or Reset or Bus Device Reset */ 2583 if (sdc->sdc_firmware & SDCFW_RMB) { 2584 /***************************/ 2585 /* medium removable device */ 2586 /***************************/ 2587 sdc->sdc_state = SDCS_PREVRMB; 2588 im->im_tab.b_active = 2; 2589 scop_medrmv(intr, sc, slave, 2590 SCSI_INTEN, SDRMV_PREV); 2591 return; 2592 } 2593 2594 case 0x2a: /* Mode Select Parameter Changed */ 2595 case 0x47: /* SCSI interface bus parity error */ 2596 if (sdc->sdc_state & SDCS_ECC) { 2597 sdc->sdc_state = SDCS_RETRY; 2598 goto sdintr_msel_reset; 2599 } 2600 sdc->sdc_state = SDCS_NORMAL; 2601 goto sdintr_exec; 2602 2603 /********************************/ 2604 /* set error flag */ 2605 /********************************/ 2606 case 0x40: /* RAM failure */ 2607 case 0x41: /* Data Path diagnostic failure */ 2608 case 0x42: /* Power On diagnostic failure */ 2609 2610 case 0xb2: /* Caddy load/eject failed */ 2611 case 0xb4: /* Focus servo failure */ 2612 case 0xb5: /* Spindle servo failure */ 2613 case 0xb6: /* Caddy load mechanism failed */ 2614 goto sdintr_error; 2615 2616 /*MO*/ case 0x80: /* Limit Laser Life */ 2617 /*MO*/ case 0x81: /* Focus Coil Over-current Failure */ 2618 /*MO*/ case 0x82: /* Tracking Coil Over-current Failure */ 2619 /*MO*/ case 0x83: /* Temperature Alarm */ 2620 /*CD*/ /* case 0x80: */ /* Prevent bit is set */ 2621 /*CD*/ /* case 0x81: */ /* Logical unit is reserved */ 2622 /*CD*/ /* case 0x82: */ /* End of usr area encountered */ 2623 /*CD*/ /* case 0x83: */ /* Overlapped commands attempted */ 2624 goto sdintr_error; 2625 2626 default: 2627 /* 2628 * error detect, but what shall we do ? 2629 */ 2630 /* case 0x05: */ /* Drive Not Selected */ 2631 /* case 0x07: */ /* Multiple Drives Selected */ 2632 /* case 0x0a: */ /* No disk */ 2633 /* case 0x1a: */ /* Parameter overrun */ 2634 /* case 0x1b: */ /* Synchronous transfer error */ 2635 /* case 0x1d: */ /* Compare error */ 2636 /* case 0x22: */ /* Illegal function for device type */ 2637 /* case 0x23: */ /* Illegal function for Medium type */ 2638 /* case 0x25: */ /* Illegal LUN */ 2639 /* case 0x27: */ /* Write Protected */ 2640 /* case 0x2b: */ /* Firmware has been downloaded */ 2641 /* case 0x39: */ /* Automatic Reallocation Failure */ 2642 /* case 0x43: */ /* Message Reject Error */ 2643 /* case 0x45: */ /* Selection/Reselection failure */ 2644 /* case 0x48: */ /* Initiator detected error */ 2645 /* case 0x49: */ /* Inappropriate/illegal message */ 2646 /* case 0x60: */ /* COPY: STATUS error */ 2647 /* case 0x85: */ /* Audio address not valid */ 2648 /* case 0xb0: */ /* Caddy not inserted in drive */ 2649 /* case 0xb1: */ /* Unable to recover TOC */ 2650 /* case 0xb3: */ /* CIRC unrecovered data error(L-EC off) */ 2651 /* case 0xc3: */ /* COPY: Illegale CDB length */ 2652 /* case 0xc5: */ /* COPY: Catastrophic error */ 2653 /* case 0xc6: */ /* COPY: Illegal phase change */ 2654 /* case 0xfc: */ /* COPY: MODE SENSE failed */ 2655 2656 /* 2657 * medium error 2658 */ 2659 /* case 0x19: */ /* Defect list error */ 2660 /* case 0x1c: */ /* Primary Defect List not found */ 2661 /* case 0x30: */ /* Incompatible Cartridge */ 2662 /* case 0x32: */ /* No Spare Defect Location Available */ 2663 /* case 0x3a: */ /* Defect List Update Failure */ 2664 /* case 0x3d: */ /* Defect List Not Available */ 2665 goto sdintr_error; 2666 } 2667 /* 2668 * No error detected or ignored. 2669 */ 2670 break; 2671 2672 /************************************************/ 2673 /* */ 2674 /* PREVENT MEDIUM REMOVABLE COMMAND */ 2675 /* */ 2676 /************************************************/ 2677 case SDCS_PREVRMB: 2678 if (tstatus == TGST_CC) { 2679 sdc->sdc_state = SDCS_PREVRMB|SDCS_RSENSE; 2680 goto sdintr_rsense; 2681 } 2682 sdd->sdd_flags |= SDDF_INHRMV; 2683 if (sdc->sdc_state & SDCS_ECC) { 2684 sdc->sdc_state = SDCS_RETRY; 2685 goto sdintr_msel_reset; 2686 } 2687 sdc->sdc_state = SDCS_NORMAL; 2688 goto sdintr_exec; 2689 break; 2690 2691 /****************************************/ 2692 /* */ 2693 /* REZERO done & RETRY COMMAND */ 2694 /* */ 2695 /****************************************/ 2696 case SDCS_ECC|SDCS_ECC_HOLD|SDCS_REZERO: 2697 if (sdc->sdc_firmware & SDCFW_DEFMODE) { 2698 sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD|SDCS_RETRY; 2699 goto sdintr_stst; 2700 } 2701 2702 sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD; 2703 goto sdintr_msel_set; 2704 2705 /********************************/ 2706 /* */ 2707 /* RETRY COMMAND */ 2708 /* */ 2709 /********************************/ 2710 case SDCS_RETRY: 2711 sdc->sdc_state = SDCS_NORMAL; 2712 goto sdintr_exec; 2713 2714 /************************************************/ 2715 /* */ 2716 /* ERROR CORRECTION ON MODE SELECT result */ 2717 /* */ 2718 /************************************************/ 2719 case SDCS_ECC: 2720 if (tstatus != TGST_GOOD) { 2721 printf("sd%d: bad target status 0x%x\n", 2722 unit, sc->sc_tstatus); 2723 goto sdintr_error; 2724 } 2725 sdintr_ecc: 2726 if (bp->b_flags & B_READ) { 2727 sdc->sdc_state = SDCS_ECC|SDCS_RASREAD; 2728 im->im_tab.b_active = 2; 2729 scop_rdwr(intr, sc, slave, SCSI_INTEN, 2730 B_READ, sdwork, 2731 sdd->sdd_badsect, sdd->sdd_sectsize); 2732 return; 2733 } 2734 goto sdintr_rasblk; 2735 2736 /************************************************/ 2737 /* */ 2738 /* READ DATA from BAD BLOCK result */ 2739 /* */ 2740 /************************************************/ 2741 case SDCS_ECC|SDCS_RASREAD: 2742 if (tstatus == TGST_CC) { 2743 sdc->sdc_state = SDCS_ECC|SDCS_RASREAD|SDCS_RSENSE; 2744 goto sdintr_rsense; 2745 } else if (tstatus != TGST_GOOD) { 2746 printf("sd%d: bad target status 0x%x\n", 2747 unit, sc->sc_tstatus); 2748 printf("sd%d: cannot read block\n", unit); 2749 goto sdintr_error; 2750 } 2751 sdintr_rasblk: 2752 if (sdd->sdd_flags & SDDF_WPROTECT) 2753 goto sdintr_error; 2754 sdc->sdc_state = SDCS_ECC|SDCS_RASBLK; 2755 im->im_tab.b_active = 2; 2756 scop_rasblk(intr, sc, slave, SCSI_INTEN, sdd->sdd_badsect); 2757 sdd->sdd_flags &= ~SDDF_VBADSECT; 2758 return; 2759 2760 /****************************************/ 2761 /* */ 2762 /* REASSIGN BLOCK result */ 2763 /* */ 2764 /****************************************/ 2765 case SDCS_ECC|SDCS_RASBLK: 2766 if (tstatus == TGST_CC) { 2767 sdc->sdc_state = SDCS_ECC|SDCS_RASBLK|SDCS_RSENSE; 2768 goto sdintr_rsense; 2769 } else if (tstatus != TGST_GOOD) { 2770 printf("sd%d: bad target status 0x%x\n", 2771 unit, sc->sc_tstatus); 2772 goto sdintr_error; 2773 } 2774 printf("sd%d: block %d is reassigned\n", 2775 unit, sdd->sdd_badsect); 2776 if (bp->b_flags & B_READ) { 2777 sdintr_raswrite: 2778 sdc->sdc_state = SDCS_ECC|SDCS_RASWRITE; 2779 im->im_tab.b_active = 2; 2780 scop_rdwr(intr, sc, slave, SCSI_INTEN, 2781 B_WRITE, sdwork, 2782 sdd->sdd_badsect, sdd->sdd_sectsize); 2783 return; 2784 } 2785 sdc->sdc_state = SDCS_RETRY; 2786 goto sdintr_msel_reset; 2787 2788 /************************************************/ 2789 /* */ 2790 /* WRITE DATA to REASSIGNED BLOCK result */ 2791 /* */ 2792 /************************************************/ 2793 case SDCS_ECC|SDCS_RASWRITE: 2794 if (tstatus == TGST_CC) { 2795 sdc->sdc_state = SDCS_ECC|SDCS_RASWRITE|SDCS_RSENSE; 2796 goto sdintr_rsense; 2797 } else if (tstatus != TGST_GOOD) { 2798 printf("sd%d: bad target status 0x%x\n", 2799 unit, sc->sc_tstatus); 2800 goto sdintr_error; 2801 } 2802 sdc->sdc_state = SDCS_RETRY; 2803 goto sdintr_msel_reset; 2804 2805 /****************************************/ 2806 /* */ 2807 /* reset ECC & RETRY TIMES */ 2808 /* */ 2809 /****************************************/ 2810 case SDCS_ECCOFF|SDCS_RETRY: 2811 sdc->sdc_state = SDCS_RETRY; 2812 goto sdintr_msel_reset; 2813 2814 /********************************************************/ 2815 /* */ 2816 /* READ DATA from BAD BLOCK result in faliure */ 2817 /* */ 2818 /********************************************************/ 2819 case SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA: 2820 if (tstatus == TGST_CC) { 2821 sdc->sdc_state = 2822 SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE; 2823 goto sdintr_rsense; 2824 } else if (tstatus != TGST_GOOD) { 2825 printf("sd%d: rasblk: bad target status 0x%x\n", 2826 unit, sc->sc_tstatus); 2827 goto sdintr_error; 2828 } 2829 bzero(sdwork, sdd->sdd_sectsize); 2830 scop_rdwr(intr, sc, slave, SCSI_INTDIS, 2831 B_WRITE, sdwork, sdd->sdd_badsect, sdd->sdd_sectsize); 2832 printf("sd%d: block %d is reassigned (lost data)\n", 2833 unit, sdd->sdd_badsect); 2834 goto sdintr_error; 2835 2836 /****************************************/ 2837 /* */ 2838 /* issue START UNIT command */ 2839 /* */ 2840 /****************************************/ 2841 case SDCS_ECC|SDCS_ECC_HOLD: 2842 /* 2843 * Drive not ready... so start.. 2844 */ 2845 sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD|SDCS_RETRY; 2846 sdintr_stst: 2847 timeout(delay_start, (caddr_t)ii, hz); 2848 return; 2849 2850 /****************************************/ 2851 /* */ 2852 /* RETRY with ECC & more RETRYS */ 2853 /* */ 2854 /****************************************/ 2855 case SDCS_ECC|SDCS_ECC_HOLD|SDCS_RETRY: 2856 sdc->sdc_state = SDCS_ECCOFF; 2857 sdintr_exec: 2858 if (sdc->sdc_countcc++ > MAXRETRYCNT) 2859 goto sdintr_error; 2860 sdexec(bp); 2861 return; 2862 2863 /****************************************/ 2864 /* */ 2865 /* reset ECC & RETRY TIMES */ 2866 /* */ 2867 /****************************************/ 2868 case SDCS_ECCOFF: 2869 if (tstatus == TGST_CC) { 2870 sdc->sdc_state = SDCS_ECCOFF|SDCS_RSENSE; 2871 goto sdintr_rsense; 2872 } else if (tstatus != TGST_GOOD) { 2873 printf("sd%d: bad target status 0x%x\n", 2874 unit, sc->sc_tstatus); 2875 goto sdintr_error; 2876 } 2877 sdc->sdc_state = SDCS_NORMAL; 2878 goto sdintr_msel_reset; 2879 2880 sdintr_msel_set: 2881 /* 2882 * set more ERROR RECOVERY PARAMETERS 2883 */ 2884 if ((erp_page = sdi->max_ERP_page) == NULL) 2885 goto check_target_status; 2886 bzero((caddr_t)sc->sc_param, 4); 2887 len = *(erp_page + 1) + 2; 2888 bcopy(erp_page, &sc->sc_param[4], len); 2889 2890 im->im_tab.b_active = 2; 2891 scop_mselect(intr, sc, slave, SCSI_INTEN, 2892 (SDM_PF<<24) + len +4, (caddr_t)0); 2893 return; 2894 2895 sdintr_msel_reset: 2896 if (sdc->sdc_firmware & SDCFW_DEFMODE) 2897 goto sdintr_exec; 2898 2899 /* 2900 * set normal ERROR RECOVERY PARAMETERS 2901 */ 2902 erp_page = sdi->ERP_page; 2903 bzero((caddr_t)sc->sc_param, 4); 2904 len = *(erp_page + 1) + 2; 2905 bcopy(erp_page, &sc->sc_param[4], len); 2906 2907 im->im_tab.b_active = 2; 2908 scop_mselect(intr, sc, slave, SCSI_INTEN, 2909 (SDM_PF<<24) + len +4, (caddr_t)0); 2910 return; 2911 2912 sdintr_error: 2913 bp->b_flags |= B_ERROR; 2914 if (sdc->sdc_state & SDCS_ECC) { 2915 sdc->sdc_state = SDCS_NORMAL; 2916 goto sdintr_msel_reset; 2917 } 2918 break; 2919 2920 /* 2921 * UNKNOWN STATUS 2922 */ 2923 default: 2924 printf("sd%d: unknown status (0x%x)\n", unit, sdc->sdc_state); 2925 goto sdintr_error; 2926 } 2927 2928 sdintr_done: 2929 2930 if (bp->b_flags & B_ERROR) { 2931 printf("%s%d%c: hard error sn%d ", "sd", 2932 minor(bp->b_dev) >> 3, 'a'+(minor(bp->b_dev)&07), bp->b_blkno); 2933 printf("\n"); 2934 } 2935 sdd->sdd_lastblk = dkblock(bp) + btodb(bp->b_bcount - bp->b_resid); 2936 sdc->sdc_countcc = 0; 2937 sdc->sdc_retrycnt = 0; 2938 sdd->sdd_flags &= ~SDDF_VBADSECT; 2939 2940 if (im->im_tab.b_active) { 2941 im->im_tab.b_active = 0; 2942 im->im_tab.b_errcnt = 0; 2943 im->im_tab.b_actf = dp->b_forw; 2944 dp->b_active = 0; 2945 dp->b_errcnt = 0; 2946 dp->b_actf = bp->av_forw; 2947 if (bp == &csdbuf[unit]) { 2948 register struct scsi *ksc = &kernscsi[unit]; 2949 /* copy result */ 2950 bcopy((caddr_t)sc, (caddr_t)ksc, sizeof(struct scsi)); 2951 } 2952 2953 iodone(bp); 2954 2955 /* 2956 * If this unit has more work to do, 2957 * then start it up right away. 2958 */ 2959 if (dp->b_actf) 2960 sdustart(ii); 2961 } 2962 as &= ~(1 << slave); 2963 2964 sdc->sdc_state = SDCS_NORMAL; 2965 2966 /* 2967 * UNLOCK SCSI access 2968 */ 2969 sdc->sdc_firmware &= ~SDCFW_BUSY; 2970 2971 start: 2972 /* 2973 * Process other units which need attention. 2974 * For each unit which needs attention, call 2975 * the unit start routine to place the slave 2976 * on the controller device queue. 2977 */ 2978 sdc->sdc_softas = 0; 2979 while (unit = ffs(as)) { 2980 unit--; 2981 as &= ~(1 << unit); 2982 sdustart(sdip[im->im_ctlr][unit]); 2983 } 2984 /* 2985 * If the controller is not transferring, 2986 * but there are devices ready to transfer, 2987 * start the controller. 2988 */ 2989 if (im->im_tab.b_actf && im->im_tab.b_active == 0) 2990 (void) sdstart(im); 2991 } 2992 2993 wait_re_init_done(bp) 2994 register struct buf *bp; 2995 { 2996 if (re_init_done >= 2) 2997 sdexec(bp); 2998 else 2999 timeout(wait_re_init_done, bp, 10*hz); 3000 } 3001 3002 delay_start(ii) 3003 struct iop/**/_device *ii; 3004 { 3005 ii->ii_mi->im_tab.b_active = 2; 3006 scop_stst(ii->ii_intr, get_scsi(ii->ii_intr), ii->ii_slave, 3007 SCSI_INTEN, SDSS_START); 3008 } 3009 3010 delay_medrmv(ii) 3011 struct iop/**/_device *ii; 3012 { 3013 ii->ii_mi->im_tab.b_active = 2; 3014 scop_medrmv(ii->ii_intr, get_scsi(ii->ii_intr), ii->ii_slave, 3015 SCSI_INTEN, SDRMV_PREV); 3016 } 3017 3018 sderrordisp(rsen_data, ii) 3019 u_char *rsen_data; 3020 struct iop/**/_device *ii; 3021 { 3022 register struct sc_extnd *sce; 3023 register struct sdc_softc *sdc; 3024 register struct sdd_softc *sdd; 3025 register int unit; 3026 register int code; 3027 struct sc_nextnd *scn; 3028 struct msg_list *ml; 3029 3030 unit = ii->ii_unit; 3031 sdc = &sdc_softc[ii->ii_ctlr]; 3032 sdd = &sdd_softc[unit]; 3033 3034 sce = (struct sc_extnd *)rsen_data; 3035 3036 if (sce->sce_extend == 0x70) { 3037 /* 3038 * Extended Sense data 3039 */ 3040 code = sce->sce_sdecode; 3041 3042 if (code & 0x80) 3043 ml = ecodelist_mo; 3044 else 3045 ml = ecodelist; 3046 3047 if (sce->sce_advalid) { 3048 if ((sdd->sdd_flags & SDDF_VBADSECT) == 0) { 3049 #ifdef mips 3050 sdd->sdd_badsect = (sce->sce_infob1 << 24) + 3051 (sce->sce_infob2 << 16) + 3052 (sce->sce_infob3 << 8) + 3053 (sce->sce_infob4); 3054 #else 3055 sdd->sdd_badsect = *((int *)&sce->sce_infob1); 3056 #endif 3057 sdd->sdd_flags |= SDDF_VBADSECT; 3058 } 3059 } 3060 3061 if (!rsense_msg_disp && !isdispmsg(code, ml, sdc->sdc_countcc)) 3062 return (code); 3063 3064 if (sce->sce_advalid) { 3065 int sn; 3066 #ifdef mips 3067 sn = (sce->sce_infob1 << 24) + 3068 (sce->sce_infob2 << 16) + 3069 (sce->sce_infob3 << 8) + 3070 (sce->sce_infob4); 3071 #else 3072 sn = *((int *)&sce->sce_infob1); 3073 #endif 3074 if (sce->sce_addlen >= 5) { 3075 printf("sd%d(sn %d): skey=0x%x, code=0x%x\n", 3076 unit, sn, sce->sce_skey, code); 3077 } else { 3078 printf("sd%d(sn %d): skey=0x%x\n", 3079 unit, sn, sce->sce_skey); 3080 } 3081 } else { 3082 if (sce->sce_addlen >= 5) 3083 printf("sd%d: skey=0x%x, code=0x%x\n", 3084 unit, sce->sce_skey, code); 3085 else 3086 printf("sd%d: skey=0x%x\n", 3087 unit, sce->sce_skey); 3088 } 3089 if (sce->sce_addlen >= 6) 3090 printf("sd%d: ASCQ=0x%x\n", unit, sce->sce_ascq); 3091 { 3092 u_char *p; 3093 int len; 3094 3095 len = 8 + sce->sce_addlen; 3096 if (len > RSEN_CNT) 3097 len = RSEN_CNT; 3098 p = (u_char *)sce; 3099 printf("sd%d: ", unit); 3100 while (len--) 3101 printf("%x ", *p++); 3102 printf("\n"); 3103 } 3104 } else { 3105 /* 3106 * Non-extended Sense data 3107 */ 3108 scn = (struct sc_nextnd *)rsen_data; 3109 3110 code = scn->scn_ecode; 3111 ml = ecodelist; 3112 if (sce->sce_advalid) { 3113 if ((sdd->sdd_flags & SDDF_VBADSECT) == 0) { 3114 sdd->sdd_badsect = scn->scn_secno; 3115 sdd->sdd_flags |= SDDF_VBADSECT; 3116 } 3117 } 3118 if (rsense_msg_disp || isdispmsg(code, ml, sdc->sdc_countcc)) { 3119 if (sce->sce_advalid) 3120 printf("sd%d(sn %d): code=0x%x\n", 3121 unit, scn->scn_secno, code); 3122 else 3123 printf("sd%d: code=0x%x\n", unit, code); 3124 } 3125 } 3126 return (code); 3127 } 3128 3129 void 3130 sdminphys(bp) 3131 struct buf *bp; 3132 { 3133 if (bp->b_bcount > MAXSDPHYS) 3134 bp->b_bcount = MAXSDPHYS; 3135 } 3136 3137 3138 #define sdphysio physio 3139 3140 sdread(dev, uio, flag) 3141 register dev_t dev; 3142 struct uio *uio; 3143 int flag; 3144 { 3145 register struct iop/**/_device *ii; 3146 register int unit; 3147 3148 unit = dev2unit(dev); 3149 if (unit >= nsd || (ii = sddinfo[unit]) == 0) 3150 return (ENXIO); 3151 3152 return (sdphysio(sdstrategy, &rsdbuf[unit], dev, B_READ, sdminphys, uio)); 3153 } 3154 3155 sdwrite(dev, uio, flag) 3156 register dev_t dev; 3157 struct uio *uio; 3158 int flag; 3159 { 3160 register struct iop/**/_device *ii; 3161 register int unit; 3162 3163 unit = dev2unit(dev); 3164 if (unit >= nsd || (ii = sddinfo[unit]) == 0) 3165 return (ENXIO); 3166 3167 return (sdphysio(sdstrategy, &rsdbuf[unit], dev, B_WRITE, sdminphys, uio)); 3168 } 3169 3170 #define MAXBL 256 3171 3172 /*ARGSUSED*/ 3173 sdioctl(dev, cmd, data, flag) 3174 dev_t dev; 3175 int cmd; 3176 caddr_t data; 3177 int flag; 3178 { 3179 register struct iop/**/_device *ii; 3180 register struct sc_ureq *scu; 3181 register struct sdst *st; 3182 register struct scsi *sc; 3183 register int unit; 3184 register int ctlr; 3185 register int slave; 3186 struct sdc_softc *sdc; 3187 struct sdd_softc *sdd; 3188 struct Partinfo *pi; 3189 struct dkst *di; 3190 struct buf *bp; 3191 struct sddevinfo *sdi; 3192 struct sdst *stp; 3193 struct scsi uscsi; 3194 int error; 3195 int i; 3196 int s; 3197 int tstatus; 3198 char *p; 3199 int blkno, count; 3200 3201 unit = dev2unit(dev); 3202 if (unit >= nsd || (ii = sddinfo[unit]) == 0 || ii->ii_alive == 0) 3203 return (ENXIO); 3204 3205 slave = ii->ii_slave; 3206 ctlr = ii->ii_ctlr; 3207 sdc = &sdc_softc[ctlr]; 3208 sdd = &sdd_softc[unit]; 3209 sc = &uscsi; 3210 3211 error = 0; 3212 switch (cmd) { 3213 3214 case DIOCWLABEL: 3215 if (*(int *)data & SD_F_ENW) 3216 ii->ii_flags |= SD_F_ENW; 3217 else 3218 ii->ii_flags &= ~SD_F_ENW; 3219 break; 3220 3221 case DIOCGDINFO: 3222 *(struct disklabel *)data = sdlabel[unit]; 3223 break; 3224 3225 case DIOCSDINFO: 3226 sdlabel[unit] = *(struct disklabel *)data; 3227 disklabel2sdst(unit, &sdlabel[unit], &sdstdrv[unit]); 3228 break; 3229 3230 case DIOCWDINFO: 3231 case DKIOCRGEOM: 3232 switch (cmd) { 3233 case DKIOCRGEOM: 3234 st = &sdstdrv[unit]; 3235 sdi = &sddevinfo[ii->ii_type]; 3236 stp = sdi->sdstp; 3237 3238 st->ncyl = stp->ncyl; /* # cylinders / drive */ 3239 st->ntrak = stp->ntrak; /* # tracks / cylinder */ 3240 st->nsect = stp->nsect; /* # sectors / track */ 3241 st->rps = stp->rps; /* # revolutions / second */ 3242 3243 sdst2disklabel(unit, st, &sdlabel[unit]); 3244 3245 if (*(int *)data == RGEOM_SDINFO) 3246 goto done; 3247 3248 break; 3249 3250 case DIOCWDINFO: 3251 sdlabel[unit] = *(struct disklabel *)data; 3252 3253 break; 3254 } 3255 3256 /* 3257 * Common code for DIOCWDINFO and DKIOCRGEOM 3258 */ 3259 3260 /**** READ sector 0 ****/ 3261 /* 3262 * LOCK sdtmp buffer 3263 */ 3264 s = splclock(); 3265 while (sdtmp_stat & B_BUSY) { 3266 sdtmp_stat |= B_WANTED; 3267 sleep((caddr_t)sdtmp, PRIBIO); 3268 } 3269 sdtmp_stat |= B_BUSY; 3270 splx(s); 3271 3272 bzero(sdtmp, DEV_BSIZE); 3273 3274 if ((sdd->sdd_flags & SDDF_NONFMT) == 0) { 3275 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 3276 uscsi.sc_cpoint = sdtmp; 3277 uscsi.sc_ctrnscnt = DEV_BSIZE; 3278 uscsi.sc_opcode = SCOP_READ; 3279 uscsi.sc_lad = 0; 3280 uscsi.sc_count = 1; 3281 error = sdcmd(dev, &uscsi); 3282 } else { 3283 error = EIO; 3284 } 3285 3286 if (error) { 3287 /* 3288 * UNLOCK sdtmp buffer 3289 */ 3290 s = splclock(); 3291 if (sdtmp_stat & B_WANTED) 3292 wakeup((caddr_t)sdtmp); 3293 sdtmp_stat &= ~(B_BUSY|B_WANTED); 3294 splx(s); 3295 3296 break; 3297 } 3298 3299 *(struct disklabel *)(sdtmp + LABELOFFSET) = sdlabel[unit]; 3300 disklabel2diskinfo(unit, &sdlabel[unit], 3301 &((struct firstsector *)sdtmp)->diskinfo); 3302 3303 /**** WRITE sector 0 ****/ 3304 3305 if (error == 0) { 3306 if ((sdd->sdd_flags & SDDF_NONFMT) == 0) { 3307 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 3308 uscsi.sc_cpoint = sdtmp; 3309 uscsi.sc_ctrnscnt = DEV_BSIZE; 3310 uscsi.sc_opcode = SCOP_WRITE; 3311 3312 uscsi.sc_lad = 0; 3313 uscsi.sc_count = 1; 3314 3315 error = sdcmd(dev, &uscsi); 3316 } else 3317 error = EIO; 3318 } 3319 3320 /* 3321 * UNLOCK sdtmp buffer 3322 */ 3323 s = splclock(); 3324 if (sdtmp_stat & B_WANTED) 3325 wakeup((caddr_t)sdtmp); 3326 sdtmp_stat &= ~(B_BUSY|B_WANTED); 3327 splx(s); 3328 3329 disklabel2sdst(unit, &sdlabel[unit], &sdstdrv[unit]); 3330 3331 break; 3332 3333 case DKIOCGGEOM: 3334 st = &sdstdrv[unit]; 3335 di = (struct dkst *)data; 3336 3337 di->dks_ncyl = st->ncyl; /* # cylinders / drive */ 3338 di->dks_ntrak = st->ntrak; /* # tracks / cylinder */ 3339 di->dks_nsect = st->nsect; /* # sectors / track */ 3340 di->dks_rps = st->rps; /* # revolutions / second */ 3341 3342 break; 3343 3344 case DKIOCSGEOM: 3345 st = &sdstdrv[unit]; 3346 di = (struct dkst *)data; 3347 3348 st->ncyl = di->dks_ncyl; /* # cylinders / drive */ 3349 st->ntrak = di->dks_ntrak; /* # tracks / cylinder */ 3350 st->nsect = di->dks_nsect; /* # sectors / track */ 3351 st->rps = di->dks_rps; /* # revolutions / second */ 3352 3353 sdst2disklabel(unit, st, &sdlabel[unit]); 3354 break; 3355 3356 case DKIOCGPART: 3357 case DKIOCSPART: 3358 /* 3359 * partition information 3360 */ 3361 st = &sdstdrv[unit]; 3362 pi = (struct Partinfo *)data; 3363 3364 if (cmd == DKIOCGPART) { 3365 pi->dp_nblocks = st->sizes[dev2part(dev)].sd_nblocks; 3366 pi->dp_blkoff = st->sizes[dev2part(dev)].sd_blkoff; 3367 } else { 3368 st->sizes[dev2part(dev)].sd_nblocks = pi->dp_nblocks; 3369 st->sizes[dev2part(dev)].sd_blkoff = pi->dp_blkoff; 3370 3371 sdst2disklabel(unit, st, &sdlabel[unit]); 3372 } 3373 break; 3374 3375 case DKIOCGUNIT: 3376 *(int *)data = slave; 3377 break; 3378 3379 case DKIOCGCHAN: 3380 *(int *)data = ii->ii_intr; 3381 break; 3382 3383 case DKIOCSEEK: 3384 scinit(sc, slave, sdd->sdd_sectsize); 3385 sc->sc_opcode = SCOP_SEEK; 3386 sc->sc_lad = *(int *)data; 3387 3388 (void) sdcmd(dev, sc); 3389 tstatus = sc->sc_tstatus & TGSTMASK; 3390 if ((sc->sc_istatus != INST_EP) || (tstatus != TGST_GOOD)) 3391 error = ESPIPE; 3392 break; 3393 3394 case DKIOCRSEC0: 3395 case DKIOCRBOOT1: 3396 case DKIOCRBOOT: 3397 if (sdd->sdd_flags & SDDF_NONFMT) { 3398 error = EIO; 3399 break; 3400 } 3401 switch (cmd) { 3402 3403 case DKIOCRSEC0: 3404 blkno = 0; 3405 count = 1; 3406 break; 3407 3408 case DKIOCRBOOT1: 3409 blkno = 1; 3410 count = 15; 3411 break; 3412 3413 default: 3414 blkno = 0; 3415 count = 16; 3416 } 3417 p = (char *)*(int *)data; 3418 for (i = 0; !error && i < count; i++) { 3419 s = splclock(); 3420 while (sdtmp_stat & B_BUSY) { 3421 sdtmp_stat |= B_WANTED; 3422 sleep((caddr_t)sdtmp, PRIBIO); 3423 } 3424 sdtmp_stat |= B_BUSY; 3425 splx(s); 3426 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 3427 uscsi.sc_cpoint = sdtmp; 3428 uscsi.sc_ctrnscnt = DEV_BSIZE; 3429 uscsi.sc_opcode = SCOP_READ; 3430 uscsi.sc_lad = blkno; 3431 uscsi.sc_count = 1; 3432 if (error = sdcmd(dev, &uscsi)) 3433 goto dkior_done; 3434 if (error = copyout(sdtmp, p, DEV_BSIZE)) 3435 goto dkior_done; 3436 blkno++; 3437 p += DEV_BSIZE; 3438 3439 dkior_done: 3440 s = splclock(); 3441 if (sdtmp_stat & B_WANTED) 3442 wakeup((caddr_t)sdtmp); 3443 sdtmp_stat &= ~(B_BUSY|B_WANTED); 3444 splx(s); 3445 } 3446 break; 3447 3448 case DKIOCWSEC0: 3449 case DKIOCWBOOT1: 3450 case DKIOCWBOOT: 3451 if (sdd->sdd_flags & SDDF_NONFMT) { 3452 error = EIO; 3453 break; 3454 } 3455 switch (cmd) { 3456 3457 case DKIOCWSEC0: 3458 blkno = 0; 3459 count = 1; 3460 break; 3461 3462 case DKIOCWBOOT1: 3463 blkno = 1; 3464 count = 15; 3465 break; 3466 3467 default: 3468 blkno = 0; 3469 count = 16; 3470 } 3471 p = (char *)*(int *)data; 3472 for (i = 0; !error && i < count; i++) { 3473 s = splclock(); 3474 while (sdtmp_stat & B_BUSY) { 3475 sdtmp_stat |= B_WANTED; 3476 sleep(sdtmp, PRIBIO); 3477 } 3478 sdtmp_stat |= B_BUSY; 3479 splx(s); 3480 if (error = copyin(p, sdtmp, DEV_BSIZE)) 3481 goto dkiow_done; 3482 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 3483 uscsi.sc_cpoint = sdtmp; 3484 uscsi.sc_ctrnscnt = DEV_BSIZE; 3485 uscsi.sc_opcode = SCOP_WRITE; 3486 uscsi.sc_lad = blkno; 3487 uscsi.sc_count = 1; 3488 if (error = sdcmd(dev, &uscsi)) 3489 goto dkiow_done; 3490 blkno++; 3491 p += DEV_BSIZE; 3492 3493 dkiow_done: 3494 s = splclock(); 3495 if (sdtmp_stat & B_WANTED) 3496 wakeup(sdtmp); 3497 sdtmp_stat &= ~(B_BUSY|B_WANTED); 3498 splx(s); 3499 } 3500 break; 3501 3502 case SDIOC_PRVRMV: 3503 case SDIOC_ALWRMV: 3504 /* 3505 * prevent/allow medium removal 3506 */ 3507 scinit(sc, ii->ii_slave, sdd->sdd_sectsize); 3508 sc->sc_opcode = SCOP_MEDRMV; 3509 sc->sc_count = (cmd==SDIOC_PRVRMV)? SDRMV_PREV : SDRMV_ALLOW; 3510 if (cmd == SDIOC_PRVRMV) 3511 sdd->sdd_flags |= SDDF_INHRMV; 3512 else 3513 sdd->sdd_flags &= ~SDDF_INHRMV; 3514 3515 error = sdcmd(dev, sc); 3516 break; 3517 3518 case SDIOC_SXUSE: 3519 if (isalone(unit) != ONLY_ONE) 3520 return (EBUSY); 3521 sdd->sdd_flags |= SDDF_XUSE; 3522 break; 3523 3524 case SDIOC_RXUSE: 3525 sdd->sdd_flags &= ~SDDF_XUSE; 3526 break; 3527 3528 case SDIOC_ERSON: 3529 sdd->sdd_flags &= ~SDDF_ERASEOFF; 3530 break; 3531 3532 case SDIOC_ERSOFF: 3533 if ((sdd->sdd_flags & SDDF_XUSE) != 0) 3534 return (EBUSY); 3535 sdd->sdd_flags |= SDDF_ERASEOFF; 3536 sdd->sdd_flags &= ~SDDF_NONFMT; 3537 break; 3538 3539 case SDIOC_FORMAT: 3540 /* 3541 * format unit 3542 */ 3543 if ((flag & FWRITE) == 0) 3544 return (EINVAL); 3545 if (isalone(unit) != ONLY_ONE) 3546 return (EBUSY); 3547 sdd->sdd_flags |= SDDF_XUSE; 3548 sdd->sdd_flags &= ~(SDDF_NONFMT|SDDF_FMTDONE|SDDF_SAMEDSK); 3549 scinit(sc, ii->ii_slave, sdd->sdd_sectsize); 3550 sc->sc_ctrnscnt = 4; 3551 sc->sc_opcode = SCOP_FMT; 3552 3553 sc->sc_lad = ((sddevinfo[ii->ii_type].fmt_opts & FMT_DLFMT) 3554 | SDF_FMTDAT) << 16; 3555 3556 switch (sddevinfo[ii->ii_type].type) { 3557 3558 case SMO_S501: 3559 case SMO_S501_ISO: 3560 case SMO_S501_ISO2: 3561 sc->sc_lad |= ((SDF_MKCDA|SDF_MKPLST) << 8); 3562 break; 3563 3564 default: 3565 break; 3566 } 3567 3568 { 3569 struct fmt_data *fdata = (struct fmt_data *)data; 3570 3571 error = copyin((caddr_t)fdata->dlh, sc->sc_param, 4); 3572 if (error != 0) { 3573 sdd->sdd_flags &= ~SDDF_XUSE; 3574 break; 3575 } 3576 if (fdata->noglist) 3577 sc->sc_lad |= (SDF_CMPLST<<16); 3578 } 3579 3580 if (sdd->sdd_flags & SDDF_ERASEOFF) 3581 sc->sc_ctrl = 0x40; 3582 3583 error = sdcmd(dev, sc); 3584 sdd->sdd_flags &= ~SDDF_XUSE; 3585 break; 3586 3587 case SDIOC_FORMAT2: 3588 /* 3589 * format unit 3590 */ 3591 if ((flag & FWRITE) == 0) 3592 return (EINVAL); 3593 if (isalone(unit) != ONLY_ONE) 3594 return (EBUSY); 3595 sdd->sdd_flags |= SDDF_XUSE; 3596 sdd->sdd_flags &= ~(SDDF_NONFMT|SDDF_FMTDONE|SDDF_SAMEDSK); 3597 3598 scu = (struct sc_ureq *)data; 3599 error = sd_scu_exec(dev, scu, sc); 3600 sdd->sdd_flags &= ~SDDF_XUSE; 3601 break; 3602 3603 case SDIOC_GSTOPT: 3604 case SDIOC_SSTOPT: 3605 /* 3606 * get/set stop-unit timer 3607 */ 3608 if (cmd == SDIOC_GSTOPT) 3609 *(int *)data = sdd->sdd_stoptime; 3610 else { 3611 if (*(int *)data == 0) 3612 return (EINVAL); 3613 sdd->sdd_stoptime = *(int *)data; 3614 } 3615 break; 3616 3617 case SDIOC_SEJECT: 3618 /* 3619 * set auto eject flag 3620 */ 3621 sdd->sdd_flags |= SDDF_REQ_EJECT; 3622 break; 3623 3624 case SDIOC_GFLAGS: 3625 /* 3626 * get ii->ii_flags 3627 */ 3628 *(int *)data = ii->ii_flags; 3629 break; 3630 3631 case SDIOC_SFLAGS: 3632 /* 3633 * set ii->ii_flags 3634 */ 3635 ii->ii_flags = *(int *)data; 3636 break; 3637 3638 case SDIOC_RASBLK: 3639 /* 3640 * reassign block 3641 */ 3642 { 3643 struct sc_rab *sca = (struct sc_rab *)sc->sc_param; 3644 3645 scinit(sc, ii->ii_slave, sdd->sdd_sectsize); 3646 sc->sc_opcode = SCOP_RASBLK; 3647 sc->sc_ctrnscnt = 8; 3648 3649 sca->sca_dllen = 4; 3650 sca->sca_dlad[0] = *(int *)data; 3651 3652 error = sdcmd(dev, sc); 3653 } 3654 break; 3655 3656 case SDIOC_GNICKNAME: 3657 { 3658 int len; 3659 3660 len = strlen(sddevinfo[ii->ii_type].call_name); 3661 3662 if (len > IOCPARM_MASK) 3663 len = IOCPARM_MASK; 3664 3665 error = copyout( 3666 (caddr_t) sddevinfo[ii->ii_type].call_name, 3667 (caddr_t) *(int *)data, 3668 len); 3669 } 3670 break; 3671 3672 case SDIOC_GTYPINDEX: 3673 *(int *)data = (int)ii->ii_type; 3674 break; 3675 3676 #ifdef SDIOC_SSYNCPARAM 3677 case SDIOC_SSYNCPARAM: 3678 { 3679 struct sync_param *syncp; 3680 3681 syncp = (struct sync_param *)data; 3682 scinit(sc, ii->ii_slave, sdd->sdd_sectsize); 3683 sc->sc_opcode = SCOP_TST; 3684 sc->sc_message = MSG_EXTND; /* extended message */ 3685 sc->sc_param[0] = MSG_EXTND; 3686 sc->sc_param[1] = 0x03; 3687 sc->sc_param[2] = 0x01; /* synchronous transfer */ 3688 sc->sc_param[3] = syncp->tr_period; /* transfer period */ 3689 sc->sc_param[4] = syncp->tr_offset; /* REQ offset */ 3690 3691 (void) sdcmd(dev, sc); 3692 3693 syncp = &sd_sync_param[unit]; 3694 syncp->tr_period = sc->sc_param[3]; 3695 syncp->tr_offset = sc->sc_param[4]; 3696 3697 if (syncp->tr_offset) 3698 sdd->sdd_flags |= SDDF_SYNCTR; 3699 else 3700 sdd->sdd_flags &= ~SDDF_SYNCTR; 3701 } 3702 break; 3703 3704 case SDIOC_GSYNCPARAM: 3705 { 3706 struct sync_param *syncp = (struct sync_param *)data; 3707 3708 syncp->tr_period = sd_sync_param[unit].tr_period; 3709 syncp->tr_offset = sd_sync_param[unit].tr_offset; 3710 } 3711 break; 3712 #endif /* SDIOC_SSYNCPARAM */ 3713 3714 case MTIOCTOP: 3715 { 3716 register struct mtop *mtop = (struct mtop *)data; 3717 register int lba; 3718 int rest; 3719 int blength; 3720 3721 switch (mtop->mt_op) { 3722 3723 case MTOFFL: 3724 /* 3725 * set auto eject flag 3726 */ 3727 sdd->sdd_flags |= SDDF_REQ_EJECT; 3728 break; 3729 3730 #ifdef MTERASE 3731 case MTERASE: 3732 if (isalone(unit) != ONLY_ONE) 3733 return (EBUSY); 3734 sdd->sdd_flags |= SDDF_XUSE; 3735 st = &sdstdrv[unit]; 3736 /* 3737 * MO disk erase 3738 * block 0 to end (C partition) 3739 */ 3740 lba = 0; 3741 rest = sdd->sdd_nsect; /* C part size */ 3742 while (rest > 0) { 3743 blength = (rest > MAXBL)? MAXBL : rest; 3744 scinit(sc, ii->ii_slave, 3745 sdd->sdd_sectsize); 3746 sc->sc_opcode = SCOP_MOERASE; 3747 sc->sc_lad = lba; 3748 sc->sc_count = (blength % MAXBL); 3749 3750 (void) sdcmd(dev, sc); 3751 lba += blength; 3752 rest -= blength; 3753 } 3754 sdd->sdd_flags &= ~SDDF_XUSE; 3755 break; 3756 #endif /* MTERASE */ 3757 3758 default: 3759 return (EINVAL); 3760 } 3761 } 3762 break; 3763 3764 case SCSIIOCCMD: 3765 scu = (struct sc_ureq *)data; 3766 if ((scu->scu_count > 0) && scu->scu_addr) { 3767 if (useracc(scu->scu_addr, scu->scu_count, B_WRITE) 3768 == NULL) { 3769 error = EFAULT; 3770 break; 3771 } 3772 } 3773 error = sd_scu_exec(dev, scu, sc); 3774 break; 3775 3776 3777 case SDIOC_INQUIRY: 3778 /* 3779 * LOCK sdtmp buffer 3780 */ 3781 s = splclock(); 3782 while (sdtmp_stat & B_BUSY) { 3783 sdtmp_stat |= B_WANTED; 3784 sleep((caddr_t)sdtmp, PRIBIO); 3785 } 3786 sdtmp_stat |= B_BUSY; 3787 splx(s); 3788 3789 bzero((caddr_t)sdtmp, sizeof(struct sc_inq)); 3790 scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); 3791 uscsi.sc_cpoint = sdtmp; 3792 uscsi.sc_ctrnscnt = sizeof(struct sc_inq); 3793 uscsi.sc_opcode = SCOP_INQUIRY; 3794 uscsi.sc_count = sizeof(struct sc_inq); 3795 3796 if ((error = sdcmd(dev, &uscsi)) == 0) 3797 bcopy((caddr_t)sdtmp, data, sizeof(struct sc_inq)); 3798 /* 3799 * UNLOCK open 3800 */ 3801 s = splclock(); 3802 if (sdtmp_stat & B_WANTED) 3803 wakeup((caddr_t)sdtmp); 3804 sdtmp_stat &= ~(B_BUSY|B_WANTED); 3805 splx(s); 3806 break; 3807 3808 3809 case SCSIIOCGTIMEO: 3810 *(int *)data = sdc->sdc_timeo; 3811 break; 3812 3813 case SCSIIOCSTIMEO: 3814 if (*(int *)data == 0) 3815 return (EINVAL); 3816 sdc->sdc_timeo = *(int *)data; 3817 sdc->sdc_wticks = 0; 3818 break; 3819 3820 default: 3821 error = EINVAL; 3822 break; 3823 } 3824 3825 done: 3826 return (error); 3827 } 3828 3829 static 3830 sd_scu_exec(dev, scu, sc) 3831 dev_t dev; 3832 register struct sc_ureq *scu; 3833 register struct scsi *sc; 3834 { 3835 struct sdd_softc *sdd; 3836 int error; 3837 3838 sdd = &sdd_softc[dev2unit(dev)]; 3839 3840 if (((scu->scu_identify & MSG_IDENT) == 0) 3841 || (scu->scu_identify & ~(MSG_IDENT|IDT_DISCON|IDT_DRMASK)) 3842 || (scu->scu_addr && (scu->scu_bytesec == 0))) { 3843 return (EINVAL); 3844 } 3845 3846 bzero((caddr_t)sc, sizeof(struct scsi)); 3847 sc->sc_tstatus = scu->scu_tstatus; 3848 sc->sc_identify = scu->scu_identify; 3849 sc->sc_message = scu->scu_message; 3850 sc->sc_bytesec = scu->scu_bytesec; 3851 sc->sc_cpoint = scu->scu_addr; 3852 sc->sc_ctrnscnt = scu->scu_count; 3853 bcopy((caddr_t)scu->scu_cdb, &sc->sc_cdb, sizeof(sc->sc_cdb)); 3854 3855 bcopy((caddr_t)scu->scu_param, (caddr_t)sc->sc_param, 3856 sizeof(sc->sc_param)); 3857 3858 sdd->sdd_flags |= SDDF_SKIPCHECK; 3859 error = sdcmd(dev, sc); 3860 sdd->sdd_flags &= ~SDDF_SKIPCHECK; 3861 3862 scu->scu_istatus = sc->sc_istatus; 3863 scu->scu_tstatus = sc->sc_tstatus; 3864 scu->scu_message = sc->sc_message; 3865 bcopy((caddr_t)sc->sc_param, (caddr_t)scu->scu_param, 3866 sizeof(sc->sc_param)); 3867 return (error); 3868 } 3869 3870 /*ARGSUSED*/ 3871 sddump(dev) 3872 dev_t dev; 3873 { 3874 return (ENXIO); 3875 } 3876 3877 sdsize(dev) 3878 register dev_t dev; 3879 { 3880 register struct iop/**/_device *ii; 3881 register struct sdd_softc *sdd; 3882 register struct sdst *st; 3883 register int unit; 3884 int i; 3885 3886 unit = dev2unit(dev); 3887 if (unit >= nsd || (ii = sddinfo[unit]) == 0 || ii->ii_alive == 0) 3888 return (-1); 3889 3890 sdd = &sdd_softc[unit]; 3891 switch (sdc_softc[ii->ii_ctlr].sdc_firmware & SDCFW_DEVMASK) { 3892 3893 case SDCFW_HD: /* Hard Disk */ 3894 st = &sdstdrv[unit]; 3895 break; 3896 3897 case SDCFW_MO: /* MO only */ 3898 if ((sdd->sdd_flags & SDDF_SAMEDSK) == SDDF_DSKCHGD) { 3899 /* 3900 * read partition information, 3901 * and set up sdstdrv[unit] 3902 */ 3903 if (sd_b_open(dev, FREAD|FWRITE) != 0) { 3904 /* 3905 * block device open error 3906 */ 3907 return (-1); 3908 } else { 3909 /* 3910 * use disk partition information 3911 */ 3912 st = &sdstdrv[unit]; 3913 if (isalone(unit) == ONLY_ONE) 3914 sd_b_close(dev, 0); 3915 } 3916 } else if (sdd->sdd_flags & SDDF_NONFMT) { 3917 /* 3918 * medium is not initialized. 3919 */ 3920 return (-1); 3921 } else { 3922 st = &sdstdrv[unit]; 3923 } 3924 break; 3925 3926 default: 3927 /* case SDCFW_CD: */ 3928 return (-1); 3929 3930 } 3931 3932 if (st->sizes == NULL) 3933 return (-1); /* XXX */ 3934 else 3935 return (st->sizes[dev2part(dev)].sd_nblocks); /* XXX */ 3936 } 3937 3938 /* 3939 * Reset driver. 3940 * Cancel software state of all pending transfers, 3941 * and restart all units and the controller. 3942 */ 3943 sdreset() 3944 { 3945 register struct iop/**/_ctlr *im; 3946 register struct iop/**/_device *ii; 3947 register struct sdc_softc *sdc; 3948 register struct sdd_softc *sdd; 3949 register int i; 3950 register int unit; 3951 3952 re_init_done = 1; 3953 for (i = 0; i < nsdc; i++) { 3954 im = sdminfo[i]; 3955 if (im == 0) 3956 continue; 3957 if (im->im_alive == 0) 3958 continue; 3959 printf(" sdc%d: ", i); 3960 sdc = &sdc_softc[i]; 3961 sdc->sdc_wticks = 0; 3962 3963 /* scop_init() is already called by screset() */ 3964 3965 sdtmp_stat &= ~B_BUSY; 3966 3967 for (unit = 0; unit < nsd; unit++) { 3968 ii = sddinfo[unit]; 3969 if (ii == 0) 3970 continue; 3971 if (ii->ii_alive == 0) 3972 continue; 3973 if (ii->ii_mi != im) 3974 continue; 3975 3976 csdbuf[unit].b_flags &= ~B_BUSY; 3977 3978 sdd = &sdd_softc[unit]; 3979 sdd->sdd_flags = 0; 3980 3981 /* 3982 * UNLOCK SCSI access 3983 */ 3984 sdc->sdc_firmware &= ~SDCFW_BUSY; 3985 3986 if (sdslave(ii, ii->ii_addr, im->im_intr) == 0) { 3987 printf("sd%d: not ready\n", ii->ii_slave); 3988 continue; 3989 } 3990 sdattach(ii); 3991 } 3992 } 3993 re_init_done = 2; 3994 } 3995 3996 int sd_long_timeout = 24 * 60 * 60; /* 24 hours */ 3997 3998 #define max(a, b) (((a)>(b))?(a):(b)) 3999 4000 /* 4001 * Wake up every second and if interrupt is pending 4002 * but nothing has happened increment a counter. 4003 * If nothing happens for sdc_timeo seconds, reset the IOP 4004 * and begin anew. 4005 */ 4006 sdwatch() 4007 { 4008 register struct iop/**/_ctlr *im; 4009 register struct sdc_softc *sdc; 4010 register int i; 4011 register int unit; 4012 int timeo; 4013 4014 extern int Scsi_Disconnect; 4015 4016 timeout(sdwatch, (caddr_t)0, hz); 4017 for (i = 0; i < nsdc; i++) { 4018 im = sdminfo[i]; 4019 if (im == 0) 4020 continue; 4021 if (im->im_alive == 0) 4022 continue; 4023 sdc = &sdc_softc[i]; 4024 4025 if (im->im_tab.b_active) 4026 goto active; 4027 4028 for (unit = 0; unit < nsd; unit++) 4029 if (sdutab[unit].b_active && sddinfo[unit]->ii_mi == im) 4030 goto active; 4031 4032 sdc->sdc_wticks = 0; 4033 continue; 4034 active: 4035 if (Scsi_Disconnect) 4036 timeo = sdc->sdc_timeo; 4037 else 4038 timeo = max(sdc->sdc_timeo, sd_long_timeout); 4039 4040 if (sdc->sdc_wticks++ >= timeo) { 4041 register struct scsi *sc; 4042 4043 sc = get_scsi(im->im_intr); 4044 sdc->sdc_wticks = 0; 4045 printf("sdc%d: lost interrupt\n", i); 4046 4047 screset(im->im_intr); 4048 } 4049 } 4050 } 4051 4052 /* 4053 * sdstop() is timer interrupt routine. 4054 * So, can't use sleep(). 4055 */ 4056 sdstop() 4057 { 4058 register struct iop/**/_ctlr *im; 4059 register struct iop/**/_device *ii; 4060 register struct sdc_softc *sdc; 4061 register struct sdd_softc *sdd; 4062 register int unit; 4063 register int intr; 4064 register int i; 4065 struct scsi *sc; 4066 int eject_sw; 4067 4068 timeout(sdstop, (caddr_t)0, hz); 4069 4070 for (i = 0; i < nsdc; i++) { 4071 im = sdminfo[i]; 4072 if (im == 0) 4073 continue; 4074 if (im->im_alive == 0) 4075 continue; 4076 for (unit = 0; unit < nsd; unit++) { 4077 if ((ii = sddinfo[unit]) == 0) 4078 continue; 4079 if (ii->ii_mi != im) 4080 continue; 4081 sdc = &sdc_softc[ii->ii_ctlr]; 4082 if ((sdc->sdc_firmware & SDCFW_RMB) == 0) 4083 continue; 4084 intr = ii->ii_intr; 4085 if (isalone(unit)) 4086 continue; 4087 /**********************/ 4088 /* MO & CD-ROM */ 4089 /**********************/ 4090 /* 4091 * there is no process which open the unit. 4092 */ 4093 sdd = &sdd_softc[unit]; 4094 sc = get_scsi(intr); 4095 if (sdd->sdd_start > 0) 4096 sdd->sdd_start--; 4097 else if (sdd->sdd_start == 0) { 4098 /* 4099 * Now stop the unit. 4100 * check SCSI access 4101 */ 4102 if (sdc->sdc_firmware & SDCFW_BUSY) 4103 continue; 4104 sdc->sdc_firmware |= SDCFW_BUSY; 4105 sdc->sdc_state |= SDCS_IOCTL|SDCS_SCUNLOCK; 4106 4107 eject_sw = (sdd->sdd_flags & SDDF_REQ_EJECT) ? 4108 SDSS_EJECT : SDSS_STOP; 4109 scop_stst(intr, sc, ii->ii_slave, 4110 SCSI_INTEN, eject_sw); 4111 sdd->sdd_start = -2; 4112 } 4113 } 4114 } 4115 } 4116 4117 isalone(unit) 4118 register int unit; 4119 { 4120 register int i, n; 4121 4122 n = 0; 4123 for (i = 0; i < PNUM; i++) 4124 n += (sd_b_openf[unit][i] + sd_c_openf[unit][i]); 4125 return (n); 4126 } 4127 4128 /************************************************ 4129 * Convert Hex and RS code table definition * 4130 ************************************************/ 4131 4132 #define X8_L 0x001d 4133 #define X8_H 0x1d00 4134 4135 4136 #define hextors(data) hxtable[(int)((data) & 0xff)] 4137 #define XORMASK(code) xortable[(unsigned int)(code)] 4138 4139 int hxtable[256] = { 4140 0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 4141 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b, 4142 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 4143 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71, 4144 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 4145 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45, 4146 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 4147 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6, 4148 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 4149 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88, 4150 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 4151 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40, 4152 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 4153 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d, 4154 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 4155 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57, 4156 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 4157 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18, 4158 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 4159 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e, 4160 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 4161 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61, 4162 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 4163 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2, 4164 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 4165 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6, 4166 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 4167 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a, 4168 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 4169 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7, 4170 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 4171 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf, 4172 }; 4173 4174 int xortable[256] = { 4175 0x00000000, 0x90910101, 0x91210201, 0x01b00300, 4176 0x92410401, 0x02d00500, 0x03600600, 0x93f10701, 4177 0x94810801, 0x04100900, 0x05a00a00, 0x95310b01, 4178 0x06c00c00, 0x96510d01, 0x97e10e01, 0x07700f00, 4179 0x99011001, 0x09901100, 0x08201200, 0x98b11301, 4180 0x0b401400, 0x9bd11501, 0x9a611601, 0x0af01700, 4181 0x0d801800, 0x9d111901, 0x9ca11a01, 0x0c301b00, 4182 0x9fc11c01, 0x0f501d00, 0x0ee01e00, 0x9e711f01, 4183 0x82012001, 0x12902100, 0x13202200, 0x83b12301, 4184 0x10402400, 0x80d12501, 0x81612601, 0x11f02700, 4185 0x16802800, 0x86112901, 0x87a12a01, 0x17302b00, 4186 0x84c12c01, 0x14502d00, 0x15e02e00, 0x85712f01, 4187 0x1b003000, 0x8b913101, 0x8a213201, 0x1ab03300, 4188 0x89413401, 0x19d03500, 0x18603600, 0x88f13701, 4189 0x8f813801, 0x1f103900, 0x1ea03a00, 0x8e313b01, 4190 0x1dc03c00, 0x8d513d01, 0x8ce13e01, 0x1c703f00, 4191 0xb4014001, 0x24904100, 0x25204200, 0xb5b14301, 4192 0x26404400, 0xb6d14501, 0xb7614601, 0x27f04700, 4193 0x20804800, 0xb0114901, 0xb1a14a01, 0x21304b00, 4194 0xb2c14c01, 0x22504d00, 0x23e04e00, 0xb3714f01, 4195 0x2d005000, 0xbd915101, 0xbc215201, 0x2cb05300, 4196 0xbf415401, 0x2fd05500, 0x2e605600, 0xbef15701, 4197 0xb9815801, 0x29105900, 0x28a05a00, 0xb8315b01, 4198 0x2bc05c00, 0xbb515d01, 0xbae15e01, 0x2a705f00, 4199 0x36006000, 0xa6916101, 0xa7216201, 0x37b06300, 4200 0xa4416401, 0x34d06500, 0x35606600, 0xa5f16701, 4201 0xa2816801, 0x32106900, 0x33a06a00, 0xa3316b01, 4202 0x30c06c00, 0xa0516d01, 0xa1e16e01, 0x31706f00, 4203 0xaf017001, 0x3f907100, 0x3e207200, 0xaeb17301, 4204 0x3d407400, 0xadd17501, 0xac617601, 0x3cf07700, 4205 0x3b807800, 0xab117901, 0xaaa17a01, 0x3a307b00, 4206 0xa9c17c01, 0x39507d00, 0x38e07e00, 0xa8717f01, 4207 0xd8018001, 0x48908100, 0x49208200, 0xd9b18301, 4208 0x4a408400, 0xdad18501, 0xdb618601, 0x4bf08700, 4209 0x4c808800, 0xdc118901, 0xdda18a01, 0x4d308b00, 4210 0xdec18c01, 0x4e508d00, 0x4fe08e00, 0xdf718f01, 4211 0x41009000, 0xd1919101, 0xd0219201, 0x40b09300, 4212 0xd3419401, 0x43d09500, 0x42609600, 0xd2f19701, 4213 0xd5819801, 0x45109900, 0x44a09a00, 0xd4319b01, 4214 0x47c09c00, 0xd7519d01, 0xd6e19e01, 0x46709f00, 4215 0x5a00a000, 0xca91a101, 0xcb21a201, 0x5bb0a300, 4216 0xc841a401, 0x58d0a500, 0x5960a600, 0xc9f1a701, 4217 0xce81a801, 0x5e10a900, 0x5fa0aa00, 0xcf31ab01, 4218 0x5cc0ac00, 0xcc51ad01, 0xcde1ae01, 0x5d70af00, 4219 0xc301b001, 0x5390b100, 0x5220b200, 0xc2b1b301, 4220 0x5140b400, 0xc1d1b501, 0xc061b601, 0x50f0b700, 4221 0x5780b800, 0xc711b901, 0xc6a1ba01, 0x5630bb00, 4222 0xc5c1bc01, 0x5550bd00, 0x54e0be00, 0xc471bf01, 4223 0x6c00c000, 0xfc91c101, 0xfd21c201, 0x6db0c300, 4224 0xfe41c401, 0x6ed0c500, 0x6f60c600, 0xfff1c701, 4225 0xf881c801, 0x6810c900, 0x69a0ca00, 0xf931cb01, 4226 0x6ac0cc00, 0xfa51cd01, 0xfbe1ce01, 0x6b70cf00, 4227 0xf501d001, 0x6590d100, 0x6420d200, 0xf4b1d301, 4228 0x6740d400, 0xf7d1d501, 0xf661d601, 0x66f0d700, 4229 0x6180d800, 0xf111d901, 0xf0a1da01, 0x6030db00, 4230 0xf3c1dc01, 0x6350dd00, 0x62e0de00, 0xf271df01, 4231 0xee01e001, 0x7e90e100, 0x7f20e200, 0xefb1e301, 4232 0x7c40e400, 0xecd1e501, 0xed61e601, 0x7df0e700, 4233 0x7a80e800, 0xea11e901, 0xeba1ea01, 0x7b30eb00, 4234 0xe8c1ec01, 0x7850ed00, 0x79e0ee00, 0xe971ef01, 4235 0x7700f000, 0xe791f101, 0xe621f201, 0x76b0f300, 4236 0xe541f401, 0x75d0f500, 0x7460f600, 0xe4f1f701, 4237 0xe381f801, 0x7310f900, 0x72a0fa00, 0xe231fb01, 4238 0x71c0fc00, 0xe151fd01, 0xe0e1fe01, 0x7070ff00 4239 }; 4240 4241 /******************************************************** 4242 * EDC (Error Detection Code) check * 4243 * (using CRC code) * 4244 * MODE 1 : Sync + Header + User data + edc * 4245 * MODE 2 : Sub header + User data + edc * 4246 ********************************************************/ 4247 4248 #define SYNC_EDC 0x908eff4e /* sector sync EDC value */ 4249 #define HEADER 4 /* header length 4 bytes */ 4250 #define SUB_H 8 /* Subheader length 8 bytes */ 4251 #define USER_DATA 2048 /* User data length 2048 bytes */ 4252 #define EDC_LEN 4 /* EDC code length 4 bytes */ 4253 4254 cal_edc1(db, mode) 4255 register unsigned char *db; 4256 int mode; 4257 { 4258 register int j; 4259 register unsigned int work; 4260 4261 j = USER_DATA + EDC_LEN; 4262 if (mode == 2) { 4263 j += SUB_H; 4264 work = 0; 4265 } else { 4266 j += HEADER; 4267 work = SYNC_EDC; 4268 } 4269 while (--j >= 0) 4270 work = ((work >> 8) | (*db++ << 24)) ^ XORMASK(work & 0xff); 4271 4272 return (work); 4273 } 4274 4275 4276 /************************************************/ 4277 /* error detection & correction */ 4278 /* if form 1 */ 4279 /* header area should be zero */ 4280 /************************************************/ 4281 4282 /* 4283 * error detection & correction P-direction 4284 */ 4285 p_dir(dbuf) 4286 register unsigned short *dbuf; 4287 { 4288 unsigned short s0, s1, d; 4289 register int col, row; 4290 register int x; 4291 unsigned char s0l, s0h, s1l, s1h; 4292 4293 /* 4294 * calculate syndrome S0 S1 4295 */ 4296 for (col = 0; col < 43; col++) { 4297 s0 = s1 = 0; 4298 4299 for (row = 0; row < 26; row++) { 4300 d = dbuf[43 * row + col]; 4301 s0 ^= d; 4302 s1 = rsshift(s1) ^ d; 4303 } 4304 4305 s0h = s0 & 0x00ff; 4306 s1h = s1 & 0x00ff; 4307 s0l = (s0 >> 8) & 0x00ff; 4308 s1l = (s1 >> 8) & 0x00ff; 4309 /* 4310 * calculate error position & correction 4311 */ 4312 if (s0l != 0) { 4313 if((x = hextors(s1l) - hextors(s0l)) < 0) 4314 x += 255; 4315 if ((x >= 0) && (x < 26)) { 4316 x = 25 - x; 4317 /* 4318 * correction 4319 */ 4320 dbuf[43 * x + col] ^= (s0 & 0xff00); 4321 } 4322 } 4323 4324 /* 4325 * calculate error position & correction 4326 */ 4327 if (s0h != 0) { 4328 if((x = hextors(s1h) - hextors(s0h)) < 0) 4329 x += 255; 4330 if ((x >= 0) && (x < 26)) { 4331 x = 25 - x; 4332 /* 4333 * correction 4334 */ 4335 dbuf[43 * x + col] ^= (s0 & 0x00ff); 4336 } 4337 } 4338 } 4339 } 4340 4341 /* 4342 * error detection & correction Q-direction 4343 */ 4344 q_dir(dbuf) 4345 register unsigned short *dbuf; 4346 { 4347 unsigned short s0, s1, d; 4348 register int col, row; 4349 register int x; 4350 unsigned char s0l, s0h, s1l, s1h; 4351 4352 /* 4353 * calculate syndrome S0 S1 4354 */ 4355 for (row = 0; row < 26; row++) { 4356 s0 = s1 = 0; 4357 4358 for (col = 0; col < 45; col++) { 4359 if (col < 43) 4360 d = dbuf[(44 * col + 43 * row) % 1118]; 4361 else if (col == 43) 4362 d = dbuf[43 * 26 + row]; 4363 else 4364 d = dbuf[44 * 26 + row]; 4365 s0 ^= d; 4366 s1 = rsshift(s1) ^ d; 4367 } 4368 4369 s0h = s0 & 0x00ff; 4370 s1h = s1 & 0x00ff; 4371 s0l = (s0 >> 8) & 0x00ff; 4372 s1l = (s1 >> 8) & 0x00ff; 4373 /* 4374 * calculate error position & correction 4375 */ 4376 if (s0l != 0) { 4377 if((x = hextors(s1l) - hextors(s0l)) < 0) 4378 x += 255; 4379 if (x >= 0 && x < 45) { 4380 x = 44 - x; 4381 /* 4382 * correction 4383 */ 4384 if (x < 43) 4385 dbuf[(44 * x + 43 * row) % 1118] 4386 ^= s0 & 0xff00; 4387 else if (x == 43) 4388 dbuf[43 * 26 + row] ^= s0 & 0xff00; 4389 else 4390 dbuf[44 * 26 + row] ^= s0 & 0xff00; 4391 } 4392 } 4393 4394 /* 4395 * calculate error position & correction 4396 */ 4397 if (s0h != 0) { 4398 if((x = hextors(s1h) - hextors(s0h)) < 0) 4399 x += 255; 4400 if ((x >= 0) && (x < 45)) { 4401 x = 44 - x; 4402 /* 4403 * correction 4404 */ 4405 if (x < 43) 4406 dbuf[(44 * x + 43 * row) % 1118] 4407 ^= s0 & 0x00ff; 4408 else if ( x == 43) 4409 dbuf[43 * 26 + row] ^= s0 & 0x00ff; 4410 else 4411 dbuf[44 * 26 + row] ^= s0 & 0x00ff; 4412 } 4413 } 4414 } 4415 } 4416 4417 /* 4418 * shift high & low byte at the same time 4419 */ 4420 rsshift(d) 4421 unsigned short d; 4422 { 4423 register int x; 4424 register int dmy; /* This way is faster */ 4425 4426 dmy = (int)d; 4427 x = (dmy << 1) & 0xfefe; /* clear LSB of high & low byte */ 4428 if ((dmy & 0x0080) != 0) 4429 x ^= X8_L; 4430 if ((dmy & 0x8000) != 0) 4431 x ^= X8_H; 4432 return(x); 4433 } 4434 #endif /* NSD > 0 */ 4435