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