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