1 /* $NetBSD: sci.c,v 1.22 2000/01/18 19:33:32 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1994 Michael L. Hitch 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Van Jacobson of Lawrence Berkeley Laboratory. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)scsi.c 7.5 (Berkeley) 5/4/91 40 */ 41 42 /* 43 * AMIGA NCR 5380 scsi adaptor driver 44 */ 45 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/device.h> 49 #include <sys/disklabel.h> 50 #include <sys/dkstat.h> 51 #include <sys/buf.h> 52 #include <dev/scsipi/scsi_all.h> 53 #include <dev/scsipi/scsipi_all.h> 54 #include <dev/scsipi/scsiconf.h> 55 #include <vm/vm.h> 56 #include <vm/vm_kern.h> 57 #include <vm/vm_page.h> 58 #include <machine/pmap.h> 59 #include <machine/cpu.h> 60 #include <amiga/amiga/device.h> 61 #include <amiga/amiga/custom.h> 62 #include <amiga/amiga/isr.h> 63 #include <amiga/dev/scireg.h> 64 #include <amiga/dev/scivar.h> 65 66 /* 67 * SCSI delays 68 * In u-seconds, primarily for state changes on the SPC. 69 */ 70 #define SCI_CMD_WAIT 50000 /* wait per step of 'immediate' cmds */ 71 #define SCI_DATA_WAIT 50000 /* wait per data in/out step */ 72 #define SCI_INIT_WAIT 50000 /* wait per step (both) during init */ 73 74 int sciicmd __P((struct sci_softc *, int, void *, int, void *, int,u_char)); 75 int scigo __P((struct sci_softc *, struct scsipi_xfer *)); 76 int scigetsense __P((struct sci_softc *, struct scsipi_xfer *)); 77 int sciselectbus __P((struct sci_softc *, u_char, u_char)); 78 void sciabort __P((struct sci_softc *, char *)); 79 void scierror __P((struct sci_softc *, u_char)); 80 void scisetdelay __P((int)); 81 void sci_scsidone __P((struct sci_softc *, int)); 82 void sci_donextcmd __P((struct sci_softc *)); 83 int sci_ixfer_out __P((struct sci_softc *, int, register u_char *, int)); 84 void sci_ixfer_in __P((struct sci_softc *, int, register u_char *, int)); 85 86 int sci_cmd_wait = SCI_CMD_WAIT; 87 int sci_data_wait = SCI_DATA_WAIT; 88 int sci_init_wait = SCI_INIT_WAIT; 89 90 int sci_no_dma = 0; 91 92 #ifdef DEBUG 93 #define QPRINTF(a) if (sci_debug > 1) printf a 94 int sci_debug = 0; 95 #else 96 #define QPRINTF(a) 97 #endif 98 99 /* 100 * default minphys routine for sci based controllers 101 */ 102 void 103 sci_minphys(bp) 104 struct buf *bp; 105 { 106 107 /* 108 * No max transfer at this level. 109 */ 110 minphys(bp); 111 } 112 113 /* 114 * used by specific sci controller 115 * 116 * it appears that the higher level code does nothing with LUN's 117 * so I will too. I could plug it in, however so could they 118 * in scsi_scsipi_cmd(). 119 */ 120 int 121 sci_scsicmd(xs) 122 struct scsipi_xfer *xs; 123 { 124 struct sci_pending *pendp; 125 struct sci_softc *dev; 126 struct scsipi_link *slp; 127 int flags, s; 128 129 slp = xs->sc_link; 130 dev = slp->adapter_softc; 131 flags = xs->xs_control; 132 133 if (flags & XS_CTL_DATA_UIO) 134 panic("sci: scsi data uio requested"); 135 136 if (dev->sc_xs && flags & XS_CTL_POLL) 137 panic("sci_scsicmd: busy"); 138 139 s = splbio(); 140 pendp = &dev->sc_xsstore[slp->scsipi_scsi.target][slp->scsipi_scsi.lun]; 141 if (pendp->xs) { 142 splx(s); 143 return(TRY_AGAIN_LATER); 144 } 145 146 if (dev->sc_xs) { 147 pendp->xs = xs; 148 TAILQ_INSERT_TAIL(&dev->sc_xslist, pendp, link); 149 splx(s); 150 return(SUCCESSFULLY_QUEUED); 151 } 152 pendp->xs = NULL; 153 dev->sc_xs = xs; 154 splx(s); 155 156 /* 157 * nothing is pending do it now. 158 */ 159 sci_donextcmd(dev); 160 161 if (flags & XS_CTL_POLL) 162 return(COMPLETE); 163 return(SUCCESSFULLY_QUEUED); 164 } 165 166 /* 167 * entered with dev->sc_xs pointing to the next xfer to perform 168 */ 169 void 170 sci_donextcmd(dev) 171 struct sci_softc *dev; 172 { 173 struct scsipi_xfer *xs; 174 struct scsipi_link *slp; 175 int flags, phase, stat; 176 177 xs = dev->sc_xs; 178 slp = xs->sc_link; 179 flags = xs->xs_control; 180 181 if (flags & XS_CTL_DATA_IN) 182 phase = DATA_IN_PHASE; 183 else if (flags & XS_CTL_DATA_OUT) 184 phase = DATA_OUT_PHASE; 185 else 186 phase = STATUS_PHASE; 187 188 if (flags & XS_CTL_RESET) 189 scireset(dev); 190 191 dev->sc_stat[0] = -1; 192 xs->cmd->bytes[0] |= slp->scsipi_scsi.lun << 5; 193 if (phase == STATUS_PHASE || flags & XS_CTL_POLL) 194 stat = sciicmd(dev, slp->scsipi_scsi.target, xs->cmd, xs->cmdlen, 195 xs->data, xs->datalen, phase); 196 else if (scigo(dev, xs) == 0) 197 return; 198 else 199 stat = dev->sc_stat[0]; 200 201 sci_scsidone(dev, stat); 202 } 203 204 void 205 sci_scsidone(dev, stat) 206 struct sci_softc *dev; 207 int stat; 208 { 209 struct sci_pending *pendp; 210 struct scsipi_xfer *xs; 211 int s, donext; 212 213 xs = dev->sc_xs; 214 #ifdef DIAGNOSTIC 215 if (xs == NULL) 216 panic("sci_scsidone"); 217 #endif 218 /* 219 * is this right? 220 */ 221 xs->status = stat; 222 223 if (stat == 0) 224 xs->resid = 0; 225 else { 226 switch(stat) { 227 case SCSI_CHECK: 228 stat = scigetsense(dev, xs); 229 if (stat != 0) 230 goto bad_sense; 231 xs->error = XS_SENSE; 232 break; 233 case SCSI_BUSY: 234 xs->error = XS_BUSY; 235 break; 236 bad_sense: 237 default: 238 xs->error = XS_DRIVER_STUFFUP; 239 QPRINTF(("sci_scsicmd() bad %x\n", stat)); 240 break; 241 } 242 } 243 244 xs->xs_status |= XS_STS_DONE; 245 246 /* 247 * grab next command before scsipi_done() 248 * this way no single device can hog scsi resources. 249 */ 250 s = splbio(); 251 pendp = dev->sc_xslist.tqh_first; 252 if (pendp == NULL) { 253 donext = 0; 254 dev->sc_xs = NULL; 255 } else { 256 donext = 1; 257 TAILQ_REMOVE(&dev->sc_xslist, pendp, link); 258 dev->sc_xs = pendp->xs; 259 pendp->xs = NULL; 260 } 261 splx(s); 262 scsipi_done(xs); 263 264 if (donext) 265 sci_donextcmd(dev); 266 } 267 268 int 269 scigetsense(dev, xs) 270 struct sci_softc *dev; 271 struct scsipi_xfer *xs; 272 { 273 struct scsipi_sense rqs; 274 struct scsipi_link *slp; 275 276 slp = xs->sc_link; 277 278 rqs.opcode = REQUEST_SENSE; 279 rqs.byte2 = slp->scsipi_scsi.lun << 5; 280 #ifdef not_yet 281 rqs.length = xs->req_sense_length ? xs->req_sense_length : 282 sizeof(xs->sense.scsi_sense); 283 #else 284 rqs.length = sizeof(xs->sense.scsi_sense); 285 #endif 286 287 rqs.unused[0] = rqs.unused[1] = rqs.control = 0; 288 289 return(sciicmd(dev, slp->scsipi_scsi.target, &rqs, sizeof(rqs), 290 &xs->sense.scsi_sense, 291 rqs.length, DATA_IN_PHASE)); 292 } 293 294 void 295 sciabort(dev, where) 296 struct sci_softc *dev; 297 char *where; 298 { 299 printf ("%s: abort %s: csr = 0x%02x, bus = 0x%02x\n", 300 dev->sc_dev.dv_xname, where, *dev->sci_csr, *dev->sci_bus_csr); 301 302 if (dev->sc_flags & SCI_SELECTED) { 303 304 /* lets just hope it worked.. */ 305 dev->sc_flags &= ~SCI_SELECTED; 306 /* XXX */ 307 scireset (dev); 308 } 309 } 310 311 /* 312 * XXX Set/reset long delays. 313 * 314 * if delay == 0, reset default delays 315 * if delay < 0, set both delays to default long initialization values 316 * if delay > 0, set both delays to this value 317 * 318 * Used when a devices is expected to respond slowly (e.g. during 319 * initialization). 320 */ 321 void 322 scisetdelay(del) 323 int del; 324 { 325 static int saved_cmd_wait, saved_data_wait; 326 327 if (del) { 328 saved_cmd_wait = sci_cmd_wait; 329 saved_data_wait = sci_data_wait; 330 if (del > 0) 331 sci_cmd_wait = sci_data_wait = del; 332 else 333 sci_cmd_wait = sci_data_wait = sci_init_wait; 334 } else { 335 sci_cmd_wait = saved_cmd_wait; 336 sci_data_wait = saved_data_wait; 337 } 338 } 339 340 void 341 scireset(dev) 342 struct sci_softc *dev; 343 { 344 u_int s; 345 u_char my_id; 346 347 dev->sc_flags &= ~SCI_SELECTED; 348 if (dev->sc_flags & SCI_ALIVE) 349 sciabort(dev, "reset"); 350 351 printf("%s: ", dev->sc_dev.dv_xname); 352 353 s = splbio(); 354 /* preserve our ID for now */ 355 my_id = 7; 356 357 /* 358 * Reset the chip 359 */ 360 *dev->sci_icmd = SCI_ICMD_TEST; 361 *dev->sci_icmd = SCI_ICMD_TEST | SCI_ICMD_RST; 362 delay (25); 363 *dev->sci_icmd = 0; 364 365 /* 366 * Set up various chip parameters 367 */ 368 *dev->sci_icmd = 0; 369 *dev->sci_tcmd = 0; 370 *dev->sci_sel_enb = 0; 371 372 /* anything else was zeroed by reset */ 373 374 splx (s); 375 376 printf("sci id %d\n", my_id); 377 dev->sc_flags |= SCI_ALIVE; 378 } 379 380 void 381 scierror(dev, csr) 382 struct sci_softc *dev; 383 u_char csr; 384 { 385 struct scsipi_xfer *xs; 386 387 xs = dev->sc_xs; 388 389 #ifdef DIAGNOSTIC 390 if (xs == NULL) 391 panic("scierror"); 392 #endif 393 if (xs->xs_control & XS_CTL_SILENT) 394 return; 395 396 printf("%s: ", dev->sc_dev.dv_xname); 397 printf("csr == 0x%02i\n", csr); /* XXX */ 398 } 399 400 /* 401 * select the bus, return when selected or error. 402 */ 403 int 404 sciselectbus(dev, target, our_addr) 405 struct sci_softc *dev; 406 u_char target, our_addr; 407 { 408 register int timeo = 2500; 409 410 QPRINTF (("sciselectbus %d\n", target)); 411 412 /* if we're already selected, return */ 413 if (dev->sc_flags & SCI_SELECTED) /* XXXX */ 414 return 1; 415 416 if ((*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) && 417 (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) && 418 (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL))) 419 return 1; 420 421 *dev->sci_tcmd = 0; 422 *dev->sci_odata = 0x80 + (1 << target); 423 *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_SEL; 424 while ((*dev->sci_bus_csr & SCI_BUS_BSY) == 0) { 425 if (--timeo > 0) { 426 delay(100); 427 } else { 428 break; 429 } 430 } 431 if (timeo) { 432 *dev->sci_icmd = 0; 433 dev->sc_flags |= SCI_SELECTED; 434 return (0); 435 } 436 *dev->sci_icmd = 0; 437 return (1); 438 } 439 440 int 441 sci_ixfer_out(dev, len, buf, phase) 442 register struct sci_softc *dev; 443 int len; 444 register u_char *buf; 445 int phase; 446 { 447 register int wait = sci_data_wait; 448 u_char csr; 449 450 QPRINTF(("sci_ixfer_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 451 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], 452 buf[6], buf[7], buf[8], buf[9])); 453 454 *dev->sci_tcmd = phase; 455 *dev->sci_icmd = SCI_ICMD_DATA; 456 for (;len > 0; len--) { 457 csr = *dev->sci_bus_csr; 458 while (!(csr & SCI_BUS_REQ)) { 459 if ((csr & SCI_BUS_BSY) == 0 || --wait < 0) { 460 #ifdef DEBUG 461 if (sci_debug) 462 printf("sci_ixfer_out fail: l%d i%x w%d\n", 463 len, csr, wait); 464 #endif 465 return (len); 466 } 467 delay(1); 468 csr = *dev->sci_bus_csr; 469 } 470 471 if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH)) 472 break; 473 *dev->sci_odata = *buf; 474 *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_ACK; 475 buf++; 476 while (*dev->sci_bus_csr & SCI_BUS_REQ); 477 *dev->sci_icmd = SCI_ICMD_DATA; 478 } 479 480 QPRINTF(("sci_ixfer_out done\n")); 481 return (0); 482 } 483 484 void 485 sci_ixfer_in(dev, len, buf, phase) 486 struct sci_softc *dev; 487 int len; 488 register u_char *buf; 489 int phase; 490 { 491 int wait = sci_data_wait; 492 u_char csr; 493 volatile register u_char *sci_bus_csr = dev->sci_bus_csr; 494 volatile register u_char *sci_data = dev->sci_data; 495 volatile register u_char *sci_icmd = dev->sci_icmd; 496 #ifdef DEBUG 497 u_char *obp = buf; 498 #endif 499 500 csr = *sci_bus_csr; 501 502 QPRINTF(("sci_ixfer_in %d, csr=%02x\n", len, csr)); 503 504 *dev->sci_tcmd = phase; 505 *sci_icmd = 0; 506 for (;len > 0; len--) { 507 csr = *sci_bus_csr; 508 while (!(csr & SCI_BUS_REQ)) { 509 if (!(csr & SCI_BUS_BSY) || --wait < 0) { 510 #ifdef DEBUG 511 if (sci_debug) 512 printf("sci_ixfer_in fail: l%d i%x w%d\n", 513 len, csr, wait); 514 #endif 515 return; 516 } 517 518 delay(1); 519 csr = *sci_bus_csr; 520 } 521 522 if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH)) 523 break; 524 *buf = *sci_data; 525 *sci_icmd = SCI_ICMD_ACK; 526 buf++; 527 while (*sci_bus_csr & SCI_BUS_REQ); 528 *sci_icmd = 0; 529 } 530 531 QPRINTF(("sci_ixfer_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 532 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5], 533 obp[6], obp[7], obp[8], obp[9])); 534 } 535 536 /* 537 * SCSI 'immediate' command: issue a command to some SCSI device 538 * and get back an 'immediate' response (i.e., do programmed xfer 539 * to get the response data). 'cbuf' is a buffer containing a scsi 540 * command of length clen bytes. 'buf' is a buffer of length 'len' 541 * bytes for data. The transfer direction is determined by the device 542 * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the 543 * command must supply no data. 'xferphase' is the bus phase the 544 * caller expects to happen after the command is issued. It should 545 * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE. 546 */ 547 int 548 sciicmd(dev, target, cbuf, clen, buf, len, xferphase) 549 struct sci_softc *dev; 550 void *cbuf, *buf; 551 int clen, len; 552 u_char xferphase; 553 { 554 u_char phase; 555 register int wait; 556 557 /* select the SCSI bus (it's an error if bus isn't free) */ 558 if (sciselectbus (dev, target, dev->sc_scsi_addr)) 559 return -1; 560 /* 561 * Wait for a phase change (or error) then let the device 562 * sequence us through the various SCSI phases. 563 */ 564 dev->sc_stat[0] = 0xff; 565 dev->sc_msg[0] = 0xff; 566 phase = CMD_PHASE; 567 while (1) { 568 wait = sci_cmd_wait; 569 570 while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == SCI_BUS_BSY); 571 572 QPRINTF((">CSR:%02x<", *dev->sci_bus_csr)); 573 if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) { 574 return -1; 575 } 576 phase = SCI_PHASE(*dev->sci_bus_csr); 577 578 switch (phase) { 579 case CMD_PHASE: 580 if (sci_ixfer_out (dev, clen, cbuf, phase)) 581 goto abort; 582 phase = xferphase; 583 break; 584 585 case DATA_IN_PHASE: 586 if (len <= 0) 587 goto abort; 588 wait = sci_data_wait; 589 sci_ixfer_in (dev, len, buf, phase); 590 phase = STATUS_PHASE; 591 break; 592 593 case DATA_OUT_PHASE: 594 if (len <= 0) 595 goto abort; 596 wait = sci_data_wait; 597 if (sci_ixfer_out (dev, len, buf, phase)) 598 goto abort; 599 phase = STATUS_PHASE; 600 break; 601 602 case MESG_IN_PHASE: 603 dev->sc_msg[0] = 0xff; 604 sci_ixfer_in (dev, 1, dev->sc_msg,phase); 605 dev->sc_flags &= ~SCI_SELECTED; 606 while (*dev->sci_bus_csr & SCI_BUS_BSY); 607 goto out; 608 break; 609 610 case MESG_OUT_PHASE: 611 phase = STATUS_PHASE; 612 break; 613 614 case STATUS_PHASE: 615 sci_ixfer_in (dev, 1, dev->sc_stat, phase); 616 phase = MESG_IN_PHASE; 617 break; 618 619 case BUS_FREE_PHASE: 620 goto out; 621 622 default: 623 printf("sci: unexpected phase %d in icmd from %d\n", 624 phase, target); 625 goto abort; 626 } 627 #if 0 628 if (wait <= 0) 629 goto abort; 630 #endif 631 } 632 633 abort: 634 sciabort(dev, "icmd"); 635 out: 636 QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 637 return (dev->sc_stat[0]); 638 } 639 640 int 641 scigo(dev, xs) 642 struct sci_softc *dev; 643 struct scsipi_xfer *xs; 644 { 645 int count, target; 646 u_char phase, *addr; 647 648 target = xs->sc_link->scsipi_scsi.target; 649 count = xs->datalen; 650 addr = xs->data; 651 652 if (sci_no_dma) { 653 sciicmd (dev, target, (u_char *) xs->cmd, xs->cmdlen, 654 addr, count, 655 xs->xs_control & XS_CTL_DATA_IN ? DATA_IN_PHASE : DATA_OUT_PHASE); 656 657 return (1); 658 } 659 660 /* select the SCSI bus (it's an error if bus isn't free) */ 661 if (sciselectbus (dev, target, dev->sc_scsi_addr)) 662 return -1; 663 /* 664 * Wait for a phase change (or error) then let the device 665 * sequence us through the various SCSI phases. 666 */ 667 dev->sc_stat[0] = 0xff; 668 dev->sc_msg[0] = 0xff; 669 phase = CMD_PHASE; 670 while (1) { 671 while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == 672 SCI_BUS_BSY); 673 674 QPRINTF((">CSR:%02x<", *dev->sci_bus_csr)); 675 if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) { 676 goto abort; 677 } 678 phase = SCI_PHASE(*dev->sci_bus_csr); 679 680 switch (phase) { 681 case CMD_PHASE: 682 if (sci_ixfer_out (dev, xs->cmdlen, (u_char *) xs->cmd, phase)) 683 goto abort; 684 phase = xs->xs_control & XS_CTL_DATA_IN ? DATA_IN_PHASE : DATA_OUT_PHASE; 685 break; 686 687 case DATA_IN_PHASE: 688 if (count <= 0) 689 goto abort; 690 /* XXX use psuedo DMA if available */ 691 if (count >= 128 && dev->dma_xfer_in) 692 (*dev->dma_xfer_in)(dev, count, addr, phase); 693 else 694 sci_ixfer_in (dev, count, addr, phase); 695 phase = STATUS_PHASE; 696 break; 697 698 case DATA_OUT_PHASE: 699 if (count <= 0) 700 goto abort; 701 /* XXX use psuedo DMA if available */ 702 if (count >= 128 && dev->dma_xfer_out) 703 (*dev->dma_xfer_out)(dev, count, addr, phase); 704 else 705 if (sci_ixfer_out (dev, count, addr, phase)) 706 goto abort; 707 phase = STATUS_PHASE; 708 break; 709 710 case MESG_IN_PHASE: 711 dev->sc_msg[0] = 0xff; 712 sci_ixfer_in (dev, 1, dev->sc_msg,phase); 713 dev->sc_flags &= ~SCI_SELECTED; 714 while (*dev->sci_bus_csr & SCI_BUS_BSY); 715 goto out; 716 break; 717 718 case MESG_OUT_PHASE: 719 phase = STATUS_PHASE; 720 break; 721 722 case STATUS_PHASE: 723 sci_ixfer_in (dev, 1, dev->sc_stat, phase); 724 phase = MESG_IN_PHASE; 725 break; 726 727 case BUS_FREE_PHASE: 728 goto out; 729 730 default: 731 printf("sci: unexpected phase %d in icmd from %d\n", 732 phase, target); 733 goto abort; 734 } 735 } 736 737 abort: 738 sciabort(dev, "go"); 739 out: 740 QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 741 return (1); 742 } 743