1*57096Sakito /* 2*57096Sakito * Copyright (c) 1992 OMRON Corporation. 3*57096Sakito * Copyright (c) 1992 The Regents of the University of California. 4*57096Sakito * All rights reserved. 5*57096Sakito * 6*57096Sakito * This code is derived from software contributed to Berkeley by 7*57096Sakito * OMRON Corporation. 8*57096Sakito * 9*57096Sakito * %sccs.include.redist.c% 10*57096Sakito * 11*57096Sakito * @(#)sc.c 7.1 (Berkeley) 12/13/92 12*57096Sakito */ 13*57096Sakito 14*57096Sakito /* 15*57096Sakito * sc.c -- SCSI Protocole Controller (SPC) driver 16*57096Sakito * remaked by A.Fujita, MAR-11-199 17*57096Sakito */ 18*57096Sakito 19*57096Sakito 20*57096Sakito #define NSC 1 21*57096Sakito 22*57096Sakito #include <sys/param.h> 23*57096Sakito #include <luna68k/dev/scsireg.h> 24*57096Sakito #include <luna68k/stand/device.h> 25*57096Sakito #include <luna68k/stand/scsivar.h> 26*57096Sakito 27*57096Sakito #define SCSI_IPL 2 28*57096Sakito #define SCSI_ID 7 29*57096Sakito 30*57096Sakito int scinit(), scstart(), scgo(), scintr(), scdone(); 31*57096Sakito void screset(); 32*57096Sakito struct driver scdriver = { 33*57096Sakito scinit, "sc", scstart, scgo, scintr, scdone 34*57096Sakito }; 35*57096Sakito 36*57096Sakito struct scsi_softc scsi_softc[NSC]; 37*57096Sakito 38*57096Sakito /* 39*57096Sakito * Initialize SPC & Data Structure 40*57096Sakito */ 41*57096Sakito 42*57096Sakito int 43*57096Sakito scinit(hc) 44*57096Sakito register struct hp_ctlr *hc; 45*57096Sakito { 46*57096Sakito register struct scsi_softc *hs = &scsi_softc[hc->hp_unit]; 47*57096Sakito register int i; 48*57096Sakito 49*57096Sakito hc->hp_ipl = SCSI_IPL; 50*57096Sakito hs->sc_hc = hc; 51*57096Sakito 52*57096Sakito hs->sc_flags = 0; 53*57096Sakito hs->sc_phase = BUS_FREE_PHASE; 54*57096Sakito hs->sc_target = SCSI_ID; 55*57096Sakito 56*57096Sakito hs->sc_cdb = NULL; 57*57096Sakito hs->sc_cdblen = 0; 58*57096Sakito hs->sc_buf = NULL; 59*57096Sakito hs->sc_len = 0; 60*57096Sakito hs->sc_lock = NULL; 61*57096Sakito 62*57096Sakito hs->sc_stat = 0; 63*57096Sakito hs->sc_msg[0] = 0; 64*57096Sakito 65*57096Sakito screset(hc->hp_unit); 66*57096Sakito return(1); 67*57096Sakito } 68*57096Sakito 69*57096Sakito void 70*57096Sakito screset(unit) 71*57096Sakito register int unit; 72*57096Sakito { 73*57096Sakito register struct scsi_softc *hs = &scsi_softc[unit]; 74*57096Sakito volatile register struct scsidevice *hd = 75*57096Sakito (struct scsidevice *)hs->sc_hc->hp_addr; 76*57096Sakito 77*57096Sakito printf("sc%d: ", unit); 78*57096Sakito 79*57096Sakito /* 80*57096Sakito * Disable interrupts then reset the FUJI chip. 81*57096Sakito */ 82*57096Sakito 83*57096Sakito hd->scsi_sctl = SCTL_DISABLE | SCTL_CTRLRST; 84*57096Sakito hd->scsi_scmd = 0; 85*57096Sakito hd->scsi_pctl = 0; 86*57096Sakito hd->scsi_temp = 0; 87*57096Sakito hd->scsi_tch = 0; 88*57096Sakito hd->scsi_tcm = 0; 89*57096Sakito hd->scsi_tcl = 0; 90*57096Sakito hd->scsi_ints = 0; 91*57096Sakito 92*57096Sakito /* We can use Asynchronous Transfer only */ 93*57096Sakito printf("async"); 94*57096Sakito 95*57096Sakito /* 96*57096Sakito * Configure MB89352 with its SCSI address, all 97*57096Sakito * interrupts enabled & appropriate parity. 98*57096Sakito */ 99*57096Sakito hd->scsi_bdid = SCSI_ID; 100*57096Sakito hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB| 101*57096Sakito SCTL_PARITY_ENAB | SCTL_RESEL_ENAB | 102*57096Sakito SCTL_INTR_ENAB; 103*57096Sakito printf(", parity"); 104*57096Sakito 105*57096Sakito DELAY(400); 106*57096Sakito hd->scsi_sctl &= ~SCTL_DISABLE; 107*57096Sakito 108*57096Sakito printf(", scsi id %d\n", SCSI_ID); 109*57096Sakito } 110*57096Sakito 111*57096Sakito 112*57096Sakito /* 113*57096Sakito * SPC Arbitration/Selection routine 114*57096Sakito */ 115*57096Sakito 116*57096Sakito int 117*57096Sakito issue_select(hd, target) 118*57096Sakito volatile register struct scsidevice *hd; 119*57096Sakito u_char target; 120*57096Sakito { 121*57096Sakito hd->scsi_pctl = 0; 122*57096Sakito hd->scsi_temp = (1 << SCSI_ID) | (1 << target); 123*57096Sakito 124*57096Sakito /* select timeout is hardcoded to 2ms */ 125*57096Sakito hd->scsi_tch = 0; 126*57096Sakito hd->scsi_tcm = 32; 127*57096Sakito hd->scsi_tcl = 4; 128*57096Sakito 129*57096Sakito hd->scsi_scmd = SCMD_SELECT; 130*57096Sakito 131*57096Sakito return (1); 132*57096Sakito } 133*57096Sakito 134*57096Sakito 135*57096Sakito /* 136*57096Sakito * SPC Manual Transfer routines 137*57096Sakito */ 138*57096Sakito 139*57096Sakito /* not yet */ 140*57096Sakito 141*57096Sakito 142*57096Sakito /* 143*57096Sakito * SPC Program Transfer routines 144*57096Sakito */ 145*57096Sakito 146*57096Sakito int 147*57096Sakito ixfer_start(hd, len, phase, wait) 148*57096Sakito volatile register struct scsidevice *hd; 149*57096Sakito int len; 150*57096Sakito u_char phase; 151*57096Sakito register int wait; 152*57096Sakito { 153*57096Sakito hd->scsi_tch = ((len & 0xff0000) >> 16); 154*57096Sakito hd->scsi_tcm = ((len & 0x00ff00) >> 8); 155*57096Sakito hd->scsi_tcl = (len & 0x0000ff); 156*57096Sakito hd->scsi_pctl = phase; 157*57096Sakito hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR; 158*57096Sakito } 159*57096Sakito 160*57096Sakito int 161*57096Sakito ixfer_out(hd, len, buf) 162*57096Sakito volatile register struct scsidevice *hd; 163*57096Sakito int len; 164*57096Sakito register u_char *buf; 165*57096Sakito { 166*57096Sakito for(; len > 0; len--) { 167*57096Sakito while (hd->scsi_ssts & SSTS_DREG_FULL) { 168*57096Sakito DELAY(5); 169*57096Sakito } 170*57096Sakito hd->scsi_dreg = *buf++; 171*57096Sakito } 172*57096Sakito } 173*57096Sakito 174*57096Sakito int 175*57096Sakito ixfer_in(hd, len, buf) 176*57096Sakito volatile register struct scsidevice *hd; 177*57096Sakito int len; 178*57096Sakito register u_char *buf; 179*57096Sakito { 180*57096Sakito for (; len > 0; len--) { 181*57096Sakito int i; 182*57096Sakito while (hd->scsi_ssts & SSTS_DREG_EMPTY) { 183*57096Sakito DELAY(5); 184*57096Sakito } 185*57096Sakito *buf++ = hd->scsi_dreg; 186*57096Sakito } 187*57096Sakito } 188*57096Sakito 189*57096Sakito 190*57096Sakito /* 191*57096Sakito * SPC drive routines 192*57096Sakito */ 193*57096Sakito 194*57096Sakito int 195*57096Sakito scrun(ctlr, slave, cdb, cdblen, buf, len, lock) 196*57096Sakito int ctlr, slave; 197*57096Sakito u_char *cdb; 198*57096Sakito int cdblen; 199*57096Sakito u_char *buf; 200*57096Sakito int len; 201*57096Sakito int *lock; 202*57096Sakito { 203*57096Sakito register struct scsi_softc *hs = &scsi_softc[ctlr]; 204*57096Sakito volatile register struct scsidevice *hd = 205*57096Sakito (struct scsidevice *) hs->sc_hc->hp_addr; 206*57096Sakito 207*57096Sakito if (hd->scsi_ssts & (SSTS_INITIATOR|SSTS_TARGET|SSTS_BUSY)) 208*57096Sakito return(0); 209*57096Sakito 210*57096Sakito hs->sc_flags = 0; 211*57096Sakito hs->sc_phase = ARB_SEL_PHASE; 212*57096Sakito hs->sc_target = slave; 213*57096Sakito 214*57096Sakito hs->sc_cdb = cdb; 215*57096Sakito hs->sc_cdblen = cdblen; 216*57096Sakito hs->sc_buf = buf; 217*57096Sakito hs->sc_len = len; 218*57096Sakito hs->sc_lock = lock; 219*57096Sakito 220*57096Sakito hs->sc_stat = 0; 221*57096Sakito hs->sc_msg[0] = 0; 222*57096Sakito 223*57096Sakito *(hs->sc_lock) = SC_IN_PROGRESS; 224*57096Sakito issue_select(hd, hs->sc_target); 225*57096Sakito 226*57096Sakito return(1); 227*57096Sakito } 228*57096Sakito 229*57096Sakito int 230*57096Sakito scfinish(ctlr) 231*57096Sakito int ctlr; 232*57096Sakito { 233*57096Sakito register struct scsi_softc *hs = &scsi_softc[ctlr]; 234*57096Sakito int status = hs->sc_stat; 235*57096Sakito 236*57096Sakito hs->sc_flags = 0; 237*57096Sakito hs->sc_phase = BUS_FREE_PHASE; 238*57096Sakito hs->sc_target = SCSI_ID; 239*57096Sakito 240*57096Sakito hs->sc_cdb = NULL; 241*57096Sakito hs->sc_cdblen = 0; 242*57096Sakito hs->sc_buf = NULL; 243*57096Sakito hs->sc_len = 0; 244*57096Sakito hs->sc_lock = NULL; 245*57096Sakito 246*57096Sakito hs->sc_stat = 0; 247*57096Sakito hs->sc_msg[0] = 0; 248*57096Sakito 249*57096Sakito return(status); 250*57096Sakito } 251*57096Sakito 252*57096Sakito int 253*57096Sakito scabort(hs, hd) 254*57096Sakito register struct scsi_softc *hs; 255*57096Sakito volatile register struct scsidevice *hd; 256*57096Sakito { 257*57096Sakito int len; 258*57096Sakito u_char junk; 259*57096Sakito 260*57096Sakito printf("sc%d: abort phase=0x%x, ssts=0x%x, ints=0x%x\n", 261*57096Sakito hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts, 262*57096Sakito hd->scsi_ints); 263*57096Sakito 264*57096Sakito if (hd->scsi_ints != 0) 265*57096Sakito hd->scsi_ints = hd->scsi_ints; 266*57096Sakito 267*57096Sakito if (hd->scsi_psns == 0 || (hd->scsi_ssts & SSTS_INITIATOR) == 0) 268*57096Sakito /* no longer connected to scsi target */ 269*57096Sakito return; 270*57096Sakito 271*57096Sakito /* get the number of bytes remaining in current xfer + fudge */ 272*57096Sakito len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | hd->scsi_tcl; 273*57096Sakito 274*57096Sakito /* for that many bus cycles, try to send an abort msg */ 275*57096Sakito for (len += 1024; (hd->scsi_ssts & SSTS_INITIATOR) && --len >= 0; ) { 276*57096Sakito hd->scsi_scmd = SCMD_SET_ATN; 277*57096Sakito 278*57096Sakito while ((hd->scsi_psns & PSNS_REQ) == 0) { 279*57096Sakito if (! (hd->scsi_ssts & SSTS_INITIATOR)) 280*57096Sakito goto out; 281*57096Sakito DELAY(1); 282*57096Sakito } 283*57096Sakito 284*57096Sakito if ((hd->scsi_psns & PHASE) == MESG_OUT_PHASE) 285*57096Sakito hd->scsi_scmd = SCMD_RST_ATN; 286*57096Sakito hd->scsi_pctl = hs->sc_phase = hd->scsi_psns & PHASE; 287*57096Sakito 288*57096Sakito if (hd->scsi_psns & PHASE_IO) { 289*57096Sakito /* one of the input phases - read & discard a byte */ 290*57096Sakito hd->scsi_scmd = SCMD_SET_ACK; 291*57096Sakito while (hd->scsi_psns & PSNS_REQ) 292*57096Sakito DELAY(1); 293*57096Sakito junk = hd->scsi_temp; 294*57096Sakito } else { 295*57096Sakito /* one of the output phases - send an abort msg */ 296*57096Sakito hd->scsi_temp = MSG_ABORT; 297*57096Sakito hd->scsi_scmd = SCMD_SET_ACK; 298*57096Sakito while (hd->scsi_psns & PSNS_REQ) 299*57096Sakito DELAY(1); 300*57096Sakito } 301*57096Sakito 302*57096Sakito hd->scsi_scmd = SCMD_RST_ACK; 303*57096Sakito } 304*57096Sakito out: 305*57096Sakito /* 306*57096Sakito * Either the abort was successful & the bus is disconnected or 307*57096Sakito * the device didn't listen. If the latter, announce the problem. 308*57096Sakito * Either way, reset the card & the SPC. 309*57096Sakito */ 310*57096Sakito if (len < 0 && hs) 311*57096Sakito printf("sc%d: abort failed. phase=0x%x, ssts=0x%x\n", 312*57096Sakito hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts); 313*57096Sakito } 314*57096Sakito 315*57096Sakito 316*57096Sakito /* 317*57096Sakito * SCSI Command Handler 318*57096Sakito */ 319*57096Sakito 320*57096Sakito int 321*57096Sakito scsi_test_unit_rdy(ctlr, slave, unit) 322*57096Sakito int ctlr, slave, unit; 323*57096Sakito { 324*57096Sakito static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY }; 325*57096Sakito int status, lock; 326*57096Sakito 327*57096Sakito #ifdef DEBUG 328*57096Sakito printf("scsi_test_unit_rdy( %d, %d, %d): Start\n", ctlr, slave, unit); 329*57096Sakito #endif 330*57096Sakito 331*57096Sakito cdb.lun = unit; 332*57096Sakito 333*57096Sakito if (!(scrun(ctlr, slave, &cdb, 6, (u_char *) 0, 0, &lock))) { 334*57096Sakito #ifdef DEBUG 335*57096Sakito printf("scsi_test_unit_rdy: Command Transfer Failed.\n"); 336*57096Sakito #endif 337*57096Sakito return(-1); 338*57096Sakito } 339*57096Sakito 340*57096Sakito while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) 341*57096Sakito DELAY(10); 342*57096Sakito 343*57096Sakito status = scfinish(ctlr); 344*57096Sakito 345*57096Sakito if (lock == SC_IO_COMPLETE) { 346*57096Sakito #ifdef DEBUG 347*57096Sakito printf("scsi_test_unit_rdy: Status -- 0x%x\n", status); 348*57096Sakito #endif 349*57096Sakito return(status); 350*57096Sakito } else { 351*57096Sakito return(lock); 352*57096Sakito } 353*57096Sakito } 354*57096Sakito 355*57096Sakito int 356*57096Sakito scsi_request_sense(ctlr, slave, unit, buf, len) 357*57096Sakito int ctlr, slave, unit; 358*57096Sakito u_char *buf; 359*57096Sakito unsigned len; 360*57096Sakito { 361*57096Sakito static struct scsi_cdb6 cdb = { CMD_REQUEST_SENSE }; 362*57096Sakito int status, lock; 363*57096Sakito 364*57096Sakito #ifdef DEBUG 365*57096Sakito printf("scsi_request_sense: Start\n"); 366*57096Sakito #endif 367*57096Sakito 368*57096Sakito /* Request Sense$N>l9g!"E>Aw$5$l$k%G!<%?D9$O%?!<%2368H$K0MB8$7!" */ 369*57096Sakito /* %;%s%9%G!<%?$N#8/usr/home/csrg/sccs/sys/luna68k/stand/SCCS/s.sc.c$%HL\$NAddtional Sens Length$K$h$jF0E*$K7hDj$9$k!#*/ 370*57096Sakito /* $3$3$G$O%G!<%?!<E>Aw?t$rcdb$NAllocation Length$K:GDcD9$G$"$k#8/usr/home/csrg/sccs/sys/luna68k/stand/SCCS/s.sc.c$%H */ 371*57096Sakito /* $r8GDj$7$F!"#S#P#C$N=hM}%7!<%1%s%9$rJx$5$J$$$h$&$K$7$F$$$k!# */ 372*57096Sakito 373*57096Sakito /* %F!<@(#)sc.c 7.1f%K373H$N>uBV$rD4$Y$k$?$a!"Addtional Sens Field$r%"%/%;%9$9$k */ 374*57096Sakito /* I,MW$,$"$k$N$G12/13/92P%$%97.1i%$%PB&$Glen$r7hDj$9$k$3$H$K$9$k */ 375*57096Sakito 376*57096Sakito cdb.lun = unit; 377*57096Sakito cdb.len = len; 378*57096Sakito 379*57096Sakito if (!(scrun(ctlr, slave, &cdb, 6, buf, len, &lock))) { 380*57096Sakito #ifdef DEBUG 381*57096Sakito printf("scsi_request_sense: Command Transfer Failed.\n"); 382*57096Sakito #endif 383*57096Sakito return(-1); 384*57096Sakito } 385*57096Sakito 386*57096Sakito while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) 387*57096Sakito DELAY(10); 388*57096Sakito 389*57096Sakito status = scfinish(ctlr); 390*57096Sakito 391*57096Sakito if (lock == SC_IO_COMPLETE) { 392*57096Sakito #ifdef DEBUG 393*57096Sakito printf("scsi_request_sense: Status -- 0x%x\n", status); 394*57096Sakito #endif 395*57096Sakito return(status); 396*57096Sakito } else { 397*57096Sakito return(lock); 398*57096Sakito } 399*57096Sakito } 400*57096Sakito 401*57096Sakito int 402*57096Sakito scsi_immed_command(ctlr, slave, unit, cdb, buf, len) 403*57096Sakito int ctlr, slave, unit; 404*57096Sakito struct scsi_fmt_cdb *cdb; 405*57096Sakito u_char *buf; 406*57096Sakito unsigned len; 407*57096Sakito { 408*57096Sakito int lock, status; 409*57096Sakito 410*57096Sakito #ifdef DEBUG 411*57096Sakito printf("scsi_immed_command( %d, %d, %d, cdb(%d), buf, %d): Start\n", 412*57096Sakito ctlr, slave, unit, cdb->len, len); 413*57096Sakito #endif 414*57096Sakito 415*57096Sakito cdb->cdb[1] |= unit << 5; 416*57096Sakito 417*57096Sakito if (!(scrun(ctlr, slave, &cdb->cdb[0], cdb->len, buf, len, &lock))) { 418*57096Sakito #ifdef DEBUG 419*57096Sakito printf("scsi_immed_command: Command Transfer Failed.\n"); 420*57096Sakito #endif 421*57096Sakito return(-1); 422*57096Sakito } 423*57096Sakito 424*57096Sakito while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) 425*57096Sakito DELAY(10); 426*57096Sakito 427*57096Sakito status = scfinish(ctlr); 428*57096Sakito 429*57096Sakito if (lock == SC_IO_COMPLETE) { 430*57096Sakito #ifdef DEBUG 431*57096Sakito printf("scsi_immed_command: Status -- 0x%x\n", status); 432*57096Sakito #endif 433*57096Sakito return(status); 434*57096Sakito } else { 435*57096Sakito return(lock); 436*57096Sakito } 437*57096Sakito } 438*57096Sakito 439*57096Sakito int 440*57096Sakito scsi_format_unit(ctlr, slave, unit) 441*57096Sakito int ctlr, slave, unit; 442*57096Sakito { 443*57096Sakito static struct scsi_cdb6 cdb = { CMD_FORMAT_UNIT, 0, 0, 0, 0, 0 }; 444*57096Sakito int status, lock, count = 0; 445*57096Sakito 446*57096Sakito #ifdef DEBUG 447*57096Sakito printf("scsi_format_unit( %d, %d, %d): Start\n", ctlr, slave, unit); 448*57096Sakito #endif 449*57096Sakito 450*57096Sakito cdb.lun = unit; 451*57096Sakito 452*57096Sakito if (!(scrun(ctlr, slave, &cdb, 6, (u_char *) 0, 0, &lock))) { 453*57096Sakito #ifdef DEBUG 454*57096Sakito printf("scsi_format_unit: Command Transfer Failed.\n"); 455*57096Sakito #endif 456*57096Sakito return(-1); 457*57096Sakito } 458*57096Sakito 459*57096Sakito while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) { 460*57096Sakito DELAY(1000000); 461*57096Sakito #ifdef DEBUG 462*57096Sakito if ((count % 60) == 0) 463*57096Sakito printf("scsi_format_unit: %d\n"); 464*57096Sakito #endif 465*57096Sakito } 466*57096Sakito 467*57096Sakito status = scfinish(ctlr); 468*57096Sakito 469*57096Sakito if (lock == SC_IO_COMPLETE) { 470*57096Sakito #ifdef DEBUG 471*57096Sakito printf("scsi_format_unit: Status -- 0x%x\n", status); 472*57096Sakito #endif 473*57096Sakito return(status); 474*57096Sakito } else { 475*57096Sakito return(lock); 476*57096Sakito } 477*57096Sakito } 478*57096Sakito 479*57096Sakito 480*57096Sakito /* 481*57096Sakito * ???? 482*57096Sakito */ 483*57096Sakito 484*57096Sakito int 485*57096Sakito scstart() 486*57096Sakito { 487*57096Sakito } 488*57096Sakito 489*57096Sakito int 490*57096Sakito scgo() 491*57096Sakito { 492*57096Sakito } 493*57096Sakito 494*57096Sakito int 495*57096Sakito scdone() 496*57096Sakito { 497*57096Sakito } 498*57096Sakito 499*57096Sakito 500*57096Sakito /* 501*57096Sakito * Interrupt Routine 502*57096Sakito */ 503*57096Sakito 504*57096Sakito int 505*57096Sakito scintr() 506*57096Sakito { 507*57096Sakito register struct scsi_softc *hs; 508*57096Sakito volatile register struct scsidevice *hd; 509*57096Sakito register u_char ints, temp; 510*57096Sakito register int i; 511*57096Sakito u_char *buf; 512*57096Sakito int len; 513*57096Sakito 514*57096Sakito for (i = 0; i < NSC; i++) { 515*57096Sakito hs = &scsi_softc[i]; 516*57096Sakito hd = (struct scsidevice *) hs->sc_hc->hp_addr; 517*57096Sakito if ((ints = hd->scsi_ints) != 0) 518*57096Sakito goto get_intr; 519*57096Sakito } 520*57096Sakito 521*57096Sakito /* Unknown Interrupt occured */ 522*57096Sakito return; 523*57096Sakito 524*57096Sakito 525*57096Sakito /* 526*57096Sakito * Interrupt 527*57096Sakito */ 528*57096Sakito 529*57096Sakito get_intr: 530*57096Sakito #ifdef DEBUG 531*57096Sakito printf("scintr: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x 0x%x\n", 532*57096Sakito ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns, 533*57096Sakito hs->sc_phase); 534*57096Sakito #endif 535*57096Sakito if (ints & INTS_RESEL) { 536*57096Sakito if (hs->sc_phase == BUS_FREE_PHASE) { 537*57096Sakito temp = hd->scsi_temp & ~(1 << SCSI_ID); 538*57096Sakito for (i = 0; temp != 1; i++) { 539*57096Sakito temp >>= 1; 540*57096Sakito } 541*57096Sakito hs->sc_target = i; 542*57096Sakito *(hs->sc_lock) = SC_IN_PROGRESS; 543*57096Sakito } else 544*57096Sakito goto abort; 545*57096Sakito } else if (ints & INTS_DISCON) { 546*57096Sakito if ((hs->sc_msg[0] == MSG_CMD_COMPLETE) || (hs->sc_msg[0] == MSG_DISCONNECT)) { 547*57096Sakito hs->sc_phase = BUS_FREE_PHASE; 548*57096Sakito hs->sc_target = SCSI_ID; 549*57096Sakito if (hs->sc_msg[0] == MSG_CMD_COMPLETE) 550*57096Sakito /* SCSI IO complete */ 551*57096Sakito *(hs->sc_lock) = SC_IO_COMPLETE; 552*57096Sakito else 553*57096Sakito /* Cisconnected from Target */ 554*57096Sakito *(hs->sc_lock) = SC_DISCONNECTED; 555*57096Sakito hd->scsi_ints = ints; 556*57096Sakito return; 557*57096Sakito } else 558*57096Sakito goto abort; 559*57096Sakito } else if (ints & INTS_CMD_DONE) { 560*57096Sakito if (hs->sc_phase == BUS_FREE_PHASE) 561*57096Sakito goto abort; 562*57096Sakito else if (hs->sc_phase == MESG_IN_PHASE) { 563*57096Sakito hd->scsi_scmd = SCMD_RST_ACK; 564*57096Sakito hd->scsi_ints = ints; 565*57096Sakito hs->sc_phase = hd->scsi_psns & PHASE; 566*57096Sakito return; 567*57096Sakito } 568*57096Sakito if (hs->sc_flags & SC_SEL_TIMEOUT) 569*57096Sakito hs->sc_flags &= ~SC_SEL_TIMEOUT; 570*57096Sakito } else if (ints & INTS_SRV_REQ) { 571*57096Sakito if (hs->sc_phase != MESG_IN_PHASE) 572*57096Sakito goto abort; 573*57096Sakito } else if (ints & INTS_TIMEOUT) { 574*57096Sakito if (hs->sc_phase == ARB_SEL_PHASE) { 575*57096Sakito if (hs->sc_flags & SC_SEL_TIMEOUT) { 576*57096Sakito hs->sc_flags &= ~SC_SEL_TIMEOUT; 577*57096Sakito hs->sc_phase = BUS_FREE_PHASE; 578*57096Sakito hs->sc_target = SCSI_ID; 579*57096Sakito /* Such SCSI Device is not conected. */ 580*57096Sakito *(hs->sc_lock) = SC_DEV_NOT_FOUND; 581*57096Sakito hd->scsi_ints = ints; 582*57096Sakito return; 583*57096Sakito } else { 584*57096Sakito /* wait more 250 usec */ 585*57096Sakito hs->sc_flags |= SC_SEL_TIMEOUT; 586*57096Sakito hd->scsi_temp = 0; 587*57096Sakito hd->scsi_tch = 0; 588*57096Sakito hd->scsi_tcm = 0x06; 589*57096Sakito hd->scsi_tcl = 0x40; 590*57096Sakito hd->scsi_ints = ints; 591*57096Sakito return; 592*57096Sakito } 593*57096Sakito } else 594*57096Sakito goto abort; 595*57096Sakito } else 596*57096Sakito goto abort; 597*57096Sakito 598*57096Sakito hd->scsi_ints = ints; 599*57096Sakito 600*57096Sakito /* 601*57096Sakito * Next SCSI Transfer 602*57096Sakito */ 603*57096Sakito 604*57096Sakito while ((hd->scsi_psns & PSNS_REQ) == 0) { 605*57096Sakito DELAY(1); 606*57096Sakito } 607*57096Sakito 608*57096Sakito hs->sc_phase = hd->scsi_psns & PHASE; 609*57096Sakito 610*57096Sakito if ((hs->sc_phase == DATA_OUT_PHASE) || (hs->sc_phase == DATA_IN_PHASE)) { 611*57096Sakito len = hs->sc_len; 612*57096Sakito buf = hs->sc_buf; 613*57096Sakito } else if (hs->sc_phase == CMD_PHASE) { 614*57096Sakito len = hs->sc_cdblen; 615*57096Sakito buf = hs->sc_cdb; 616*57096Sakito } else if (hs->sc_phase == STATUS_PHASE) { 617*57096Sakito len = 1; 618*57096Sakito buf = &hs->sc_stat; 619*57096Sakito } else { 620*57096Sakito len = 1; 621*57096Sakito buf = hs->sc_msg; 622*57096Sakito } 623*57096Sakito 624*57096Sakito ixfer_start(hd, len, hs->sc_phase, 0); 625*57096Sakito if (hs->sc_phase & PHASE_IO) 626*57096Sakito ixfer_in(hd, len, buf); 627*57096Sakito else 628*57096Sakito ixfer_out(hd, len, buf); 629*57096Sakito 630*57096Sakito return; 631*57096Sakito 632*57096Sakito /* 633*57096Sakito * SCSI Abort 634*57096Sakito */ 635*57096Sakito abort: 636*57096Sakito /* SCSI IO failed */ 637*57096Sakito scabort(hs, hd); 638*57096Sakito hd->scsi_ints = ints; 639*57096Sakito *(hs->sc_lock) = SC_IO_FAILED; 640*57096Sakito return; 641*57096Sakito } 642