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