1 /* $NetBSD: sc.c,v 1.14 2015/02/14 13:07:39 tsutsui Exp $ */ 2 3 /* 4 * Copyright (c) 1992 OMRON Corporation. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * OMRON Corporation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)sc.c 8.1 (Berkeley) 6/10/93 38 */ 39 /* 40 * Copyright (c) 1992, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * This code is derived from software contributed to Berkeley by 44 * OMRON Corporation. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 * 70 * @(#)sc.c 8.1 (Berkeley) 6/10/93 71 */ 72 73 /* 74 * sc.c -- SCSI Protocole Controller (SPC) driver 75 * remaked by A.Fujita, MAR-11-199 76 */ 77 78 79 #define NSC 2 80 81 #include <sys/param.h> 82 #include <luna68k/stand/boot/samachdep.h> 83 #include <luna68k/stand/boot/scsireg.h> 84 #include <luna68k/stand/boot/scsivar.h> 85 86 #define SCSI_ID 7 87 88 static void screset(struct scsi_softc *); 89 static void scprobe(struct scsi_softc *, uint, uint); 90 static int issue_select(struct scsidevice *, uint8_t); 91 static void ixfer_start(struct scsidevice *, int, uint8_t, int); 92 static void ixfer_out(struct scsidevice *, int, uint8_t *); 93 static void ixfer_in(struct scsidevice *, int, uint8_t *); 94 static int scrun(int, int, uint8_t *, int, uint8_t *, int, volatile int *); 95 static int scfinish(int); 96 static void scabort(struct scsi_softc *); 97 98 struct scsi_softc scsi_softc[NSC]; 99 100 /* 101 * Initialize SPC & Data Structure 102 */ 103 104 int 105 scinit(int ctlr, void *addr) 106 { 107 struct scsi_softc *hs; 108 uint id; 109 110 if (ctlr < 0 || ctlr >= NSC) 111 return 0; 112 113 hs = &scsi_softc[ctlr]; 114 hs->sc_ctlr = ctlr; 115 hs->sc_spc = addr; 116 117 hs->sc_flags = 0; 118 hs->sc_phase = BUS_FREE_PHASE; 119 hs->sc_target = SCSI_ID; 120 121 hs->sc_cdb = NULL; 122 hs->sc_cdblen = 0; 123 hs->sc_buf = NULL; 124 hs->sc_len = 0; 125 hs->sc_lock = NULL; 126 127 hs->sc_stat = 0; 128 hs->sc_msg[0] = 0; 129 130 screset(hs); 131 132 for (id = 0; id < 7; id++) 133 scprobe(hs, id, 0); 134 135 return 1; 136 } 137 138 static void 139 screset(struct scsi_softc *hs) 140 { 141 struct scsidevice *hd = hs->sc_spc; 142 143 printf("sc%d at 0x%08lx: ", hs->sc_ctlr, (u_long)hs->sc_spc); 144 145 /* 146 * Disable interrupts then reset the FUJI chip. 147 */ 148 149 hd->scsi_sctl = SCTL_DISABLE | SCTL_CTRLRST; 150 hd->scsi_scmd = 0; 151 hd->scsi_pctl = 0; 152 hd->scsi_temp = 0; 153 hd->scsi_tch = 0; 154 hd->scsi_tcm = 0; 155 hd->scsi_tcl = 0; 156 hd->scsi_ints = 0; 157 158 /* We can use Asynchronous Transfer only */ 159 printf("async"); 160 161 /* 162 * Configure MB89352 with its SCSI address, all 163 * interrupts enabled & appropriate parity. 164 */ 165 hd->scsi_bdid = SCSI_ID; 166 hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB| 167 SCTL_PARITY_ENAB | SCTL_RESEL_ENAB | 168 SCTL_INTR_ENAB; 169 printf(", parity"); 170 171 DELAY(400); 172 hd->scsi_sctl &= ~SCTL_DISABLE; 173 174 printf(", ID %d\n", SCSI_ID); 175 } 176 177 bool 178 scident(uint ctlr, uint target, uint lun, struct scsi_inquiry *inqout, 179 uint32_t *capout) 180 { 181 struct scsi_inquiry inqbuf; 182 struct scsi_generic_cdb inq = { 183 6, 184 { CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0 } 185 }; 186 uint32_t capbuf[2]; 187 struct scsi_generic_cdb cap = { 188 10, 189 { CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 190 }; 191 int i; 192 int tries = 10; 193 194 /* 195 * See if unit exists and is a disk then read block size & nblocks. 196 */ 197 while ((i = scsi_test_unit_rdy(ctlr, target, lun)) != 0) { 198 if (i < 0 || --tries < 0) 199 return false; 200 if (i == STS_CHECKCOND) { 201 uint8_t sensebuf[8]; 202 struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf; 203 204 scsi_request_sense(ctlr, target, lun, sensebuf, 8); 205 if (sp->class == 7 && sp->key == 6) 206 /* drive doing an RTZ -- give it a while */ 207 DELAY(1000000); 208 } 209 DELAY(1000); 210 } 211 if (scsi_immed_command(ctlr, target, lun, &inq, (uint8_t *)&inqbuf, 212 sizeof(inqbuf)) || 213 scsi_immed_command(ctlr, target, lun, &cap, (uint8_t *)&capbuf, 214 sizeof(capbuf))) 215 /* doesn't exist or not a CCS device */ 216 return false; 217 218 switch (inqbuf.type) { 219 case 0: /* disk */ 220 case 4: /* WORM */ 221 case 5: /* CD-ROM */ 222 case 7: /* Magneto-optical */ 223 break; 224 default: /* not a disk */ 225 return false; 226 } 227 228 if (inqout != NULL) 229 *inqout = inqbuf; 230 if (capout != NULL) { 231 /* assume big endian */ 232 capout[0] = capbuf[0]; 233 capout[1] = capbuf[1]; 234 } 235 236 return true; 237 } 238 239 static void 240 scprobe(struct scsi_softc *hs, uint target, uint lun) 241 { 242 struct scsi_inquiry inqbuf; 243 uint32_t capbuf[2]; 244 char idstr[32]; 245 int i; 246 247 if (!scident(hs->sc_ctlr, target, lun, &inqbuf, capbuf)) 248 return; 249 250 memcpy(idstr, &inqbuf.vendor_id, 28); 251 for (i = 27; i > 23; --i) 252 if (idstr[i] != ' ') 253 break; 254 idstr[i + 1] = '\0'; 255 for (i = 23; i > 7; --i) 256 if (idstr[i] != ' ') 257 break; 258 idstr[i + 1] = '\0'; 259 for (i = 7; i >= 0; --i) 260 if (idstr[i] != ' ') 261 break; 262 idstr[i + 1] = '\0'; 263 264 printf(" ID %d: %s %s rev %s", target, idstr, &idstr[8], &idstr[24]); 265 printf(", %d bytes/sect x %d sectors\n", capbuf[1], capbuf[0]); 266 } 267 268 269 /* 270 * SPC Arbitration/Selection routine 271 */ 272 273 static int 274 issue_select(struct scsidevice *hd, uint8_t target) 275 { 276 277 hd->scsi_pctl = 0; 278 hd->scsi_temp = (1 << SCSI_ID) | (1 << target); 279 280 /* select timeout is hardcoded to 250ms */ 281 hd->scsi_tch = 2; 282 hd->scsi_tcm = 113; 283 hd->scsi_tcl = 3; 284 285 hd->scsi_scmd = SCMD_SELECT; 286 287 return 1; 288 } 289 290 291 /* 292 * SPC Manual Transfer routines 293 */ 294 295 /* not yet */ 296 297 298 /* 299 * SPC Program Transfer routines 300 */ 301 302 static void 303 ixfer_start(struct scsidevice *hd, int len, uint8_t phase, int wait) 304 { 305 306 hd->scsi_tch = ((len & 0xff0000) >> 16); 307 hd->scsi_tcm = ((len & 0x00ff00) >> 8); 308 hd->scsi_tcl = (len & 0x0000ff); 309 hd->scsi_pctl = phase; 310 hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR; 311 } 312 313 static void 314 ixfer_out(struct scsidevice *hd, int len, uint8_t *buf) 315 { 316 317 for (; len > 0; len--) { 318 while (hd->scsi_ssts & SSTS_DREG_FULL) { 319 DELAY(5); 320 } 321 hd->scsi_dreg = *buf++; 322 } 323 } 324 325 static void 326 ixfer_in(struct scsidevice *hd, int len, uint8_t *buf) 327 { 328 329 for (; len > 0; len--) { 330 while (hd->scsi_ssts & SSTS_DREG_EMPTY) { 331 DELAY(5); 332 } 333 *buf++ = hd->scsi_dreg; 334 } 335 } 336 337 338 /* 339 * SPC drive routines 340 */ 341 342 static int 343 scrun(int ctlr, int target, uint8_t *cdb, int cdblen, uint8_t *buf, int len, 344 volatile int *lock) 345 { 346 struct scsi_softc *hs; 347 struct scsidevice *hd; 348 349 if (ctlr < 0 || ctlr >= NSC) 350 return 0; 351 352 hs = &scsi_softc[ctlr]; 353 hd = hs->sc_spc; 354 if (hd == NULL) 355 return 0; 356 357 if ((hd->scsi_ssts & (SSTS_INITIATOR | SSTS_TARGET | SSTS_BUSY)) != 0) 358 return 0; 359 360 hs->sc_flags = 0; 361 hs->sc_phase = ARB_SEL_PHASE; 362 hs->sc_target = target; 363 364 hs->sc_cdb = cdb; 365 hs->sc_cdblen = cdblen; 366 hs->sc_buf = buf; 367 hs->sc_len = len; 368 hs->sc_lock = lock; 369 370 hs->sc_stat = 0; 371 hs->sc_msg[0] = 0; 372 373 *(hs->sc_lock) = SC_IN_PROGRESS; 374 issue_select(hd, hs->sc_target); 375 376 return 1; 377 } 378 379 static int 380 scfinish(int ctlr) 381 { 382 struct scsi_softc *hs = &scsi_softc[ctlr]; 383 int status = hs->sc_stat; 384 385 hs->sc_flags = 0; 386 hs->sc_phase = BUS_FREE_PHASE; 387 hs->sc_target = SCSI_ID; 388 389 hs->sc_cdb = NULL; 390 hs->sc_cdblen = 0; 391 hs->sc_buf = NULL; 392 hs->sc_len = 0; 393 hs->sc_lock = NULL; 394 395 hs->sc_stat = 0; 396 hs->sc_msg[0] = 0; 397 398 return status; 399 } 400 401 static void 402 scabort(struct scsi_softc *hs) 403 { 404 struct scsidevice *hd = hs->sc_spc; 405 int len; 406 407 printf("sc%d: abort phase=0x%x, ssts=0x%x, ints=0x%x\n", 408 hs->sc_ctlr, hd->scsi_psns, hd->scsi_ssts, hd->scsi_ints); 409 410 if (hd->scsi_ints != 0) 411 hd->scsi_ints = hd->scsi_ints; 412 413 if (hd->scsi_psns == 0 || (hd->scsi_ssts & SSTS_INITIATOR) == 0) 414 /* no longer connected to scsi target */ 415 return; 416 417 /* get the number of bytes remaining in current xfer + fudge */ 418 len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | hd->scsi_tcl; 419 420 /* for that many bus cycles, try to send an abort msg */ 421 for (len += 1024; 422 ((hd->scsi_ssts & SSTS_INITIATOR)) != 0 && --len >= 0;) { 423 hd->scsi_scmd = SCMD_SET_ATN; 424 425 while ((hd->scsi_psns & PSNS_REQ) == 0) { 426 if ((hd->scsi_ssts & SSTS_INITIATOR) == 0) 427 goto out; 428 DELAY(1); 429 } 430 431 if ((hd->scsi_psns & PHASE) == MESG_OUT_PHASE) 432 hd->scsi_scmd = SCMD_RST_ATN; 433 hd->scsi_pctl = hs->sc_phase = hd->scsi_psns & PHASE; 434 435 if (hd->scsi_psns & PHASE_IO) { 436 /* one of the input phases - read & discard a byte */ 437 hd->scsi_scmd = SCMD_SET_ACK; 438 while ((hd->scsi_psns & PSNS_REQ) != 0) 439 DELAY(1); 440 (void)hd->scsi_temp; 441 } else { 442 /* one of the output phases - send an abort msg */ 443 hd->scsi_temp = MSG_ABORT; 444 hd->scsi_scmd = SCMD_SET_ACK; 445 while ((hd->scsi_psns & PSNS_REQ) != 0) 446 DELAY(1); 447 } 448 449 hd->scsi_scmd = SCMD_RST_ACK; 450 } 451 out: 452 /* 453 * Either the abort was successful & the bus is disconnected or 454 * the device didn't listen. If the latter, announce the problem. 455 * Either way, reset the card & the SPC. 456 */ 457 if (len < 0 && hs) 458 printf("sc%d: abort failed. phase=0x%x, ssts=0x%x\n", 459 hs->sc_ctlr, hd->scsi_psns, hd->scsi_ssts); 460 } 461 462 463 /* 464 * SCSI Command Handler 465 */ 466 467 int 468 scsi_test_unit_rdy(int ctlr, int target, int lun) 469 { 470 static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY }; 471 int status; 472 volatile int lock; 473 474 #ifdef DEBUG 475 printf("scsi_test_unit_rdy( %d, %d, %d): Start\n", ctlr, target, lun); 476 #endif 477 478 cdb.lun = lun; 479 480 if (scrun(ctlr, target, (void *)&cdb, 6, NULL, 0, &lock) == 0) { 481 #ifdef DEBUG 482 printf("scsi_test_unit_rdy: Command Transfer Failed.\n"); 483 #endif 484 return -1; 485 } 486 487 while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) 488 DELAY(10); 489 490 status = scfinish(ctlr); 491 492 if (lock == SC_IO_COMPLETE) { 493 #ifdef DEBUG 494 printf("scsi_test_unit_rdy: Status -- 0x%x\n", status); 495 #endif 496 return status; 497 } else { 498 return lock; 499 } 500 } 501 502 int 503 scsi_request_sense(int ctlr, int target, int lun, uint8_t *buf, 504 unsigned int len) 505 { 506 static struct scsi_cdb6 cdb = { CMD_REQUEST_SENSE }; 507 int status; 508 volatile int lock; 509 510 #ifdef DEBUG 511 printf("scsi_request_sense: Start\n"); 512 #endif 513 514 /* Request Senseの場合、転送されるデータ長はターゲットに依存し、 */ 515 /* センスデータの8バイト目のAdditional Sens Lengthにより動的に決定する。*/ 516 /* ここではデーター転送数をcdbのAllocation Lengthに最低長である8バイト */ 517 /* を固定して、SPCの処理シーケンスを崩さないようにしている。 */ 518 519 /* テープユニットの状態を調べるため、Addtional Sens Fieldをアクセスする */ 520 /* 必要があるのでデバイスドライバ側でlenを決定することにする */ 521 522 cdb.lun = lun; 523 cdb.len = len; 524 525 if (scrun(ctlr, target, (void *)&cdb, 6, buf, len, &lock) == 0) { 526 #ifdef DEBUG 527 printf("scsi_request_sense: Command Transfer Failed.\n"); 528 #endif 529 return -1; 530 } 531 532 while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) 533 DELAY(10); 534 535 status = scfinish(ctlr); 536 537 if (lock == SC_IO_COMPLETE) { 538 #ifdef DEBUG 539 printf("scsi_request_sense: Status -- 0x%x\n", status); 540 #endif 541 return status; 542 } else { 543 return lock; 544 } 545 } 546 547 int 548 scsi_immed_command(int ctlr, int target, int lun, struct scsi_generic_cdb *cdb, 549 uint8_t *buf, unsigned int len) 550 { 551 int status; 552 volatile int lock; 553 554 #ifdef DEBUG 555 printf("scsi_immed_command( %d, %d, %d, cdb(%d), buf, %d): Start\n", 556 ctlr, target, lun, cdb->len, len); 557 #endif 558 559 cdb->cdb[1] |= lun << 5; 560 561 if (scrun(ctlr, target, (void *)&cdb->cdb[0], cdb->len, buf, len, 562 &lock) == 0) { 563 #ifdef DEBUG 564 printf("scsi_immed_command: Command Transfer Failed.\n"); 565 #endif 566 return -1; 567 } 568 569 while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) 570 DELAY(10); 571 572 status = scfinish(ctlr); 573 574 if (lock == SC_IO_COMPLETE) { 575 #ifdef DEBUG 576 printf("scsi_immed_command: Status -- 0x%x\n", status); 577 #endif 578 return status; 579 } else { 580 return lock; 581 } 582 } 583 584 int 585 scsi_format_unit(int ctlr, int target, int lun) 586 { 587 static struct scsi_cdb6 cdb = { CMD_FORMAT_UNIT, 0, 0, 0, 0, 0 }; 588 int status; 589 volatile int lock; 590 #ifdef DEBUG 591 int count = 0; 592 #endif 593 594 #ifdef DEBUG 595 printf("scsi_format_unit( %d, %d, %d): Start\n", ctlr, target, lun); 596 #endif 597 598 cdb.lun = lun; 599 600 if (scrun(ctlr, target, (void *)&cdb, 6, NULL, 0, &lock) == 0) { 601 #ifdef DEBUG 602 printf("scsi_format_unit: Command Transfer Failed.\n"); 603 #endif 604 return -1; 605 } 606 607 while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) { 608 DELAY(1000000); 609 #ifdef DEBUG 610 if ((++count % 60) == 0) 611 printf("scsi_format_unit: %d\n", count / 60); 612 #endif 613 } 614 615 status = scfinish(ctlr); 616 617 if (lock == SC_IO_COMPLETE) { 618 #ifdef DEBUG 619 printf("scsi_format_unit: Status -- 0x%x\n", status); 620 #endif 621 return status; 622 } else { 623 return lock; 624 } 625 } 626 627 628 /* 629 * Interrupt Routine 630 */ 631 632 int 633 scintr(void) 634 { 635 struct scsi_softc *hs; 636 struct scsidevice *hd; 637 uint8_t ints, temp; 638 int i; 639 uint8_t *buf; 640 int len; 641 642 for (i = 0; i < NSC; i++) { 643 hs = &scsi_softc[i]; 644 hd = hs->sc_spc; 645 if ((ints = hd->scsi_ints) != 0) 646 goto get_intr; 647 } 648 649 /* Unknown Interrupt occured */ 650 return -1; 651 652 653 /* 654 * Interrupt 655 */ 656 657 get_intr: 658 #ifdef DEBUG 659 printf("scintr: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x 0x%x\n", 660 ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns, hs->sc_phase); 661 #endif 662 if (ints & INTS_RESEL) { 663 if (hs->sc_phase == BUS_FREE_PHASE) { 664 temp = hd->scsi_temp & ~(1 << SCSI_ID); 665 for (i = 0; temp != 1; i++) { 666 temp >>= 1; 667 } 668 hs->sc_target = i; 669 *(hs->sc_lock) = SC_IN_PROGRESS; 670 } else 671 goto abort; 672 } else if (ints & INTS_DISCON) { 673 if ((hs->sc_msg[0] == MSG_CMD_COMPLETE) || 674 (hs->sc_msg[0] == MSG_DISCONNECT)) { 675 hs->sc_phase = BUS_FREE_PHASE; 676 hs->sc_target = SCSI_ID; 677 if (hs->sc_msg[0] == MSG_CMD_COMPLETE) { 678 /* SCSI IO complete */ 679 *(hs->sc_lock) = SC_IO_COMPLETE; 680 } else { 681 /* Disconnected from Target */ 682 *(hs->sc_lock) = SC_DISCONNECTED; 683 } 684 hd->scsi_ints = ints; 685 return 0; 686 } else 687 goto abort; 688 } else if (ints & INTS_CMD_DONE) { 689 if (hs->sc_phase == BUS_FREE_PHASE) 690 goto abort; 691 else if (hs->sc_phase == MESG_IN_PHASE) { 692 hd->scsi_scmd = SCMD_RST_ACK; 693 hd->scsi_ints = ints; 694 hs->sc_phase = hd->scsi_psns & PHASE; 695 return 0; 696 } 697 if (hs->sc_flags & SC_SEL_TIMEOUT) 698 hs->sc_flags &= ~SC_SEL_TIMEOUT; 699 } else if (ints & INTS_SRV_REQ) { 700 if (hs->sc_phase != MESG_IN_PHASE) 701 goto abort; 702 } else if (ints & INTS_TIMEOUT) { 703 if (hs->sc_phase == ARB_SEL_PHASE) { 704 if (hs->sc_flags & SC_SEL_TIMEOUT) { 705 hs->sc_flags &= ~SC_SEL_TIMEOUT; 706 hs->sc_phase = BUS_FREE_PHASE; 707 hs->sc_target = SCSI_ID; 708 /* Such SCSI Device is not connected. */ 709 *(hs->sc_lock) = SC_DEV_NOT_FOUND; 710 hd->scsi_ints = ints; 711 return 0; 712 } else { 713 /* wait more 250 usec */ 714 hs->sc_flags |= SC_SEL_TIMEOUT; 715 hd->scsi_temp = 0; 716 hd->scsi_tch = 0; 717 hd->scsi_tcm = 0x06; 718 hd->scsi_tcl = 0x40; 719 hd->scsi_ints = ints; 720 return 0; 721 } 722 } else 723 goto abort; 724 } else 725 goto abort; 726 727 hd->scsi_ints = ints; 728 729 /* 730 * Next SCSI Transfer 731 */ 732 733 while ((hd->scsi_psns & PSNS_REQ) == 0) { 734 DELAY(1); 735 } 736 737 hs->sc_phase = hd->scsi_psns & PHASE; 738 739 if ((hs->sc_phase == DATA_OUT_PHASE) || 740 (hs->sc_phase == DATA_IN_PHASE)) { 741 len = hs->sc_len; 742 buf = hs->sc_buf; 743 } else if (hs->sc_phase == CMD_PHASE) { 744 len = hs->sc_cdblen; 745 buf = hs->sc_cdb; 746 } else if (hs->sc_phase == STATUS_PHASE) { 747 len = 1; 748 buf = &hs->sc_stat; 749 } else { 750 len = 1; 751 buf = hs->sc_msg; 752 } 753 754 ixfer_start(hd, len, hs->sc_phase, 0); 755 if (hs->sc_phase & PHASE_IO) 756 ixfer_in(hd, len, buf); 757 else 758 ixfer_out(hd, len, buf); 759 760 return 0; 761 762 /* 763 * SCSI Abort 764 */ 765 abort: 766 /* SCSI IO failed */ 767 scabort(hs); 768 hd->scsi_ints = ints; 769 *(hs->sc_lock) = SC_IO_FAILED; 770 return -1; 771 } 772