1 /* $NetBSD: sci.c,v 1.20 1997/08/27 11:23:17 bouyer 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 #define b_cylin b_resid 75 76 int sciicmd __P((struct sci_softc *, int, void *, int, void *, int,u_char)); 77 int scigo __P((struct sci_softc *, struct scsipi_xfer *)); 78 int scigetsense __P((struct sci_softc *, struct scsipi_xfer *)); 79 int sciselectbus __P((struct sci_softc *, u_char, u_char)); 80 void sciabort __P((struct sci_softc *, char *)); 81 void scierror __P((struct sci_softc *, u_char)); 82 void scisetdelay __P((int)); 83 void sci_scsidone __P((struct sci_softc *, int)); 84 void sci_donextcmd __P((struct sci_softc *)); 85 int sci_ixfer_out __P((struct sci_softc *, int, register u_char *, int)); 86 void sci_ixfer_in __P((struct sci_softc *, int, register u_char *, int)); 87 88 int sci_cmd_wait = SCI_CMD_WAIT; 89 int sci_data_wait = SCI_DATA_WAIT; 90 int sci_init_wait = SCI_INIT_WAIT; 91 92 int sci_no_dma = 0; 93 94 #ifdef DEBUG 95 #define QPRINTF(a) if (sci_debug > 1) printf a 96 int sci_debug = 0; 97 #else 98 #define QPRINTF(a) 99 #endif 100 101 /* 102 * default minphys routine for sci based controllers 103 */ 104 void 105 sci_minphys(bp) 106 struct buf *bp; 107 { 108 109 /* 110 * No max transfer at this level. 111 */ 112 minphys(bp); 113 } 114 115 /* 116 * used by specific sci controller 117 * 118 * it appears that the higher level code does nothing with LUN's 119 * so I will too. I could plug it in, however so could they 120 * in scsi_scsipi_cmd(). 121 */ 122 int 123 sci_scsicmd(xs) 124 struct scsipi_xfer *xs; 125 { 126 struct sci_pending *pendp; 127 struct sci_softc *dev; 128 struct scsipi_link *slp; 129 int flags, s; 130 131 slp = xs->sc_link; 132 dev = slp->adapter_softc; 133 flags = xs->flags; 134 135 if (flags & SCSI_DATA_UIO) 136 panic("sci: scsi data uio requested"); 137 138 if (dev->sc_xs && flags & SCSI_POLL) 139 panic("sci_scsicmd: busy"); 140 141 s = splbio(); 142 pendp = &dev->sc_xsstore[slp->scsipi_scsi.target][slp->scsipi_scsi.lun]; 143 if (pendp->xs) { 144 splx(s); 145 return(TRY_AGAIN_LATER); 146 } 147 148 if (dev->sc_xs) { 149 pendp->xs = xs; 150 TAILQ_INSERT_TAIL(&dev->sc_xslist, pendp, link); 151 splx(s); 152 return(SUCCESSFULLY_QUEUED); 153 } 154 pendp->xs = NULL; 155 dev->sc_xs = xs; 156 splx(s); 157 158 /* 159 * nothing is pending do it now. 160 */ 161 sci_donextcmd(dev); 162 163 if (flags & SCSI_POLL) 164 return(COMPLETE); 165 return(SUCCESSFULLY_QUEUED); 166 } 167 168 /* 169 * entered with dev->sc_xs pointing to the next xfer to perform 170 */ 171 void 172 sci_donextcmd(dev) 173 struct sci_softc *dev; 174 { 175 struct scsipi_xfer *xs; 176 struct scsipi_link *slp; 177 int flags, phase, stat; 178 179 xs = dev->sc_xs; 180 slp = xs->sc_link; 181 flags = xs->flags; 182 183 if (flags & SCSI_DATA_IN) 184 phase = DATA_IN_PHASE; 185 else if (flags & SCSI_DATA_OUT) 186 phase = DATA_OUT_PHASE; 187 else 188 phase = STATUS_PHASE; 189 190 if (flags & SCSI_RESET) 191 scireset(dev); 192 193 dev->sc_stat[0] = -1; 194 xs->cmd->bytes[0] |= slp->scsipi_scsi.lun << 5; 195 if (phase == STATUS_PHASE || flags & SCSI_POLL) 196 stat = sciicmd(dev, slp->scsipi_scsi.target, xs->cmd, xs->cmdlen, 197 xs->data, xs->datalen, phase); 198 else if (scigo(dev, xs) == 0) 199 return; 200 else 201 stat = dev->sc_stat[0]; 202 203 sci_scsidone(dev, stat); 204 } 205 206 void 207 sci_scsidone(dev, stat) 208 struct sci_softc *dev; 209 int stat; 210 { 211 struct sci_pending *pendp; 212 struct scsipi_xfer *xs; 213 int s, donext; 214 215 xs = dev->sc_xs; 216 #ifdef DIAGNOSTIC 217 if (xs == NULL) 218 panic("sci_scsidone"); 219 #endif 220 /* 221 * is this right? 222 */ 223 xs->status = stat; 224 225 if (stat == 0) 226 xs->resid = 0; 227 else { 228 switch(stat) { 229 case SCSI_CHECK: 230 stat = scigetsense(dev, xs); 231 if (stat != 0) 232 goto bad_sense; 233 xs->error = XS_SENSE; 234 break; 235 case SCSI_BUSY: 236 xs->error = XS_BUSY; 237 break; 238 bad_sense: 239 default: 240 xs->error = XS_DRIVER_STUFFUP; 241 QPRINTF(("sci_scsicmd() bad %x\n", stat)); 242 break; 243 } 244 } 245 xs->flags |= ITSDONE; 246 247 /* 248 * grab next command before scsipi_done() 249 * this way no single device can hog scsi resources. 250 */ 251 s = splbio(); 252 pendp = dev->sc_xslist.tqh_first; 253 if (pendp == NULL) { 254 donext = 0; 255 dev->sc_xs = NULL; 256 } else { 257 donext = 1; 258 TAILQ_REMOVE(&dev->sc_xslist, pendp, link); 259 dev->sc_xs = pendp->xs; 260 pendp->xs = NULL; 261 } 262 splx(s); 263 scsipi_done(xs); 264 265 if (donext) 266 sci_donextcmd(dev); 267 } 268 269 int 270 scigetsense(dev, xs) 271 struct sci_softc *dev; 272 struct scsipi_xfer *xs; 273 { 274 struct scsipi_sense rqs; 275 struct scsipi_link *slp; 276 277 slp = xs->sc_link; 278 279 rqs.opcode = REQUEST_SENSE; 280 rqs.byte2 = slp->scsipi_scsi.lun << 5; 281 #ifdef not_yet 282 rqs.length = xs->req_sense_length ? xs->req_sense_length : 283 sizeof(xs->sense.scsi_sense); 284 #else 285 rqs.length = sizeof(xs->sense.scsi_sense); 286 #endif 287 288 rqs.unused[0] = rqs.unused[1] = rqs.control = 0; 289 290 return(sciicmd(dev, slp->scsipi_scsi.target, &rqs, sizeof(rqs), 291 &xs->sense.scsi_sense, 292 rqs.length, DATA_IN_PHASE)); 293 } 294 295 void 296 sciabort(dev, where) 297 struct sci_softc *dev; 298 char *where; 299 { 300 printf ("%s: abort %s: csr = 0x%02x, bus = 0x%02x\n", 301 dev->sc_dev.dv_xname, where, *dev->sci_csr, *dev->sci_bus_csr); 302 303 if (dev->sc_flags & SCI_SELECTED) { 304 305 /* lets just hope it worked.. */ 306 dev->sc_flags &= ~SCI_SELECTED; 307 /* XXX */ 308 scireset (dev); 309 } 310 } 311 312 /* 313 * XXX Set/reset long delays. 314 * 315 * if delay == 0, reset default delays 316 * if delay < 0, set both delays to default long initialization values 317 * if delay > 0, set both delays to this value 318 * 319 * Used when a devices is expected to respond slowly (e.g. during 320 * initialization). 321 */ 322 void 323 scisetdelay(del) 324 int del; 325 { 326 static int saved_cmd_wait, saved_data_wait; 327 328 if (del) { 329 saved_cmd_wait = sci_cmd_wait; 330 saved_data_wait = sci_data_wait; 331 if (del > 0) 332 sci_cmd_wait = sci_data_wait = del; 333 else 334 sci_cmd_wait = sci_data_wait = sci_init_wait; 335 } else { 336 sci_cmd_wait = saved_cmd_wait; 337 sci_data_wait = saved_data_wait; 338 } 339 } 340 341 void 342 scireset(dev) 343 struct sci_softc *dev; 344 { 345 u_int s; 346 u_char my_id; 347 348 dev->sc_flags &= ~SCI_SELECTED; 349 if (dev->sc_flags & SCI_ALIVE) 350 sciabort(dev, "reset"); 351 352 printf("%s: ", dev->sc_dev.dv_xname); 353 354 s = splbio(); 355 /* preserve our ID for now */ 356 my_id = 7; 357 358 /* 359 * Reset the chip 360 */ 361 *dev->sci_icmd = SCI_ICMD_TEST; 362 *dev->sci_icmd = SCI_ICMD_TEST | SCI_ICMD_RST; 363 delay (25); 364 *dev->sci_icmd = 0; 365 366 /* 367 * Set up various chip parameters 368 */ 369 *dev->sci_icmd = 0; 370 *dev->sci_tcmd = 0; 371 *dev->sci_sel_enb = 0; 372 373 /* anything else was zeroed by reset */ 374 375 splx (s); 376 377 printf("sci id %d\n", my_id); 378 dev->sc_flags |= SCI_ALIVE; 379 } 380 381 void 382 scierror(dev, csr) 383 struct sci_softc *dev; 384 u_char csr; 385 { 386 struct scsipi_xfer *xs; 387 388 xs = dev->sc_xs; 389 390 #ifdef DIAGNOSTIC 391 if (xs == NULL) 392 panic("scierror"); 393 #endif 394 if (xs->flags & SCSI_SILENT) 395 return; 396 397 printf("%s: ", dev->sc_dev.dv_xname); 398 printf("csr == 0x%02i\n", csr); /* XXX */ 399 } 400 401 /* 402 * select the bus, return when selected or error. 403 */ 404 int 405 sciselectbus(dev, target, our_addr) 406 struct sci_softc *dev; 407 u_char target, our_addr; 408 { 409 register int timeo = 2500; 410 411 QPRINTF (("sciselectbus %d\n", target)); 412 413 /* if we're already selected, return */ 414 if (dev->sc_flags & SCI_SELECTED) /* XXXX */ 415 return 1; 416 417 if ((*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) && 418 (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) && 419 (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL))) 420 return 1; 421 422 *dev->sci_tcmd = 0; 423 *dev->sci_odata = 0x80 + (1 << target); 424 *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_SEL; 425 while ((*dev->sci_bus_csr & SCI_BUS_BSY) == 0) { 426 if (--timeo > 0) { 427 delay(100); 428 } else { 429 break; 430 } 431 } 432 if (timeo) { 433 *dev->sci_icmd = 0; 434 dev->sc_flags |= SCI_SELECTED; 435 return (0); 436 } 437 *dev->sci_icmd = 0; 438 return (1); 439 } 440 441 int 442 sci_ixfer_out(dev, len, buf, phase) 443 register struct sci_softc *dev; 444 int len; 445 register u_char *buf; 446 int phase; 447 { 448 register int wait = sci_data_wait; 449 u_char csr; 450 451 QPRINTF(("sci_ixfer_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 452 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], 453 buf[6], buf[7], buf[8], buf[9])); 454 455 *dev->sci_tcmd = phase; 456 *dev->sci_icmd = SCI_ICMD_DATA; 457 for (;len > 0; len--) { 458 csr = *dev->sci_bus_csr; 459 while (!(csr & SCI_BUS_REQ)) { 460 if ((csr & SCI_BUS_BSY) == 0 || --wait < 0) { 461 #ifdef DEBUG 462 if (sci_debug) 463 printf("sci_ixfer_out fail: l%d i%x w%d\n", 464 len, csr, wait); 465 #endif 466 return (len); 467 } 468 delay(1); 469 csr = *dev->sci_bus_csr; 470 } 471 472 if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH)) 473 break; 474 *dev->sci_odata = *buf; 475 *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_ACK; 476 buf++; 477 while (*dev->sci_bus_csr & SCI_BUS_REQ); 478 *dev->sci_icmd = SCI_ICMD_DATA; 479 } 480 481 QPRINTF(("sci_ixfer_out done\n")); 482 return (0); 483 } 484 485 void 486 sci_ixfer_in(dev, len, buf, phase) 487 struct sci_softc *dev; 488 int len; 489 register u_char *buf; 490 int phase; 491 { 492 int wait = sci_data_wait; 493 u_char csr; 494 volatile register u_char *sci_bus_csr = dev->sci_bus_csr; 495 volatile register u_char *sci_data = dev->sci_data; 496 volatile register u_char *sci_icmd = dev->sci_icmd; 497 #ifdef DEBUG 498 u_char *obp = buf; 499 #endif 500 501 csr = *sci_bus_csr; 502 503 QPRINTF(("sci_ixfer_in %d, csr=%02x\n", len, csr)); 504 505 *dev->sci_tcmd = phase; 506 *sci_icmd = 0; 507 for (;len > 0; len--) { 508 csr = *sci_bus_csr; 509 while (!(csr & SCI_BUS_REQ)) { 510 if (!(csr & SCI_BUS_BSY) || --wait < 0) { 511 #ifdef DEBUG 512 if (sci_debug) 513 printf("sci_ixfer_in fail: l%d i%x w%d\n", 514 len, csr, wait); 515 #endif 516 return; 517 } 518 519 delay(1); 520 csr = *sci_bus_csr; 521 } 522 523 if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH)) 524 break; 525 *buf = *sci_data; 526 *sci_icmd = SCI_ICMD_ACK; 527 buf++; 528 while (*sci_bus_csr & SCI_BUS_REQ); 529 *sci_icmd = 0; 530 } 531 532 QPRINTF(("sci_ixfer_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 533 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5], 534 obp[6], obp[7], obp[8], obp[9])); 535 } 536 537 /* 538 * SCSI 'immediate' command: issue a command to some SCSI device 539 * and get back an 'immediate' response (i.e., do programmed xfer 540 * to get the response data). 'cbuf' is a buffer containing a scsi 541 * command of length clen bytes. 'buf' is a buffer of length 'len' 542 * bytes for data. The transfer direction is determined by the device 543 * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the 544 * command must supply no data. 'xferphase' is the bus phase the 545 * caller expects to happen after the command is issued. It should 546 * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE. 547 */ 548 int 549 sciicmd(dev, target, cbuf, clen, buf, len, xferphase) 550 struct sci_softc *dev; 551 void *cbuf, *buf; 552 int clen, len; 553 u_char xferphase; 554 { 555 u_char phase; 556 register int wait; 557 558 /* select the SCSI bus (it's an error if bus isn't free) */ 559 if (sciselectbus (dev, target, dev->sc_scsi_addr)) 560 return -1; 561 /* 562 * Wait for a phase change (or error) then let the device 563 * sequence us through the various SCSI phases. 564 */ 565 dev->sc_stat[0] = 0xff; 566 dev->sc_msg[0] = 0xff; 567 phase = CMD_PHASE; 568 while (1) { 569 wait = sci_cmd_wait; 570 571 while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == SCI_BUS_BSY); 572 573 QPRINTF((">CSR:%02x<", *dev->sci_bus_csr)); 574 if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) { 575 return -1; 576 } 577 phase = SCI_PHASE(*dev->sci_bus_csr); 578 579 switch (phase) { 580 case CMD_PHASE: 581 if (sci_ixfer_out (dev, clen, cbuf, phase)) 582 goto abort; 583 phase = xferphase; 584 break; 585 586 case DATA_IN_PHASE: 587 if (len <= 0) 588 goto abort; 589 wait = sci_data_wait; 590 sci_ixfer_in (dev, len, buf, phase); 591 phase = STATUS_PHASE; 592 break; 593 594 case DATA_OUT_PHASE: 595 if (len <= 0) 596 goto abort; 597 wait = sci_data_wait; 598 if (sci_ixfer_out (dev, len, buf, phase)) 599 goto abort; 600 phase = STATUS_PHASE; 601 break; 602 603 case MESG_IN_PHASE: 604 dev->sc_msg[0] = 0xff; 605 sci_ixfer_in (dev, 1, dev->sc_msg,phase); 606 dev->sc_flags &= ~SCI_SELECTED; 607 while (*dev->sci_bus_csr & SCI_BUS_BSY); 608 goto out; 609 break; 610 611 case MESG_OUT_PHASE: 612 phase = STATUS_PHASE; 613 break; 614 615 case STATUS_PHASE: 616 sci_ixfer_in (dev, 1, dev->sc_stat, phase); 617 phase = MESG_IN_PHASE; 618 break; 619 620 case BUS_FREE_PHASE: 621 goto out; 622 623 default: 624 printf("sci: unexpected phase %d in icmd from %d\n", 625 phase, target); 626 goto abort; 627 } 628 #if 0 629 if (wait <= 0) 630 goto abort; 631 #endif 632 } 633 634 abort: 635 sciabort(dev, "icmd"); 636 out: 637 QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 638 return (dev->sc_stat[0]); 639 } 640 641 int 642 scigo(dev, xs) 643 struct sci_softc *dev; 644 struct scsipi_xfer *xs; 645 { 646 int count, target; 647 u_char phase, *addr; 648 649 target = xs->sc_link->scsipi_scsi.target; 650 count = xs->datalen; 651 addr = xs->data; 652 653 if (sci_no_dma) { 654 sciicmd (dev, target, (u_char *) xs->cmd, xs->cmdlen, 655 addr, count, 656 xs->flags & SCSI_DATA_IN ? DATA_IN_PHASE : DATA_OUT_PHASE); 657 658 return (1); 659 } 660 661 /* select the SCSI bus (it's an error if bus isn't free) */ 662 if (sciselectbus (dev, target, dev->sc_scsi_addr)) 663 return -1; 664 /* 665 * Wait for a phase change (or error) then let the device 666 * sequence us through the various SCSI phases. 667 */ 668 dev->sc_stat[0] = 0xff; 669 dev->sc_msg[0] = 0xff; 670 phase = CMD_PHASE; 671 while (1) { 672 while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == 673 SCI_BUS_BSY); 674 675 QPRINTF((">CSR:%02x<", *dev->sci_bus_csr)); 676 if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) { 677 goto abort; 678 } 679 phase = SCI_PHASE(*dev->sci_bus_csr); 680 681 switch (phase) { 682 case CMD_PHASE: 683 if (sci_ixfer_out (dev, xs->cmdlen, (u_char *) xs->cmd, phase)) 684 goto abort; 685 phase = xs->flags & SCSI_DATA_IN ? DATA_IN_PHASE : DATA_OUT_PHASE; 686 break; 687 688 case DATA_IN_PHASE: 689 if (count <= 0) 690 goto abort; 691 /* XXX use psuedo DMA if available */ 692 if (count >= 128 && dev->dma_xfer_in) 693 (*dev->dma_xfer_in)(dev, count, addr, phase); 694 else 695 sci_ixfer_in (dev, count, addr, phase); 696 phase = STATUS_PHASE; 697 break; 698 699 case DATA_OUT_PHASE: 700 if (count <= 0) 701 goto abort; 702 /* XXX use psuedo DMA if available */ 703 if (count >= 128 && dev->dma_xfer_out) 704 (*dev->dma_xfer_out)(dev, count, addr, phase); 705 else 706 if (sci_ixfer_out (dev, count, addr, phase)) 707 goto abort; 708 phase = STATUS_PHASE; 709 break; 710 711 case MESG_IN_PHASE: 712 dev->sc_msg[0] = 0xff; 713 sci_ixfer_in (dev, 1, dev->sc_msg,phase); 714 dev->sc_flags &= ~SCI_SELECTED; 715 while (*dev->sci_bus_csr & SCI_BUS_BSY); 716 goto out; 717 break; 718 719 case MESG_OUT_PHASE: 720 phase = STATUS_PHASE; 721 break; 722 723 case STATUS_PHASE: 724 sci_ixfer_in (dev, 1, dev->sc_stat, phase); 725 phase = MESG_IN_PHASE; 726 break; 727 728 case BUS_FREE_PHASE: 729 goto out; 730 731 default: 732 printf("sci: unexpected phase %d in icmd from %d\n", 733 phase, target); 734 goto abort; 735 } 736 } 737 738 abort: 739 sciabort(dev, "go"); 740 out: 741 QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 742 return (1); 743 } 744