1 /* $NetBSD: sci.c,v 1.21 1999/09/30 22:59:53 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 #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->xs_control; 134 135 if (flags & XS_CTL_DATA_UIO) 136 panic("sci: scsi data uio requested"); 137 138 if (dev->sc_xs && flags & XS_CTL_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 & XS_CTL_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->xs_control; 182 183 if (flags & XS_CTL_DATA_IN) 184 phase = DATA_IN_PHASE; 185 else if (flags & XS_CTL_DATA_OUT) 186 phase = DATA_OUT_PHASE; 187 else 188 phase = STATUS_PHASE; 189 190 if (flags & XS_CTL_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 & XS_CTL_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 246 xs->xs_status |= XS_STS_DONE; 247 248 /* 249 * grab next command before scsipi_done() 250 * this way no single device can hog scsi resources. 251 */ 252 s = splbio(); 253 pendp = dev->sc_xslist.tqh_first; 254 if (pendp == NULL) { 255 donext = 0; 256 dev->sc_xs = NULL; 257 } else { 258 donext = 1; 259 TAILQ_REMOVE(&dev->sc_xslist, pendp, link); 260 dev->sc_xs = pendp->xs; 261 pendp->xs = NULL; 262 } 263 splx(s); 264 scsipi_done(xs); 265 266 if (donext) 267 sci_donextcmd(dev); 268 } 269 270 int 271 scigetsense(dev, xs) 272 struct sci_softc *dev; 273 struct scsipi_xfer *xs; 274 { 275 struct scsipi_sense rqs; 276 struct scsipi_link *slp; 277 278 slp = xs->sc_link; 279 280 rqs.opcode = REQUEST_SENSE; 281 rqs.byte2 = slp->scsipi_scsi.lun << 5; 282 #ifdef not_yet 283 rqs.length = xs->req_sense_length ? xs->req_sense_length : 284 sizeof(xs->sense.scsi_sense); 285 #else 286 rqs.length = sizeof(xs->sense.scsi_sense); 287 #endif 288 289 rqs.unused[0] = rqs.unused[1] = rqs.control = 0; 290 291 return(sciicmd(dev, slp->scsipi_scsi.target, &rqs, sizeof(rqs), 292 &xs->sense.scsi_sense, 293 rqs.length, DATA_IN_PHASE)); 294 } 295 296 void 297 sciabort(dev, where) 298 struct sci_softc *dev; 299 char *where; 300 { 301 printf ("%s: abort %s: csr = 0x%02x, bus = 0x%02x\n", 302 dev->sc_dev.dv_xname, where, *dev->sci_csr, *dev->sci_bus_csr); 303 304 if (dev->sc_flags & SCI_SELECTED) { 305 306 /* lets just hope it worked.. */ 307 dev->sc_flags &= ~SCI_SELECTED; 308 /* XXX */ 309 scireset (dev); 310 } 311 } 312 313 /* 314 * XXX Set/reset long delays. 315 * 316 * if delay == 0, reset default delays 317 * if delay < 0, set both delays to default long initialization values 318 * if delay > 0, set both delays to this value 319 * 320 * Used when a devices is expected to respond slowly (e.g. during 321 * initialization). 322 */ 323 void 324 scisetdelay(del) 325 int del; 326 { 327 static int saved_cmd_wait, saved_data_wait; 328 329 if (del) { 330 saved_cmd_wait = sci_cmd_wait; 331 saved_data_wait = sci_data_wait; 332 if (del > 0) 333 sci_cmd_wait = sci_data_wait = del; 334 else 335 sci_cmd_wait = sci_data_wait = sci_init_wait; 336 } else { 337 sci_cmd_wait = saved_cmd_wait; 338 sci_data_wait = saved_data_wait; 339 } 340 } 341 342 void 343 scireset(dev) 344 struct sci_softc *dev; 345 { 346 u_int s; 347 u_char my_id; 348 349 dev->sc_flags &= ~SCI_SELECTED; 350 if (dev->sc_flags & SCI_ALIVE) 351 sciabort(dev, "reset"); 352 353 printf("%s: ", dev->sc_dev.dv_xname); 354 355 s = splbio(); 356 /* preserve our ID for now */ 357 my_id = 7; 358 359 /* 360 * Reset the chip 361 */ 362 *dev->sci_icmd = SCI_ICMD_TEST; 363 *dev->sci_icmd = SCI_ICMD_TEST | SCI_ICMD_RST; 364 delay (25); 365 *dev->sci_icmd = 0; 366 367 /* 368 * Set up various chip parameters 369 */ 370 *dev->sci_icmd = 0; 371 *dev->sci_tcmd = 0; 372 *dev->sci_sel_enb = 0; 373 374 /* anything else was zeroed by reset */ 375 376 splx (s); 377 378 printf("sci id %d\n", my_id); 379 dev->sc_flags |= SCI_ALIVE; 380 } 381 382 void 383 scierror(dev, csr) 384 struct sci_softc *dev; 385 u_char csr; 386 { 387 struct scsipi_xfer *xs; 388 389 xs = dev->sc_xs; 390 391 #ifdef DIAGNOSTIC 392 if (xs == NULL) 393 panic("scierror"); 394 #endif 395 if (xs->xs_control & XS_CTL_SILENT) 396 return; 397 398 printf("%s: ", dev->sc_dev.dv_xname); 399 printf("csr == 0x%02i\n", csr); /* XXX */ 400 } 401 402 /* 403 * select the bus, return when selected or error. 404 */ 405 int 406 sciselectbus(dev, target, our_addr) 407 struct sci_softc *dev; 408 u_char target, our_addr; 409 { 410 register int timeo = 2500; 411 412 QPRINTF (("sciselectbus %d\n", target)); 413 414 /* if we're already selected, return */ 415 if (dev->sc_flags & SCI_SELECTED) /* XXXX */ 416 return 1; 417 418 if ((*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) && 419 (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) && 420 (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL))) 421 return 1; 422 423 *dev->sci_tcmd = 0; 424 *dev->sci_odata = 0x80 + (1 << target); 425 *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_SEL; 426 while ((*dev->sci_bus_csr & SCI_BUS_BSY) == 0) { 427 if (--timeo > 0) { 428 delay(100); 429 } else { 430 break; 431 } 432 } 433 if (timeo) { 434 *dev->sci_icmd = 0; 435 dev->sc_flags |= SCI_SELECTED; 436 return (0); 437 } 438 *dev->sci_icmd = 0; 439 return (1); 440 } 441 442 int 443 sci_ixfer_out(dev, len, buf, phase) 444 register struct sci_softc *dev; 445 int len; 446 register u_char *buf; 447 int phase; 448 { 449 register int wait = sci_data_wait; 450 u_char csr; 451 452 QPRINTF(("sci_ixfer_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 453 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], 454 buf[6], buf[7], buf[8], buf[9])); 455 456 *dev->sci_tcmd = phase; 457 *dev->sci_icmd = SCI_ICMD_DATA; 458 for (;len > 0; len--) { 459 csr = *dev->sci_bus_csr; 460 while (!(csr & SCI_BUS_REQ)) { 461 if ((csr & SCI_BUS_BSY) == 0 || --wait < 0) { 462 #ifdef DEBUG 463 if (sci_debug) 464 printf("sci_ixfer_out fail: l%d i%x w%d\n", 465 len, csr, wait); 466 #endif 467 return (len); 468 } 469 delay(1); 470 csr = *dev->sci_bus_csr; 471 } 472 473 if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH)) 474 break; 475 *dev->sci_odata = *buf; 476 *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_ACK; 477 buf++; 478 while (*dev->sci_bus_csr & SCI_BUS_REQ); 479 *dev->sci_icmd = SCI_ICMD_DATA; 480 } 481 482 QPRINTF(("sci_ixfer_out done\n")); 483 return (0); 484 } 485 486 void 487 sci_ixfer_in(dev, len, buf, phase) 488 struct sci_softc *dev; 489 int len; 490 register u_char *buf; 491 int phase; 492 { 493 int wait = sci_data_wait; 494 u_char csr; 495 volatile register u_char *sci_bus_csr = dev->sci_bus_csr; 496 volatile register u_char *sci_data = dev->sci_data; 497 volatile register u_char *sci_icmd = dev->sci_icmd; 498 #ifdef DEBUG 499 u_char *obp = buf; 500 #endif 501 502 csr = *sci_bus_csr; 503 504 QPRINTF(("sci_ixfer_in %d, csr=%02x\n", len, csr)); 505 506 *dev->sci_tcmd = phase; 507 *sci_icmd = 0; 508 for (;len > 0; len--) { 509 csr = *sci_bus_csr; 510 while (!(csr & SCI_BUS_REQ)) { 511 if (!(csr & SCI_BUS_BSY) || --wait < 0) { 512 #ifdef DEBUG 513 if (sci_debug) 514 printf("sci_ixfer_in fail: l%d i%x w%d\n", 515 len, csr, wait); 516 #endif 517 return; 518 } 519 520 delay(1); 521 csr = *sci_bus_csr; 522 } 523 524 if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH)) 525 break; 526 *buf = *sci_data; 527 *sci_icmd = SCI_ICMD_ACK; 528 buf++; 529 while (*sci_bus_csr & SCI_BUS_REQ); 530 *sci_icmd = 0; 531 } 532 533 QPRINTF(("sci_ixfer_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 534 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5], 535 obp[6], obp[7], obp[8], obp[9])); 536 } 537 538 /* 539 * SCSI 'immediate' command: issue a command to some SCSI device 540 * and get back an 'immediate' response (i.e., do programmed xfer 541 * to get the response data). 'cbuf' is a buffer containing a scsi 542 * command of length clen bytes. 'buf' is a buffer of length 'len' 543 * bytes for data. The transfer direction is determined by the device 544 * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the 545 * command must supply no data. 'xferphase' is the bus phase the 546 * caller expects to happen after the command is issued. It should 547 * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE. 548 */ 549 int 550 sciicmd(dev, target, cbuf, clen, buf, len, xferphase) 551 struct sci_softc *dev; 552 void *cbuf, *buf; 553 int clen, len; 554 u_char xferphase; 555 { 556 u_char phase; 557 register int wait; 558 559 /* select the SCSI bus (it's an error if bus isn't free) */ 560 if (sciselectbus (dev, target, dev->sc_scsi_addr)) 561 return -1; 562 /* 563 * Wait for a phase change (or error) then let the device 564 * sequence us through the various SCSI phases. 565 */ 566 dev->sc_stat[0] = 0xff; 567 dev->sc_msg[0] = 0xff; 568 phase = CMD_PHASE; 569 while (1) { 570 wait = sci_cmd_wait; 571 572 while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == SCI_BUS_BSY); 573 574 QPRINTF((">CSR:%02x<", *dev->sci_bus_csr)); 575 if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) { 576 return -1; 577 } 578 phase = SCI_PHASE(*dev->sci_bus_csr); 579 580 switch (phase) { 581 case CMD_PHASE: 582 if (sci_ixfer_out (dev, clen, cbuf, phase)) 583 goto abort; 584 phase = xferphase; 585 break; 586 587 case DATA_IN_PHASE: 588 if (len <= 0) 589 goto abort; 590 wait = sci_data_wait; 591 sci_ixfer_in (dev, len, buf, phase); 592 phase = STATUS_PHASE; 593 break; 594 595 case DATA_OUT_PHASE: 596 if (len <= 0) 597 goto abort; 598 wait = sci_data_wait; 599 if (sci_ixfer_out (dev, len, buf, phase)) 600 goto abort; 601 phase = STATUS_PHASE; 602 break; 603 604 case MESG_IN_PHASE: 605 dev->sc_msg[0] = 0xff; 606 sci_ixfer_in (dev, 1, dev->sc_msg,phase); 607 dev->sc_flags &= ~SCI_SELECTED; 608 while (*dev->sci_bus_csr & SCI_BUS_BSY); 609 goto out; 610 break; 611 612 case MESG_OUT_PHASE: 613 phase = STATUS_PHASE; 614 break; 615 616 case STATUS_PHASE: 617 sci_ixfer_in (dev, 1, dev->sc_stat, phase); 618 phase = MESG_IN_PHASE; 619 break; 620 621 case BUS_FREE_PHASE: 622 goto out; 623 624 default: 625 printf("sci: unexpected phase %d in icmd from %d\n", 626 phase, target); 627 goto abort; 628 } 629 #if 0 630 if (wait <= 0) 631 goto abort; 632 #endif 633 } 634 635 abort: 636 sciabort(dev, "icmd"); 637 out: 638 QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 639 return (dev->sc_stat[0]); 640 } 641 642 int 643 scigo(dev, xs) 644 struct sci_softc *dev; 645 struct scsipi_xfer *xs; 646 { 647 int count, target; 648 u_char phase, *addr; 649 650 target = xs->sc_link->scsipi_scsi.target; 651 count = xs->datalen; 652 addr = xs->data; 653 654 if (sci_no_dma) { 655 sciicmd (dev, target, (u_char *) xs->cmd, xs->cmdlen, 656 addr, count, 657 xs->xs_control & XS_CTL_DATA_IN ? DATA_IN_PHASE : DATA_OUT_PHASE); 658 659 return (1); 660 } 661 662 /* select the SCSI bus (it's an error if bus isn't free) */ 663 if (sciselectbus (dev, target, dev->sc_scsi_addr)) 664 return -1; 665 /* 666 * Wait for a phase change (or error) then let the device 667 * sequence us through the various SCSI phases. 668 */ 669 dev->sc_stat[0] = 0xff; 670 dev->sc_msg[0] = 0xff; 671 phase = CMD_PHASE; 672 while (1) { 673 while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == 674 SCI_BUS_BSY); 675 676 QPRINTF((">CSR:%02x<", *dev->sci_bus_csr)); 677 if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) { 678 goto abort; 679 } 680 phase = SCI_PHASE(*dev->sci_bus_csr); 681 682 switch (phase) { 683 case CMD_PHASE: 684 if (sci_ixfer_out (dev, xs->cmdlen, (u_char *) xs->cmd, phase)) 685 goto abort; 686 phase = xs->xs_control & XS_CTL_DATA_IN ? DATA_IN_PHASE : DATA_OUT_PHASE; 687 break; 688 689 case DATA_IN_PHASE: 690 if (count <= 0) 691 goto abort; 692 /* XXX use psuedo DMA if available */ 693 if (count >= 128 && dev->dma_xfer_in) 694 (*dev->dma_xfer_in)(dev, count, addr, phase); 695 else 696 sci_ixfer_in (dev, count, addr, phase); 697 phase = STATUS_PHASE; 698 break; 699 700 case DATA_OUT_PHASE: 701 if (count <= 0) 702 goto abort; 703 /* XXX use psuedo DMA if available */ 704 if (count >= 128 && dev->dma_xfer_out) 705 (*dev->dma_xfer_out)(dev, count, addr, phase); 706 else 707 if (sci_ixfer_out (dev, count, addr, phase)) 708 goto abort; 709 phase = STATUS_PHASE; 710 break; 711 712 case MESG_IN_PHASE: 713 dev->sc_msg[0] = 0xff; 714 sci_ixfer_in (dev, 1, dev->sc_msg,phase); 715 dev->sc_flags &= ~SCI_SELECTED; 716 while (*dev->sci_bus_csr & SCI_BUS_BSY); 717 goto out; 718 break; 719 720 case MESG_OUT_PHASE: 721 phase = STATUS_PHASE; 722 break; 723 724 case STATUS_PHASE: 725 sci_ixfer_in (dev, 1, dev->sc_stat, phase); 726 phase = MESG_IN_PHASE; 727 break; 728 729 case BUS_FREE_PHASE: 730 goto out; 731 732 default: 733 printf("sci: unexpected phase %d in icmd from %d\n", 734 phase, target); 735 goto abort; 736 } 737 } 738 739 abort: 740 sciabort(dev, "go"); 741 out: 742 QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 743 return (1); 744 } 745