1 /* 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 7 * 8 * %sccs.include.redist.c% 9 * 10 * from: $Hdr: scsi.c,v 4.300 91/06/27 20:42:51 root Rel41 $ SONY 11 * 12 * @(#)scsi.c 8.1 (Berkeley) 06/11/93 13 */ 14 15 /* 16 * scsi.c ver 1.1 17 */ 18 19 #include <machine/param.h> 20 21 #include <sys/param.h> 22 #include <sys/buf.h> 23 #include <sys/proc.h> 24 #include <sys/user.h> 25 26 # include <machine/cpu.h> 27 28 #include <news3400/hbdev/hbvar.h> 29 #include <news3400/hbdev/scsic.h> 30 #include <news3400/hbdev/screg_1185.h> 31 32 #include <news3400/iodev/scsireg.h> 33 #include <news3400/iodev/ioptohb.h> 34 35 #define DEBUG_LOSSBSY_HUNG 36 37 #ifdef DEBUG_LOSSBSY_HUNG 38 # define PROBE_MAXRETRY 100 39 #endif 40 41 #ifndef NO_SCSI_DISCONNECT 42 int Scsi_Disconnect = IDT_DISCON; 43 #else 44 int Scsi_Disconnect = 0; 45 #endif 46 47 # define MAXCTLR 8 48 struct sc_data sc_data[MAXCTLR]; 49 struct scintsw scintsw[MAXCTLR]; 50 51 #ifdef RSENSE_MSG_DISP 52 int rsense_msg_disp = 1; /* RSENSE-message display flag */ 53 #else 54 int rsense_msg_disp = 0; /* RSENSE-message display flag */ 55 #endif 56 57 int mo_disp_format = 0; /* MO format mode display flag */ 58 59 struct msg_list { 60 int ml_code; /* message code */ 61 int ml_msglvl; /* message level */ 62 char *ml_msgstr; /* message string */ 63 }; 64 65 #ifdef NO_SHRINK_RSENSE_MSG 66 # define MSG(m) m 67 #else 68 # define MSG(m) NULL 69 #endif 70 71 struct msg_list skeylist[] = { 72 { 0x00, 1, MSG("No Sense") }, 73 { 0x01, 0, MSG("Recoverable Error") }, 74 { 0x02, 0, MSG("Not Ready") }, 75 { 0x03, 0, MSG("Medium Error") }, 76 { 0x04, 0, MSG("Hardware Error") }, 77 { 0x05, 0, MSG("Illegal Request") }, 78 { 0x06, 1, MSG("Unit Attention") }, 79 { 0x07, 1, MSG("Data protect") }, 80 { 0x08, 0, MSG("Blank Check") }, 81 { 0x09, 0, MSG("Vendor Unique") }, 82 { 0x0a, 0, MSG("Copy/Compare Aborted") }, 83 { 0x0b, 0, MSG("Aborted Command") }, 84 { 0x0c, 0, MSG("Equal") }, 85 { 0x0d, 0, MSG("Volume Overflow") }, 86 { 0x0e, 0, MSG("Miscompare") }, 87 { -1, 0, (caddr_t)0 } 88 }; 89 90 struct msg_list ecodelist[] = { 91 { 0x00, 9, MSG("No Additional Sense Information") }, 92 /*HD*/ { 0x01, 1, MSG("No Index/Address Mark Found signal") }, 93 { 0x02, 0, MSG("No Seek Complete") }, 94 { 0x03, 0, MSG("Write Fault") }, 95 { 0x04, 9, MSG("Drive Not Ready") }, 96 { 0x05, 0, MSG("Drive Not Selected") }, 97 /*HD*/ { 0x06, 0, MSG("No Track Zero") }, 98 { 0x07, 0, MSG("Multiple Drives Selected") }, 99 { 0x08, 0, MSG("Logical Unit Communication Failure") }, 100 { 0x09, 2, MSG("Track Following Error") }, 101 /*MO*/ { 0x0a, 1, MSG("No Disk") }, 102 /*MO*/ { 0x0b, 1, MSG("Load/Unload Failure") }, 103 /*MO*/ { 0x0c, 1, MSG("Spindle Failure") }, 104 /*MO*/ { 0x0d, 1, MSG("Focus Failure") }, 105 /*MO*/ { 0x0e, 1, MSG("Tracking Failure") }, 106 /*MO*/ { 0x0f, 0, MSG("Drive Initialization Failure") }, 107 { 0x10, 1, MSG("ID CRC or ECC error") }, 108 { 0x11, 0, MSG("Unrecoverd Read error") }, 109 /*HD*/ { 0x12, 0, MSG("No Address Mark (byte sync byte) found in ID field") }, 110 /*HD*/ { 0x13, 0, MSG("No Address Mark (byte sync byte) found in Data field") }, 111 /*HD*/ { 0x14, 0, MSG("No record found") }, 112 { 0x15, 1, MSG("Seek Positioning Error") }, 113 114 /*HD*/ { 0x17, 0, MSG("Recovered Read data with Read retries") }, 115 { 0x18, 0, MSG("Recovered Read data with ECC procedure") }, 116 /*HD*/ { 0x19, 0, MSG("Defect List error") }, 117 /*HD*/ { 0x1a, 0, MSG("Parameter overrun") }, 118 /*HD*/ { 0x1b, 0, MSG("Synchronous transfer error") }, 119 /*HD*/ { 0x1c, 0, MSG("Primary Defect List not found") }, 120 /*HD*/ { 0x1d, 0, MSG("Compare error") }, 121 122 { 0x20, 0, MSG("Invalid Command Operation Code") }, 123 { 0x21, 0, MSG("Illegal Logical Block Address") }, 124 /*HD*/ { 0x22, 0, MSG("Illegal function for device type") }, 125 /*MO*/ { 0x23, 0, MSG("Illegal function for Medium Type") }, 126 { 0x24, 0, MSG("Illegal Field in CDB") }, 127 { 0x25, 0, MSG("Invalid LUN") }, 128 { 0x26, 0, MSG("Invalid field in Parameter List") }, 129 { 0x27, 0, MSG("Write Protected") }, 130 { 0x28, 1, MSG("Medium Changed") }, 131 { 0x29, 1, MSG("Power On or Reset or Bus Device Reset Occured") }, 132 { 0x2a, 1, MSG("Mode Select Parameters Changed") }, 133 /*HD*/ { 0x2b, 0, MSG("Host cannot Disconnect") }, 134 135 { 0x31, 0, MSG("Medium Format Corrupted") }, 136 { 0x32, 0, MSG("No Defect Spare Location Available") }, 137 138 /*MO*/ { 0x38, 1, MSG("Recovered with Automatic Reallocation") }, 139 /*MO*/ { 0x39, 0, MSG("Automatic Reallocation Failure") }, 140 /*MO*/ { 0x3a, 1, MSG("Defect List Update Failure") }, 141 142 /*MO*/ { 0x3d, 0, MSG("Defect List Not Available") }, 143 144 /*HD*/ { 0x40, 0, MSG("RAM failure") }, 145 /*HD*/ { 0x41, 0, MSG("Data Path diagnostic failure") }, 146 { 0x42, 0, MSG("Power On Diagnostic Failure") }, 147 { 0x43, 0, MSG("Message Reject Error") }, 148 { 0x44, 9, MSG("Internal Controller Error") }, 149 /*HD*/ { 0x45, 0, MSG("Selection/Reselection failure") }, 150 151 { 0x47, 0, MSG("SCSI Interface Parity Error") }, 152 { 0x48, 0, MSG("Initiator Detected Error") }, 153 { 0x49, 0, MSG("Inappropriate/Illegal Message") }, 154 155 { 0x64, 1, MSG("Illegal mode for this track") }, 156 157 { -1, 0, (caddr_t)0 } 158 }; 159 #undef MSG 160 161 /* 162 * Init a scsi bus. 163 */ 164 scop_init(scn) 165 int scn; 166 { 167 static struct scsi sc; 168 int chan; 169 170 for (chan = 0; chan < MAXCTLR; chan++) { 171 bzero((caddr_t)&sc, sizeof(struct scsi)); 172 sc.sc_cdb.un_reserved[0] = SCOP_RESET; 173 sc.sc_cdb.un_reserved[1] = SCOP_RESET; 174 175 if (!sc_busy(chan)) { 176 sc_go(chan, (struct scsi *)&sc, SCSI_INTDIS); 177 178 chan = (chan / 8 + 1) * 8; 179 } 180 } 181 } 182 183 /************************************** 184 The multiple scsi bus is NOT suported by following routines. 185 How about use inter like dev_t ( uper is scsi#, lower is inter ) 186 or hb_ctlr. 187 probe() ga futatuarukara unit# ----- udauda. 188 **************************************/ 189 190 /* 191 * scprobe. probe routine for mass storage controller. 192 */ 193 scprobe(im, ctlrintr, sc) 194 struct iop/**/_ctlr *im; 195 int (*ctlrintr)(); 196 register struct scsi *sc; 197 { 198 register struct scintsw *sci; 199 int s; 200 #ifdef DEBUG_LOSSBSY_HUNG 201 int retry = 0; 202 #endif DEBUG_LOSSBSY_HUNG 203 204 sci = &scintsw[im->im_intr]; 205 if (sci->sci_inthandler) 206 return (0); 207 208 #ifdef DEBUG_LOSSBSY_HUNG 209 scprobe_loop: 210 /* s = splsc(); */ 211 scop_inquiry(im->im_intr, sc, 0, SCSI_INTDIS, 4, (caddr_t)0); 212 /* splx(s); */ 213 214 if (sc->sc_istatus != INST_EP) { 215 if ((sc->sc_tstatus == TGST_BUSY) && (retry++ < PROBE_MAXRETRY)) { 216 goto scprobe_loop; 217 } 218 return (0); 219 } 220 221 #else /* DEBUG_LOSSBSY_HUNG */ 222 223 /* s = splsc(); */ 224 scop_inquiry(im->im_intr, sc, 0, SCSI_INTDIS, 4, (caddr_t)0); 225 /* splx(s); */ 226 227 if (sc->sc_istatus != INST_EP) 228 return (0); 229 230 #endif /* DEBUG_LOSSBSY_HUNG */ 231 232 sci->sci_inthandler = ctlrintr; 233 sci->sci_ctlr = im->im_ctlr; 234 return (1); 235 } 236 237 /* 238 * ssprobe. probe routine for non-mass storage peripherals. 239 */ 240 ssprobe(ii, ctlrintr, sc) 241 struct iop/**/_device *ii; 242 int (*ctlrintr)(); 243 register struct scsi *sc; 244 { 245 register struct scintsw *sci; 246 int s; 247 248 sci = &scintsw[ii->ii_intr]; 249 if (sci->sci_inthandler) 250 return (0); 251 252 /* s = splsc(); */ 253 scop_inquiry(ii->ii_intr, sc, 0, SCSI_INTDIS, 4, (caddr_t)0); 254 /* splx(s); */ 255 256 if (sc->sc_istatus != INST_EP) 257 return (0); 258 259 sci->sci_inthandler = ctlrintr; 260 sci->sci_ctlr = ii->ii_unit; 261 return (1); 262 } 263 264 /* 265 * SCOP_TST request 266 */ 267 scop_tst(intr, sc, slave, ie) 268 register int intr; 269 register struct scsi *sc; 270 register int slave; 271 register int ie; 272 { 273 scinit(sc, slave, DEV_BSIZE); 274 275 /* sc_cdb */ 276 sc->sc_opcode = SCOP_TST; 277 278 sc_go(intr, (struct scsi *)sc, ie); 279 } 280 281 /* 282 * SCOP_REZERO request 283 */ 284 scop_rezero(intr, sc, slave, ie) 285 register int intr; 286 register struct scsi *sc; 287 register int slave; 288 register int ie; 289 { 290 scinit(sc, slave, DEV_BSIZE); 291 292 /* sc_cdb */ 293 sc->sc_opcode = SCOP_REZERO; 294 295 sc_go(intr, (struct scsi *)sc, ie); 296 } 297 298 /* 299 * SCOP_REWIND request 300 */ 301 scop_rewind(intr, sc, slave, ie, imme) 302 register int intr; 303 register struct scsi *sc; 304 register int slave; 305 register int ie, imme; 306 { 307 scinit(sc, slave, DEV_BSIZE); 308 309 /* sc_cdb */ 310 sc->sc_opcode = SCOP_REZERO; 311 sc->sc_tucode = imme; 312 313 sc_go(intr, (struct scsi *)sc, ie); 314 } 315 316 /* 317 * SCOP_RSENSE request 318 */ 319 scop_rsense(intr, sc, slave, ie, count, param) 320 register int intr; 321 register struct scsi *sc; 322 register int slave; 323 register int ie; 324 register int count; 325 register caddr_t param; 326 { 327 scinit(sc, slave, DEV_BSIZE); 328 329 sc->sc_cpoint = (u_char *)param; 330 sc->sc_ctrnscnt = count; 331 332 /* sc_cdb */ 333 sc->sc_opcode = SCOP_RSENSE; 334 sc->sc_count = count; 335 336 sc_go(intr, (struct scsi *)sc, ie); 337 } 338 339 /* 340 * SCOP_RASBLK request 341 */ 342 scop_rasblk(intr, sc, slave, ie, lad) 343 register int intr; 344 register struct scsi *sc; 345 register int slave; 346 register int ie; 347 register int lad; 348 { 349 struct sc_rab *sca = (struct sc_rab *)sc->sc_param; 350 351 scinit(sc, slave, DEV_BSIZE); 352 353 sca->sca_dllen = 4; 354 sca->sca_dlad[0] = lad; 355 sc->sc_cpoint = (u_char *)sca; 356 357 sc->sc_ctrnscnt = 8; 358 359 /* sc_cdb */ 360 sc->sc_opcode = SCOP_RASBLK; 361 362 sc_go(intr, (struct scsi *)sc, ie); 363 } 364 365 /* 366 * SCOP_MERASE request 367 */ 368 scop_merase(intr, sc, slave, ie, count) 369 register int intr; 370 register struct scsi *sc; 371 register int slave; 372 register int ie; 373 register int count; 374 { 375 scinit(sc, slave, DEV_BSIZE); 376 377 /* sc_cdb */ 378 sc->sc_opcode = SCOP_MERASE; 379 sc->sc_mtcount3 = count; 380 381 sc_go(intr, (struct scsi *)sc, ie); 382 } 383 384 /* 385 * SCOP_WFMARK request 386 */ 387 scop_wfmark(intr, sc, slave, ie, count) 388 register int intr; 389 register struct scsi *sc; 390 register int slave; 391 register int ie; 392 register int count; 393 { 394 scinit(sc, slave, DEV_BSIZE); 395 396 /* sc_cdb */ 397 sc->sc_opcode = SCOP_WFMARK; 398 count &= 0xffffff; 399 sc->sc_tucount3 = count & 0xff; 400 count >>= 8; 401 sc->sc_tucount2 = count & 0xff; 402 count >>= 8; 403 sc->sc_tucount1 = count & 0xff; 404 405 sc_go(intr, (struct scsi *)sc, ie); 406 } 407 408 /* 409 * SCOP_SPACE request 410 */ 411 scop_space(intr, sc, slave, ie, count, code) 412 register int intr; 413 register struct scsi *sc; 414 register int slave; 415 register int ie; 416 register int count; 417 register int code; 418 { 419 scinit(sc, slave, DEV_BSIZE); 420 421 /* sc_cdb */ 422 sc->sc_opcode = SCOP_SPACE; 423 sc->sc_tucode = code; 424 count &= 0xffffff; 425 sc->sc_tucount3 = count & 0xff; 426 count >>= 8; 427 sc->sc_tucount2 = count & 0xff; 428 count >>= 8; 429 sc->sc_tucount1 = count & 0xff; 430 431 sc_go(intr, (struct scsi *)sc, ie); 432 } 433 434 /* 435 * SCOP_INQUIRY request 436 */ 437 scop_inquiry(intr, sc, slave, ie, count, param) 438 register int intr; 439 register struct scsi *sc; 440 register int slave; 441 register int ie; 442 register int count; 443 register caddr_t param; 444 { 445 scinit(sc, slave, DEV_BSIZE); 446 447 sc->sc_cpoint = (u_char *)param; 448 sc->sc_ctrnscnt = count; 449 450 /* sc_cdb */ 451 sc->sc_opcode = SCOP_INQUIRY; 452 sc->sc_count = count; 453 454 sc_go(intr, (struct scsi *)sc, ie); 455 } 456 457 /* 458 * SCOP_STST request 459 */ 460 scop_stst(intr, sc, slave, ie, sw) 461 register int intr; 462 register struct scsi *sc; 463 register int slave; 464 register int ie; 465 register int sw; 466 { 467 scinit(sc, slave, DEV_BSIZE); 468 469 /* sc_cdb */ 470 sc->sc_opcode = SCOP_STST; 471 sc->sc_switch = sw; 472 473 sc_go(intr, (struct scsi *)sc, ie); 474 } 475 476 /* 477 * SCOP_RCAP request 478 */ 479 scop_rcap(intr, sc, slave, ie, count, param) 480 register int intr; 481 register struct scsi *sc; 482 register int slave; 483 register int ie; 484 register int count; 485 register caddr_t param; 486 { 487 scinit(sc, slave, DEV_BSIZE); 488 489 sc->sc_cpoint = (u_char *)param; 490 sc->sc_ctrnscnt = count; 491 492 /* sc_cdb */ 493 sc->sc_opcode = SCOP_RCAP; 494 sc->sc_pmi = OFF; 495 496 sc_go(intr, (struct scsi *)sc, ie); 497 } 498 499 /* 500 * SCOP_BSSRCH request 501 */ 502 scop_bssrch(intr, sc, slave, ie, count, param) 503 register int intr; 504 register struct scsi *sc; 505 register int slave; 506 register int ie; 507 register int count; 508 register caddr_t param; 509 { 510 scinit(sc, slave, DEV_BSIZE); 511 512 sc->sc_cpoint = (u_char *)param; 513 sc->sc_ctrnscnt = count; 514 515 /* sc_cdb */ 516 sc->sc_opcode = SCOP_BSSRCH; 517 sc->sc_ladhi = *(short *)param; 518 sc->sc_ladlo = *(short *)(param + 2); 519 520 sc_go(intr, (struct scsi *)sc, ie); 521 } 522 523 /* 524 * SCOP_WSSRCH request 525 */ 526 scop_wssrch(intr, sc, slave, ie, count, param) 527 register int intr; 528 register struct scsi *sc; 529 register int slave; 530 register int ie; 531 register int count; 532 register caddr_t param; 533 { 534 scinit(sc, slave, DEV_BSIZE); 535 536 sc->sc_cpoint = (u_char *)param; 537 sc->sc_ctrnscnt = count; 538 539 /* sc_cdb */ 540 sc->sc_opcode = SCOP_WSSRCH; 541 sc->sc_ladhi = *(short *)param; 542 sc->sc_ladlo = *(short *)(param + 2); 543 544 sc_go(intr, (struct scsi *)sc, ie); 545 } 546 547 /* 548 * 549 * SCOP_EESENSE request 550 * Enable/Disable Eject Request Sense 551 * Write Once only supported. 552 * 553 */ 554 scop_eesense(intr, sc, slave, ie, sw) 555 register int intr; 556 register struct scsi *sc; 557 register int slave; 558 register int ie; 559 register int sw; 560 { 561 scinit(sc, slave, DEV_BSIZE); 562 563 /* sc_cdb */ 564 sc->sc_opcode = SCOP_EESENSE; 565 sc->sc_switch = sw; 566 567 sc_go(intr, (struct scsi *)sc, ie); 568 } 569 570 /* 571 * SCOP_EJECT 572 */ 573 scop_eject(intr, sc, slave, ie) 574 register int intr; 575 register struct scsi *sc; 576 register int slave; 577 register int ie; 578 { 579 scinit(sc, slave, DEV_BSIZE); 580 581 /* sc_cdb */ 582 sc->sc_opcode = SCOP_EJECT; 583 584 sc_go(intr, (struct scsi *)sc, ie); 585 } 586 587 /* 588 * SCOP_RBLIM request 589 */ 590 scop_rblim(intr, sc, slave, ie, count, param) 591 register int intr; 592 register struct scsi *sc; 593 register int slave; 594 register int ie; 595 register int count; 596 register caddr_t param; 597 { 598 scinit(sc, slave, DEV_BSIZE); 599 600 sc->sc_cpoint = (u_char *)param; 601 sc->sc_ctrnscnt = count & 0xff; 602 603 /* sc_cdb */ 604 sc->sc_opcode = SCOP_RBLIM; 605 606 sc_go(intr, (struct scsi *)sc, ie); 607 } 608 609 /* 610 * SCOP_MSENSE request 611 */ 612 scop_msense(intr, sc, slave, ie, count, param) 613 register int intr; 614 register struct scsi *sc; 615 register int slave; 616 register int ie; 617 register int count; 618 register caddr_t param; 619 { 620 scinit(sc, slave, DEV_BSIZE); 621 622 sc->sc_cpoint = (u_char *)param; 623 sc->sc_ctrnscnt = count & 0xff; 624 625 /* sc_cdb */ 626 sc->sc_opcode = SCOP_MSENSE; 627 sc->sc_lad = count >> 8; 628 sc->sc_count = count & 0xff; 629 630 sc_go(intr, (struct scsi *)sc, ie); 631 } 632 633 /* 634 * SCOP_MSELECT request 635 */ 636 scop_mselect(intr, sc, slave, ie, count, param) 637 register int intr; 638 register struct scsi *sc; 639 register int slave; 640 register int ie; 641 register int count; 642 register caddr_t param; 643 { 644 u_char psave[20]; 645 646 bcopy((caddr_t)sc->sc_param, (caddr_t)psave, 20); 647 scinit(sc, slave, DEV_BSIZE); 648 bcopy((caddr_t)psave, (caddr_t)sc->sc_param, 20); 649 650 sc->sc_cpoint = (u_char *)param; 651 sc->sc_ctrnscnt = count & 0xff; 652 653 /* sc_cdb */ 654 sc->sc_opcode = SCOP_MSELECT; 655 sc->sc_lad = count >> 8; 656 sc->sc_count = count & 0xff; 657 658 sc_go(intr, (struct scsi *)sc, ie); 659 } 660 661 #ifdef SRD_MSELECT 662 /* 663 * SCOP_MSELECT request 664 */ 665 scop_msense_OTHER_HD(intr, sc, slave, ie, count, param) 666 register int intr; 667 register struct scsi *sc; 668 register int slave; 669 register int ie; 670 register int count; 671 register caddr_t param; 672 { 673 scinit(sc, slave, DEV_BSIZE); 674 675 sc->sc_cpoint = (u_char *)param; 676 sc->sc_ctrnscnt = count; 677 678 /* sc_cdb */ 679 sc->sc_opcode = SCOP_MSENSE; 680 sc->sc_count = count; 681 sc->sc_lad = 0x3f00; 682 683 sc_go(intr, (struct scsi *)sc, ie); 684 } 685 686 /* 687 * SCOP_MSELECT request 688 */ 689 scop_mselect_OTHER_HD(intr, sc, slave, ie, count, param) 690 register int intr; 691 register struct scsi *sc; 692 register int slave; 693 register int ie; 694 register int count; 695 register caddr_t param; 696 { 697 u_char psave[20]; 698 699 bcopy((caddr_t)sc->sc_param, (caddr_t)psave, 20); 700 scinit(sc, slave, DEV_BSIZE); 701 bcopy((caddr_t)psave, (caddr_t)sc->sc_param, 20); 702 703 sc->sc_cpoint = (u_char *)param; 704 sc->sc_ctrnscnt = count; 705 706 /* sc_cdb */ 707 sc->sc_opcode = SCOP_MSELECT; 708 sc->sc_count = count; 709 sc->sc_lad = 0; 710 711 sc_go(intr, (struct scsi *)sc, ie); 712 } 713 #endif SRD_MSELECT 714 715 scop_erase(intr, sc, slave, ie) 716 register int intr; 717 register struct scsi *sc; 718 register int slave; 719 register int ie; 720 { 721 scinit(sc, slave, DEV_BSIZE); 722 723 /* sc_cdb */ 724 sc->sc_opcode = SCOP_ERASE; 725 sc->sc_tucode = 1; 726 727 sc_go(intr, (struct scsi *)sc, ie); 728 } 729 730 /* 731 * One sector programmed I/O 732 */ 733 scop_rdwr(intr, sc, slave, ie, flag, addr, lba, sectsize) 734 int intr; 735 register struct scsi *sc; 736 int slave; 737 int ie; 738 int flag; 739 caddr_t addr; 740 int lba; 741 int sectsize; 742 { 743 scinit(sc, slave, sectsize); 744 745 sc->sc_cpoint = (u_char *)addr; 746 sc->sc_ctrnscnt = sectsize; 747 748 /* sc_cdb */ 749 sc->sc_opcode = (flag & B_READ) ? SCOP_READ : SCOP_WRITE; 750 sc->sc_lad = lba; 751 sc->sc_count = 1; 752 753 sc_go(intr, sc, ie); 754 } 755 756 /* 757 * Medium allow/prevent removable 758 */ 759 scop_medrmv(intr, sc, slave, ie, sw) 760 register int intr; 761 register struct scsi *sc; 762 register int slave; 763 register int ie; 764 register int sw; 765 { 766 scinit(sc, slave, DEV_BSIZE); 767 768 /* sc_cdb */ 769 sc->sc_opcode = SCOP_MEDRMV; 770 sc->sc_count = sw; 771 772 sc_go(intr, (struct scsi *)sc, ie); 773 } 774 775 /* 776 * initialize struct scsi 777 */ 778 scinit(sc, slave, sectsize) 779 register struct scsi *sc; 780 int slave; 781 int sectsize; 782 { 783 bzero((caddr_t)sc, sizeof(struct scsi)); 784 785 sc->sc_identify = MSG_IDENT|Scsi_Disconnect|(slave & IDT_DRMASK); 786 sc->sc_bytesec = sectsize; 787 sc->sc_lun = slave; 788 } 789 790 791 /* 792 * ABORT MESSAGE 793 */ 794 scms_abort(intr, sc, slave, ie) 795 register int intr; 796 register struct scsi *sc; 797 register int slave; 798 register int ie; 799 { 800 bzero((caddr_t)sc, sizeof(struct scsi)); 801 802 sc->sc_identify = MSG_ABORT; 803 804 /* sc_cdb */ 805 sc->sc_opcode = SCOP_TST; 806 sc->sc_lun = slave; 807 808 sc_go(intr, (struct scsi *)sc, ie); 809 } 810 811 sc_go(intr, sc, ie) 812 int intr; 813 struct scsi *sc; 814 int ie; 815 { 816 register struct sc_data *scdp; 817 818 scdp = &sc_data[intr]; 819 820 if (sc->sc_cpoint) 821 scdp->scd_vaddr = (char *)sc->sc_cpoint; 822 else 823 scdp->scd_vaddr = (char *)sc->sc_param; 824 scdp->scd_procp = curproc; 825 scdp->scd_scaddr = (char *)sc; 826 scdp->scd_count = sc->sc_ctrnscnt; 827 sc->sc_cpoint = (u_char *)ipc_phys(scdp->scd_vaddr); 828 829 _sc_go(intr, sc, ie); 830 831 if((ie & SCSI_INTEN) == 0) { 832 #ifdef mips 833 /* if (DATAIN_PHASE_FINISHED) */ 834 MachFlushDCache(scdp->scd_scaddr, sizeof (struct scsi)); 835 if (MACH_IS_USPACE(scdp->scd_vaddr)) 836 panic("sc_go: user address is not supported"); 837 else if (MACH_IS_CACHED(scdp->scd_vaddr)) 838 MachFlushDCache(scdp->scd_vaddr, scdp->scd_count); 839 else if (MACH_IS_MAPPED(scdp->scd_vaddr)) 840 #ifdef notyet /* KU:XXX */ 841 clean_k2dcache(scdp->scd_vaddr, scdp->scd_count); 842 #else 843 MachFlushCache(); /* Flush all caches */ 844 #endif 845 #endif /* mips */ 846 } 847 } 848 849 #ifdef CPU_SINGLE 850 _sc_go(intr, sc, ie) 851 int intr; 852 struct scsi *sc; 853 int ie; 854 { 855 register int i, s; 856 857 if((ie & SCSI_INTEN) == 0) { 858 scsend(intr, ie|SCSI_NOTWAIT, sc); 859 while (sc_busy(intr)) { 860 splx(splscon()); /* splsc -1 */ 861 #ifdef mc68030 862 dcia(); 863 #endif 864 } 865 } else { 866 scsend(intr, ie, (caddr_t)sc); 867 } 868 } 869 #endif /* CPU_SINGLE */ 870 871 screset(chan) 872 int chan; 873 { 874 int i, s; 875 876 s = splsc(); 877 printf("SCSI: screset() called "); 878 scop_init(chan / 8); 879 splx(s); 880 881 for (s = 0; s < 10; s++) { 882 DELAY(100000 * 10); 883 } 884 printf("\n"); 885 iop/**/reset(); 886 } 887 888 scsisetup(bp, map, nmap) 889 struct buf *bp; 890 struct sc_map *map; 891 int nmap; 892 { 893 return (iop/**/setup(bp, map, nmap)); 894 } 895 896 897 /* 898 * transrate skey / ecode into message display ON/OFF value 899 * 1 : display message 900 * 0 : silence 901 */ 902 isdispmsg(code, list, count) 903 register int code; 904 register struct msg_list *list; 905 int count; 906 { 907 register int msglvl = 0; 908 909 while (list->ml_code >= 0) { 910 if (code == list->ml_code) { 911 msglvl = list->ml_msglvl; 912 break; 913 } 914 list++; 915 } 916 return (count >= msglvl); 917 } 918 919 #ifdef NO_SHRINK_RSENSE_MSG 920 /* 921 * transrate skey / ecode into message 922 */ 923 char * 924 getmsg(code, list, defmsg) 925 int code; 926 struct msg_list *list; 927 char *defmsg; 928 { 929 while (list->ml_code >= 0) { 930 if (code == list->ml_code) 931 return (list->ml_msgstr); 932 list++; 933 } 934 return (defmsg); 935 } 936 #endif /* NO_SHRINK_RSENSE_MSG */ 937 938 check_chan_busy(intr, sc, slave) 939 register int intr; 940 register struct scsi *sc; 941 register int slave; 942 { 943 register struct sc_extnd *sce = (struct sc_extnd *)sc->sc_param; 944 int i = 0; 945 946 if (sc->sc_istatus == INST_EP) { 947 switch (sc->sc_tstatus) { 948 949 case TGST_CC: 950 scop_rsense(intr, sc, slave, SCSI_INTDIS, 18, 0); 951 if (rsense_msg_disp || 952 isdispmsg(sce->sce_skey, skeylist, 0)) { 953 #ifdef NO_SHRINK_RSENSE_MSG 954 if (sce->sce_advalid) { 955 printf("SCSI%d(block %d): %s (sense key = 0x%x)\n", 956 intr, 957 (sce->sce_infob1 << 24) + 958 (sce->sce_infob2 << 16) + 959 (sce->sce_infob3 << 8) + 960 (sce->sce_infob4), 961 getmsg(sce->sce_skey, skeylist, "(reserved)"), 962 sce->sce_skey); 963 } else { 964 printf("SCSI%d(unknown block): %s (sense key = 0x%x)\n", 965 intr, 966 getmsg(sce->sce_skey, skeylist, "(reserved)"), 967 sce->sce_skey); 968 } 969 #else /* NO_SHRINK_RSENSE_MSG */ 970 if (sce->sce_advalid) { 971 printf("SCSI%d(sn %d): skey=0x%x)\n", 972 intr, 973 (sce->sce_infob1 << 24) + 974 (sce->sce_infob2 << 16) + 975 (sce->sce_infob3 << 8) + 976 (sce->sce_infob4), 977 sce->sce_skey); 978 } else { 979 printf("SCSI%d: skey=0x%x)\n", 980 intr, sce->sce_skey); 981 } 982 #endif /* NO_SHRINK_RSENSE_MSG */ 983 printf("sense data = "); 984 for (i = 0; i < 18; i++) 985 printf("%x ", sc->sc_param[i]); 986 printf("\n"); 987 } 988 break; 989 990 case TGST_GOOD: 991 break; 992 993 default: 994 printf("SCSI%d: bad target status 0x%x\n", intr, sc->sc_tstatus); 995 break; 996 } 997 } else { 998 printf("SCSI%d: bad initiator status 0x%x\n", intr, sc->sc_istatus); 999 } 1000 1001 while (i++ < 100000) { 1002 scop_tst(intr, sc, slave, SCSI_INTDIS); 1003 if (sc->sc_tstatus != TGST_BUSY) 1004 break; 1005 } 1006 if (i > 100000) 1007 printf("SCSI%d: still busy after rasblk.\n", intr); 1008 } 1009 1010 /***/ 1011 struct scsi_berr_bug_table { 1012 int model; 1013 int serial_l; 1014 int serial_h; 1015 int value; /* 1:BUG, 0:NOBUG */ 1016 }; 1017 /***/ 1018