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