1 /* $NetBSD: sci.c,v 1.30 2003/10/31 14:38:44 bouyer 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.30 2003/10/31 14:38:44 bouyer 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 s = splbio(); 169 170 if (dev->sc_xs && flags & XS_CTL_POLL) 171 panic("sci_scsicmd: busy"); 172 173 #ifdef DIAGNOSTIC 174 /* 175 * This should never happen as we track the resources 176 * in the mid-layer. 177 */ 178 if (dev->sc_xs) { 179 scsipi_printaddr(periph); 180 printf("unable to allocate scb\n"); 181 panic("sea_scsipi_request"); 182 } 183 #endif 184 185 dev->sc_xs = xs; 186 splx(s); 187 188 /* 189 * nothing is pending do it now. 190 */ 191 sci_donextcmd(dev); 192 193 return; 194 195 case ADAPTER_REQ_GROW_RESOURCES: 196 return; 197 198 case ADAPTER_REQ_SET_XFER_MODE: 199 return; 200 } 201 } 202 203 /* 204 * entered with dev->sc_xs pointing to the next xfer to perform 205 */ 206 void 207 sci_donextcmd(struct sci_softc *dev) 208 { 209 struct scsipi_xfer *xs; 210 struct scsipi_periph *periph; 211 int flags, phase, stat; 212 213 xs = dev->sc_xs; 214 periph = xs->xs_periph; 215 flags = xs->xs_control; 216 217 if (flags & XS_CTL_DATA_IN) 218 phase = DATA_IN_PHASE; 219 else if (flags & XS_CTL_DATA_OUT) 220 phase = DATA_OUT_PHASE; 221 else 222 phase = STATUS_PHASE; 223 224 if (flags & XS_CTL_RESET) 225 scireset(dev); 226 227 dev->sc_stat[0] = -1; 228 xs->cmd->bytes[0] |= periph->periph_lun << 5; 229 if (phase == STATUS_PHASE || flags & XS_CTL_POLL) 230 stat = sciicmd(dev, periph->periph_target, xs->cmd, xs->cmdlen, 231 xs->data, xs->datalen, phase); 232 else if (scigo(dev, xs) == 0) 233 return; 234 else 235 stat = dev->sc_stat[0]; 236 237 sci_scsidone(dev, stat); 238 } 239 240 void 241 sci_scsidone(struct sci_softc *dev, int stat) 242 { 243 struct scsipi_xfer *xs; 244 245 xs = dev->sc_xs; 246 #ifdef DIAGNOSTIC 247 if (xs == NULL) 248 panic("sci_scsidone"); 249 #endif 250 xs->status = stat; 251 if (stat == 0) 252 xs->resid = 0; 253 else { 254 switch(stat) { 255 case SCSI_CHECK: 256 xs->resid = 0; 257 /* FALLTHOUGH */ 258 case SCSI_BUSY: 259 xs->error = XS_BUSY; 260 break; 261 default: 262 xs->error = XS_DRIVER_STUFFUP; 263 QPRINTF(("sci_scsicmd() bad %x\n", stat)); 264 break; 265 } 266 } 267 268 scsipi_done(xs); 269 270 } 271 272 void 273 sciabort(struct sci_softc *dev, char *where) 274 { 275 printf ("%s: abort %s: csr = 0x%02x, bus = 0x%02x\n", 276 dev->sc_dev.dv_xname, where, *dev->sci_csr, *dev->sci_bus_csr); 277 278 if (dev->sc_flags & SCI_SELECTED) { 279 280 /* lets just hope it worked.. */ 281 dev->sc_flags &= ~SCI_SELECTED; 282 /* XXX */ 283 scireset (dev); 284 } 285 } 286 287 /* 288 * XXX Set/reset long delays. 289 * 290 * if delay == 0, reset default delays 291 * if delay < 0, set both delays to default long initialization values 292 * if delay > 0, set both delays to this value 293 * 294 * Used when a devices is expected to respond slowly (e.g. during 295 * initialization). 296 */ 297 void 298 scisetdelay(int del) 299 { 300 static int saved_cmd_wait, saved_data_wait; 301 302 if (del) { 303 saved_cmd_wait = sci_cmd_wait; 304 saved_data_wait = sci_data_wait; 305 if (del > 0) 306 sci_cmd_wait = sci_data_wait = del; 307 else 308 sci_cmd_wait = sci_data_wait = sci_init_wait; 309 } else { 310 sci_cmd_wait = saved_cmd_wait; 311 sci_data_wait = saved_data_wait; 312 } 313 } 314 315 void 316 scireset(struct sci_softc *dev) 317 { 318 u_int s; 319 u_char my_id; 320 321 dev->sc_flags &= ~SCI_SELECTED; 322 if (dev->sc_flags & SCI_ALIVE) 323 sciabort(dev, "reset"); 324 325 printf("%s: ", dev->sc_dev.dv_xname); 326 327 s = splbio(); 328 /* preserve our ID for now */ 329 my_id = 7; 330 331 /* 332 * Reset the chip 333 */ 334 *dev->sci_icmd = SCI_ICMD_TEST; 335 *dev->sci_icmd = SCI_ICMD_TEST | SCI_ICMD_RST; 336 delay (25); 337 *dev->sci_icmd = 0; 338 339 /* 340 * Set up various chip parameters 341 */ 342 *dev->sci_icmd = 0; 343 *dev->sci_tcmd = 0; 344 *dev->sci_sel_enb = 0; 345 346 /* anything else was zeroed by reset */ 347 348 splx (s); 349 350 printf("sci id %d\n", my_id); 351 dev->sc_flags |= SCI_ALIVE; 352 } 353 354 void 355 scierror(struct sci_softc *dev, u_char csr) 356 { 357 struct scsipi_xfer *xs; 358 359 xs = dev->sc_xs; 360 361 #ifdef DIAGNOSTIC 362 if (xs == NULL) 363 panic("scierror"); 364 #endif 365 if (xs->xs_control & XS_CTL_SILENT) 366 return; 367 368 printf("%s: ", dev->sc_dev.dv_xname); 369 printf("csr == 0x%02i\n", csr); /* XXX */ 370 } 371 372 /* 373 * select the bus, return when selected or error. 374 */ 375 int 376 sciselectbus(struct sci_softc *dev, u_char target, u_char our_addr) 377 { 378 register int timeo = 2500; 379 380 QPRINTF (("sciselectbus %d\n", target)); 381 382 /* if we're already selected, return */ 383 if (dev->sc_flags & SCI_SELECTED) /* XXXX */ 384 return 1; 385 386 if ((*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) && 387 (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) && 388 (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL))) 389 return 1; 390 391 *dev->sci_tcmd = 0; 392 *dev->sci_odata = 0x80 + (1 << target); 393 *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_SEL; 394 while ((*dev->sci_bus_csr & SCI_BUS_BSY) == 0) { 395 if (--timeo > 0) { 396 delay(100); 397 } else { 398 break; 399 } 400 } 401 if (timeo) { 402 *dev->sci_icmd = 0; 403 dev->sc_flags |= SCI_SELECTED; 404 return (0); 405 } 406 *dev->sci_icmd = 0; 407 return (1); 408 } 409 410 int 411 sci_ixfer_out(register struct sci_softc *dev, int len, register u_char *buf, 412 int phase) 413 { 414 register int wait = sci_data_wait; 415 u_char csr; 416 417 QPRINTF(("sci_ixfer_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 418 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], 419 buf[6], buf[7], buf[8], buf[9])); 420 421 *dev->sci_tcmd = phase; 422 *dev->sci_icmd = SCI_ICMD_DATA; 423 for (;len > 0; len--) { 424 csr = *dev->sci_bus_csr; 425 while (!(csr & SCI_BUS_REQ)) { 426 if ((csr & SCI_BUS_BSY) == 0 || --wait < 0) { 427 #ifdef DEBUG 428 if (sci_debug) 429 printf("sci_ixfer_out fail: l%d i%x w%d\n", 430 len, csr, wait); 431 #endif 432 return (len); 433 } 434 delay(1); 435 csr = *dev->sci_bus_csr; 436 } 437 438 if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH)) 439 break; 440 *dev->sci_odata = *buf; 441 *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_ACK; 442 buf++; 443 while (*dev->sci_bus_csr & SCI_BUS_REQ); 444 *dev->sci_icmd = SCI_ICMD_DATA; 445 } 446 447 QPRINTF(("sci_ixfer_out done\n")); 448 return (0); 449 } 450 451 void 452 sci_ixfer_in(struct sci_softc *dev, int len, register u_char *buf, int phase) 453 { 454 int wait = sci_data_wait; 455 u_char csr; 456 volatile register u_char *sci_bus_csr = dev->sci_bus_csr; 457 volatile register u_char *sci_data = dev->sci_data; 458 volatile register u_char *sci_icmd = dev->sci_icmd; 459 #ifdef DEBUG 460 u_char *obp = buf; 461 #endif 462 463 csr = *sci_bus_csr; 464 465 QPRINTF(("sci_ixfer_in %d, csr=%02x\n", len, csr)); 466 467 *dev->sci_tcmd = phase; 468 *sci_icmd = 0; 469 for (;len > 0; len--) { 470 csr = *sci_bus_csr; 471 while (!(csr & SCI_BUS_REQ)) { 472 if (!(csr & SCI_BUS_BSY) || --wait < 0) { 473 #ifdef DEBUG 474 if (sci_debug) 475 printf("sci_ixfer_in fail: l%d i%x w%d\n", 476 len, csr, wait); 477 #endif 478 return; 479 } 480 481 delay(1); 482 csr = *sci_bus_csr; 483 } 484 485 if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH)) 486 break; 487 *buf = *sci_data; 488 *sci_icmd = SCI_ICMD_ACK; 489 buf++; 490 while (*sci_bus_csr & SCI_BUS_REQ); 491 *sci_icmd = 0; 492 } 493 494 QPRINTF(("sci_ixfer_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 495 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5], 496 obp[6], obp[7], obp[8], obp[9])); 497 } 498 499 /* 500 * SCSI 'immediate' command: issue a command to some SCSI device 501 * and get back an 'immediate' response (i.e., do programmed xfer 502 * to get the response data). 'cbuf' is a buffer containing a scsi 503 * command of length clen bytes. 'buf' is a buffer of length 'len' 504 * bytes for data. The transfer direction is determined by the device 505 * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the 506 * command must supply no data. 'xferphase' is the bus phase the 507 * caller expects to happen after the command is issued. It should 508 * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE. 509 */ 510 int 511 sciicmd(struct sci_softc *dev, int target, void *cbuf, int clen, void *buf, 512 int len, u_char xferphase) 513 { 514 u_char phase; 515 register int wait; 516 517 /* select the SCSI bus (it's an error if bus isn't free) */ 518 if (sciselectbus (dev, target, dev->sc_scsi_addr)) 519 return -1; 520 /* 521 * Wait for a phase change (or error) then let the device 522 * sequence us through the various SCSI phases. 523 */ 524 dev->sc_stat[0] = 0xff; 525 dev->sc_msg[0] = 0xff; 526 phase = CMD_PHASE; 527 while (1) { 528 wait = sci_cmd_wait; 529 530 while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == SCI_BUS_BSY); 531 532 QPRINTF((">CSR:%02x<", *dev->sci_bus_csr)); 533 if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) { 534 return -1; 535 } 536 phase = SCI_PHASE(*dev->sci_bus_csr); 537 538 switch (phase) { 539 case CMD_PHASE: 540 if (sci_ixfer_out (dev, clen, cbuf, phase)) 541 goto abort; 542 phase = xferphase; 543 break; 544 545 case DATA_IN_PHASE: 546 if (len <= 0) 547 goto abort; 548 wait = sci_data_wait; 549 sci_ixfer_in (dev, len, buf, phase); 550 phase = STATUS_PHASE; 551 break; 552 553 case DATA_OUT_PHASE: 554 if (len <= 0) 555 goto abort; 556 wait = sci_data_wait; 557 if (sci_ixfer_out (dev, len, buf, phase)) 558 goto abort; 559 phase = STATUS_PHASE; 560 break; 561 562 case MESG_IN_PHASE: 563 dev->sc_msg[0] = 0xff; 564 sci_ixfer_in (dev, 1, dev->sc_msg,phase); 565 dev->sc_flags &= ~SCI_SELECTED; 566 while (*dev->sci_bus_csr & SCI_BUS_BSY); 567 goto out; 568 break; 569 570 case MESG_OUT_PHASE: 571 phase = STATUS_PHASE; 572 break; 573 574 case STATUS_PHASE: 575 sci_ixfer_in (dev, 1, dev->sc_stat, phase); 576 phase = MESG_IN_PHASE; 577 break; 578 579 case BUS_FREE_PHASE: 580 goto out; 581 582 default: 583 printf("sci: unexpected phase %d in icmd from %d\n", 584 phase, target); 585 goto abort; 586 } 587 #if 0 588 if (wait <= 0) 589 goto abort; 590 #endif 591 } 592 593 abort: 594 sciabort(dev, "icmd"); 595 out: 596 QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 597 return (dev->sc_stat[0]); 598 } 599 600 int 601 scigo(struct sci_softc *dev, struct scsipi_xfer *xs) 602 { 603 int count, target; 604 u_char phase, *addr; 605 606 target = xs->xs_periph->periph_target; 607 count = xs->datalen; 608 addr = xs->data; 609 610 if (sci_no_dma) { 611 sciicmd (dev, target, (u_char *) xs->cmd, xs->cmdlen, 612 addr, count, 613 xs->xs_control & XS_CTL_DATA_IN ? DATA_IN_PHASE : DATA_OUT_PHASE); 614 615 return (1); 616 } 617 618 /* select the SCSI bus (it's an error if bus isn't free) */ 619 if (sciselectbus (dev, target, dev->sc_scsi_addr)) 620 return -1; 621 /* 622 * Wait for a phase change (or error) then let the device 623 * sequence us through the various SCSI phases. 624 */ 625 dev->sc_stat[0] = 0xff; 626 dev->sc_msg[0] = 0xff; 627 phase = CMD_PHASE; 628 while (1) { 629 while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == 630 SCI_BUS_BSY); 631 632 QPRINTF((">CSR:%02x<", *dev->sci_bus_csr)); 633 if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) { 634 goto abort; 635 } 636 phase = SCI_PHASE(*dev->sci_bus_csr); 637 638 switch (phase) { 639 case CMD_PHASE: 640 if (sci_ixfer_out (dev, xs->cmdlen, (u_char *) xs->cmd, phase)) 641 goto abort; 642 phase = xs->xs_control & XS_CTL_DATA_IN ? DATA_IN_PHASE : DATA_OUT_PHASE; 643 break; 644 645 case DATA_IN_PHASE: 646 if (count <= 0) 647 goto abort; 648 /* XXX use psuedo DMA if available */ 649 if (count >= 128 && dev->dma_xfer_in) 650 (*dev->dma_xfer_in)(dev, count, addr, phase); 651 else 652 sci_ixfer_in (dev, count, addr, phase); 653 phase = STATUS_PHASE; 654 break; 655 656 case DATA_OUT_PHASE: 657 if (count <= 0) 658 goto abort; 659 /* XXX use psuedo DMA if available */ 660 if (count >= 128 && dev->dma_xfer_out) 661 (*dev->dma_xfer_out)(dev, count, addr, phase); 662 else 663 if (sci_ixfer_out (dev, count, addr, phase)) 664 goto abort; 665 phase = STATUS_PHASE; 666 break; 667 668 case MESG_IN_PHASE: 669 dev->sc_msg[0] = 0xff; 670 sci_ixfer_in (dev, 1, dev->sc_msg,phase); 671 dev->sc_flags &= ~SCI_SELECTED; 672 while (*dev->sci_bus_csr & SCI_BUS_BSY); 673 goto out; 674 break; 675 676 case MESG_OUT_PHASE: 677 phase = STATUS_PHASE; 678 break; 679 680 case STATUS_PHASE: 681 sci_ixfer_in (dev, 1, dev->sc_stat, phase); 682 phase = MESG_IN_PHASE; 683 break; 684 685 case BUS_FREE_PHASE: 686 goto out; 687 688 default: 689 printf("sci: unexpected phase %d in icmd from %d\n", 690 phase, target); 691 goto abort; 692 } 693 } 694 695 abort: 696 sciabort(dev, "go"); 697 out: 698 QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 699 return (1); 700 } 701