1*41480Smckusick /* 2*41480Smckusick * Copyright (c) 1990 The Regents of the University of California. 3*41480Smckusick * All rights reserved. 4*41480Smckusick * 5*41480Smckusick * This code is derived from software contributed to Berkeley by 6*41480Smckusick * Van Jacobson of Lawrence Berkeley Laboratory. 7*41480Smckusick * 8*41480Smckusick * %sccs.include.redist.c% 9*41480Smckusick * 10*41480Smckusick * @(#)scsi.c 7.1 (Berkeley) 05/08/90 11*41480Smckusick */ 12*41480Smckusick 13*41480Smckusick /* 14*41480Smckusick * HP9000/3xx 98658 SCSI host adaptor driver. 15*41480Smckusick */ 16*41480Smckusick #include "scsi.h" 17*41480Smckusick #if NSCSI > 0 18*41480Smckusick 19*41480Smckusick #ifndef lint 20*41480Smckusick static char rcsid[] = "$Header: scsi.c,v 1.3 90/01/06 04:56:50 van Exp $"; 21*41480Smckusick #endif 22*41480Smckusick 23*41480Smckusick #include "param.h" 24*41480Smckusick #include "systm.h" 25*41480Smckusick #include "buf.h" 26*41480Smckusick #include "device.h" 27*41480Smckusick #include "scsivar.h" 28*41480Smckusick #include "scsireg.h" 29*41480Smckusick #include "dmavar.h" 30*41480Smckusick 31*41480Smckusick #include "machine/cpu.h" 32*41480Smckusick #include "machine/isr.h" 33*41480Smckusick 34*41480Smckusick extern void isrlink(); 35*41480Smckusick extern void printf(); 36*41480Smckusick extern void _insque(); 37*41480Smckusick extern void _remque(); 38*41480Smckusick extern void bzero(); 39*41480Smckusick 40*41480Smckusick int scsiinit(), scsigo(), scsiintr(), scsixfer(); 41*41480Smckusick void scsistart(), scsidone(), scsifree(), scsireset(); 42*41480Smckusick struct driver scsidriver = { 43*41480Smckusick scsiinit, "scsi", (int (*)())scsistart, scsigo, scsiintr, 44*41480Smckusick (int (*)())scsidone, 45*41480Smckusick }; 46*41480Smckusick 47*41480Smckusick struct scsi_softc scsi_softc[NSCSI]; 48*41480Smckusick struct isr scsi_isr[NSCSI]; 49*41480Smckusick 50*41480Smckusick int scsi_cmd_wait = 512; /* microsec wait per step of 'immediate' cmds */ 51*41480Smckusick int scsi_data_wait = 512; /* wait per data in/out step */ 52*41480Smckusick int scsi_nosync = 1; /* inhibit sync xfers if 1 */ 53*41480Smckusick 54*41480Smckusick #ifdef DEBUG 55*41480Smckusick int scsi_debug = 0; 56*41480Smckusick #define WAITHIST 57*41480Smckusick #endif 58*41480Smckusick 59*41480Smckusick #ifdef WAITHIST 60*41480Smckusick #define MAXWAIT 2048 61*41480Smckusick u_int ixstart_wait[MAXWAIT+2]; 62*41480Smckusick u_int ixin_wait[MAXWAIT+2]; 63*41480Smckusick u_int ixout_wait[MAXWAIT+2]; 64*41480Smckusick u_int mxin_wait[MAXWAIT+2]; 65*41480Smckusick u_int cxin_wait[MAXWAIT+2]; 66*41480Smckusick u_int fxfr_wait[MAXWAIT+2]; 67*41480Smckusick u_int sgo_wait[MAXWAIT+2]; 68*41480Smckusick #define HIST(h,w) (++h[((w)>MAXWAIT? MAXWAIT : ((w) < 0 ? -1 : (w))) + 1]); 69*41480Smckusick #else 70*41480Smckusick #define HIST(h,w) 71*41480Smckusick #endif 72*41480Smckusick 73*41480Smckusick #define b_cylin b_resid 74*41480Smckusick 75*41480Smckusick static void 76*41480Smckusick scsiabort(hs, hd, where) 77*41480Smckusick register struct scsi_softc *hs; 78*41480Smckusick volatile register struct scsidevice *hd; 79*41480Smckusick char *where; 80*41480Smckusick { 81*41480Smckusick int len; 82*41480Smckusick u_char junk; 83*41480Smckusick 84*41480Smckusick printf("scsi%d: abort from %s: phase=0x%x, ssts=0x%x, ints=0x%x\n", 85*41480Smckusick hs->sc_hc->hp_unit, where, hd->scsi_psns, hd->scsi_ssts, 86*41480Smckusick hd->scsi_ints); 87*41480Smckusick 88*41480Smckusick hd->scsi_ints = hd->scsi_ints; 89*41480Smckusick hd->scsi_csr = 0; 90*41480Smckusick if (hd->scsi_psns == 0 || (hd->scsi_ssts & SSTS_INITIATOR) == 0) 91*41480Smckusick /* no longer connected to scsi target */ 92*41480Smckusick return; 93*41480Smckusick 94*41480Smckusick /* get the number of bytes remaining in current xfer + fudge */ 95*41480Smckusick len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | hd->scsi_tcl; 96*41480Smckusick 97*41480Smckusick /* for that many bus cycles, try to send an abort msg */ 98*41480Smckusick for (len += 1024; (hd->scsi_ssts & SSTS_INITIATOR) && --len >= 0; ) { 99*41480Smckusick hd->scsi_scmd = SCMD_SET_ATN; 100*41480Smckusick while ((hd->scsi_psns & PSNS_REQ) == 0) { 101*41480Smckusick if (! (hd->scsi_ssts & SSTS_INITIATOR)) 102*41480Smckusick goto out; 103*41480Smckusick DELAY(1); 104*41480Smckusick } 105*41480Smckusick if ((hd->scsi_psns & PHASE) == MESG_OUT_PHASE) 106*41480Smckusick hd->scsi_scmd = SCMD_RST_ATN; 107*41480Smckusick hd->scsi_pctl = hd->scsi_psns & PHASE; 108*41480Smckusick if (hd->scsi_psns & PHASE_IO) { 109*41480Smckusick /* one of the input phases - read & discard a byte */ 110*41480Smckusick hd->scsi_scmd = SCMD_SET_ACK; 111*41480Smckusick if (hd->scsi_tmod == 0) 112*41480Smckusick while (hd->scsi_psns & PSNS_REQ) 113*41480Smckusick DELAY(1); 114*41480Smckusick junk = hd->scsi_temp; 115*41480Smckusick } else { 116*41480Smckusick /* one of the output phases - send an abort msg */ 117*41480Smckusick hd->scsi_temp = MSG_ABORT; 118*41480Smckusick hd->scsi_scmd = SCMD_SET_ACK; 119*41480Smckusick if (hd->scsi_tmod == 0) 120*41480Smckusick while (hd->scsi_psns & PSNS_REQ) 121*41480Smckusick DELAY(1); 122*41480Smckusick } 123*41480Smckusick hd->scsi_scmd = SCMD_RST_ACK; 124*41480Smckusick } 125*41480Smckusick out: 126*41480Smckusick /* 127*41480Smckusick * Either the abort was successful & the bus is disconnected or 128*41480Smckusick * the device didn't listen. If the latter, announce the problem. 129*41480Smckusick * Either way, reset the card & the SPC. 130*41480Smckusick */ 131*41480Smckusick if (len < 0 && hs) 132*41480Smckusick printf("scsi%d: abort failed. phase=0x%x, ssts=0x%x\n", 133*41480Smckusick hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts); 134*41480Smckusick 135*41480Smckusick if (! ((junk = hd->scsi_ints) & INTS_RESEL)) { 136*41480Smckusick hd->scsi_sctl |= SCTL_CTRLRST; 137*41480Smckusick DELAY(1); 138*41480Smckusick hd->scsi_sctl &=~ SCTL_CTRLRST; 139*41480Smckusick hd->scsi_hconf = 0; 140*41480Smckusick hd->scsi_ints = hd->scsi_ints; 141*41480Smckusick } 142*41480Smckusick } 143*41480Smckusick 144*41480Smckusick int 145*41480Smckusick scsiinit(hc) 146*41480Smckusick register struct hp_ctlr *hc; 147*41480Smckusick { 148*41480Smckusick register struct scsi_softc *hs = &scsi_softc[hc->hp_unit]; 149*41480Smckusick register struct scsidevice *hd = (struct scsidevice *)hc->hp_addr; 150*41480Smckusick 151*41480Smckusick if ((hd->scsi_id & ID_MASK) != SCSI_ID) 152*41480Smckusick return(0); 153*41480Smckusick hc->hp_ipl = SCSI_IPL(hd->scsi_csr); 154*41480Smckusick hs->sc_hc = hc; 155*41480Smckusick hs->sc_dq.dq_unit = hc->hp_unit; 156*41480Smckusick hs->sc_dq.dq_driver = &scsidriver; 157*41480Smckusick hs->sc_sq.dq_forw = hs->sc_sq.dq_back = &hs->sc_sq; 158*41480Smckusick scsi_isr[hc->hp_unit].isr_intr = scsiintr; 159*41480Smckusick scsi_isr[hc->hp_unit].isr_ipl = hc->hp_ipl; 160*41480Smckusick scsi_isr[hc->hp_unit].isr_arg = hc->hp_unit; 161*41480Smckusick isrlink(&scsi_isr[hc->hp_unit]); 162*41480Smckusick scsireset(hc->hp_unit); 163*41480Smckusick return(1); 164*41480Smckusick } 165*41480Smckusick 166*41480Smckusick void 167*41480Smckusick scsireset(unit) 168*41480Smckusick register int unit; 169*41480Smckusick { 170*41480Smckusick register struct scsi_softc *hs = &scsi_softc[unit]; 171*41480Smckusick volatile register struct scsidevice *hd = 172*41480Smckusick (struct scsidevice *)hs->sc_hc->hp_addr; 173*41480Smckusick u_int i; 174*41480Smckusick 175*41480Smckusick if (hs->sc_flags & SCSI_ALIVE) 176*41480Smckusick scsiabort(hs, hd, "reset"); 177*41480Smckusick 178*41480Smckusick printf("scsi%d: ", unit); 179*41480Smckusick 180*41480Smckusick hd->scsi_id = 0xFF; 181*41480Smckusick DELAY(100); 182*41480Smckusick /* 183*41480Smckusick * Disable interrupts then reset the FUJI chip. 184*41480Smckusick */ 185*41480Smckusick hd->scsi_csr = 0; 186*41480Smckusick hd->scsi_sctl = SCTL_DISABLE | SCTL_CTRLRST; 187*41480Smckusick hd->scsi_scmd = 0; 188*41480Smckusick hd->scsi_tmod = 0; 189*41480Smckusick hd->scsi_pctl = 0; 190*41480Smckusick hd->scsi_temp = 0; 191*41480Smckusick hd->scsi_tch = 0; 192*41480Smckusick hd->scsi_tcm = 0; 193*41480Smckusick hd->scsi_tcl = 0; 194*41480Smckusick hd->scsi_ints = 0; 195*41480Smckusick 196*41480Smckusick if ((hd->scsi_id & ID_WORD_DMA) == 0) { 197*41480Smckusick hs->sc_flags |= SCSI_DMA32; 198*41480Smckusick printf("32 bit dma, "); 199*41480Smckusick } 200*41480Smckusick 201*41480Smckusick /* Determine Max Synchronous Transfer Rate */ 202*41480Smckusick if (scsi_nosync) 203*41480Smckusick i = 3; 204*41480Smckusick else 205*41480Smckusick i = SCSI_SYNC_XFER(hd->scsi_hconf); 206*41480Smckusick switch (i) { 207*41480Smckusick case 0: 208*41480Smckusick hs->sc_sync = TMOD_SYNC | 0x3e; /* 250 nsecs */ 209*41480Smckusick printf("250ns sync"); 210*41480Smckusick break; 211*41480Smckusick case 1: 212*41480Smckusick hs->sc_sync = TMOD_SYNC | 0x5e; /* 375 nsecs */ 213*41480Smckusick printf("375ns sync"); 214*41480Smckusick break; 215*41480Smckusick case 2: 216*41480Smckusick hs->sc_sync = TMOD_SYNC | 0x7d; /* 500 nsecs */ 217*41480Smckusick printf("500ns sync"); 218*41480Smckusick break; 219*41480Smckusick case 3: 220*41480Smckusick hs->sc_sync = 0; 221*41480Smckusick printf("async"); 222*41480Smckusick break; 223*41480Smckusick } 224*41480Smckusick 225*41480Smckusick /* 226*41480Smckusick * Configure the FUJI chip with its SCSI address, all 227*41480Smckusick * interrupts enabled & appropriate parity. 228*41480Smckusick */ 229*41480Smckusick i = (~hd->scsi_hconf) & 0x7; 230*41480Smckusick hs->sc_scsi_addr = 1 << i; 231*41480Smckusick hd->scsi_bdid = i; 232*41480Smckusick if (hd->scsi_hconf & HCONF_PARITY) 233*41480Smckusick hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB | 234*41480Smckusick SCTL_SEL_ENAB | SCTL_RESEL_ENAB | 235*41480Smckusick SCTL_INTR_ENAB | SCTL_PARITY_ENAB; 236*41480Smckusick else { 237*41480Smckusick hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB | 238*41480Smckusick SCTL_SEL_ENAB | SCTL_RESEL_ENAB | 239*41480Smckusick SCTL_INTR_ENAB; 240*41480Smckusick printf(", no parity"); 241*41480Smckusick } 242*41480Smckusick hd->scsi_sctl &=~ SCTL_DISABLE; 243*41480Smckusick 244*41480Smckusick printf(", scsi id %d\n", i); 245*41480Smckusick hs->sc_flags |= SCSI_ALIVE; 246*41480Smckusick } 247*41480Smckusick 248*41480Smckusick static void 249*41480Smckusick scsierror(hs, hd, ints) 250*41480Smckusick register struct scsi_softc *hs; 251*41480Smckusick volatile register struct scsidevice *hd; 252*41480Smckusick u_char ints; 253*41480Smckusick { 254*41480Smckusick int unit = hs->sc_hc->hp_unit; 255*41480Smckusick char *sep = ""; 256*41480Smckusick 257*41480Smckusick printf("scsi%d: ", unit); 258*41480Smckusick if (ints & INTS_RST) { 259*41480Smckusick DELAY(100); 260*41480Smckusick if (hd->scsi_hconf & HCONF_SD) 261*41480Smckusick printf("spurious RST interrupt"); 262*41480Smckusick else 263*41480Smckusick printf("hardware error - check fuse"); 264*41480Smckusick sep = ", "; 265*41480Smckusick } 266*41480Smckusick if ((ints & INTS_HARD_ERR) || hd->scsi_serr) { 267*41480Smckusick if (hd->scsi_serr & SERR_SCSI_PAR) { 268*41480Smckusick printf("%sparity err", sep); 269*41480Smckusick sep = ", "; 270*41480Smckusick } 271*41480Smckusick if (hd->scsi_serr & SERR_SPC_PAR) { 272*41480Smckusick printf("%sSPC parity err", sep); 273*41480Smckusick sep = ", "; 274*41480Smckusick } 275*41480Smckusick if (hd->scsi_serr & SERR_TC_PAR) { 276*41480Smckusick printf("%sTC parity err", sep); 277*41480Smckusick sep = ", "; 278*41480Smckusick } 279*41480Smckusick if (hd->scsi_serr & SERR_PHASE_ERR) { 280*41480Smckusick printf("%sphase err", sep); 281*41480Smckusick sep = ", "; 282*41480Smckusick } 283*41480Smckusick if (hd->scsi_serr & SERR_SHORT_XFR) { 284*41480Smckusick printf("%ssync short transfer err", sep); 285*41480Smckusick sep = ", "; 286*41480Smckusick } 287*41480Smckusick if (hd->scsi_serr & SERR_OFFSET) { 288*41480Smckusick printf("%ssync offset error", sep); 289*41480Smckusick sep = ", "; 290*41480Smckusick } 291*41480Smckusick } 292*41480Smckusick if (ints & INTS_TIMEOUT) 293*41480Smckusick printf("%sSPC select timeout error", sep); 294*41480Smckusick if (ints & INTS_SRV_REQ) 295*41480Smckusick printf("%sspurious SRV_REQ interrupt", sep); 296*41480Smckusick if (ints & INTS_CMD_DONE) 297*41480Smckusick printf("%sspurious CMD_DONE interrupt", sep); 298*41480Smckusick if (ints & INTS_DISCON) 299*41480Smckusick printf("%sspurious disconnect interrupt", sep); 300*41480Smckusick if (ints & INTS_RESEL) 301*41480Smckusick printf("%sspurious reselect interrupt", sep); 302*41480Smckusick if (ints & INTS_SEL) 303*41480Smckusick printf("%sspurious select interrupt", sep); 304*41480Smckusick printf("\n"); 305*41480Smckusick } 306*41480Smckusick 307*41480Smckusick static int 308*41480Smckusick issue_select(hd, target, our_addr) 309*41480Smckusick volatile register struct scsidevice *hd; 310*41480Smckusick u_char target, our_addr; 311*41480Smckusick { 312*41480Smckusick if (hd->scsi_ssts & (SSTS_INITIATOR|SSTS_TARGET|SSTS_BUSY)) 313*41480Smckusick return (1); 314*41480Smckusick 315*41480Smckusick if (hd->scsi_ints & INTS_DISCON) 316*41480Smckusick hd->scsi_ints = INTS_DISCON; 317*41480Smckusick 318*41480Smckusick hd->scsi_pctl = 0; 319*41480Smckusick hd->scsi_temp = (1 << target) | our_addr; 320*41480Smckusick /* select timeout is hardcoded to 2ms */ 321*41480Smckusick hd->scsi_tch = 0; 322*41480Smckusick hd->scsi_tcm = 32; 323*41480Smckusick hd->scsi_tcl = 4; 324*41480Smckusick 325*41480Smckusick hd->scsi_scmd = SCMD_SELECT; 326*41480Smckusick return (0); 327*41480Smckusick } 328*41480Smckusick 329*41480Smckusick static int 330*41480Smckusick wait_for_select(hd) 331*41480Smckusick volatile register struct scsidevice *hd; 332*41480Smckusick { 333*41480Smckusick u_char ints; 334*41480Smckusick 335*41480Smckusick while ((ints = hd->scsi_ints) == 0) 336*41480Smckusick DELAY(1); 337*41480Smckusick hd->scsi_ints = ints; 338*41480Smckusick return (!(hd->scsi_ssts & SSTS_INITIATOR)); 339*41480Smckusick } 340*41480Smckusick 341*41480Smckusick static int 342*41480Smckusick ixfer_start(hd, len, phase, wait) 343*41480Smckusick volatile register struct scsidevice *hd; 344*41480Smckusick int len; 345*41480Smckusick u_char phase; 346*41480Smckusick register int wait; 347*41480Smckusick { 348*41480Smckusick 349*41480Smckusick hd->scsi_tch = len >> 16; 350*41480Smckusick hd->scsi_tcm = len >> 8; 351*41480Smckusick hd->scsi_tcl = len; 352*41480Smckusick hd->scsi_pctl = phase; 353*41480Smckusick hd->scsi_tmod = 0; /*XXX*/ 354*41480Smckusick hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR; 355*41480Smckusick 356*41480Smckusick /* wait for xfer to start or svc_req interrupt */ 357*41480Smckusick while ((hd->scsi_ssts & SSTS_BUSY) == 0) { 358*41480Smckusick if (hd->scsi_ints || --wait < 0) { 359*41480Smckusick #ifdef DEBUG 360*41480Smckusick if (scsi_debug) 361*41480Smckusick printf("ixfer_start fail: i%x, w%d\n", 362*41480Smckusick hd->scsi_ints, wait); 363*41480Smckusick #endif 364*41480Smckusick HIST(ixstart_wait, wait) 365*41480Smckusick return (0); 366*41480Smckusick } 367*41480Smckusick DELAY(1); 368*41480Smckusick } 369*41480Smckusick HIST(ixstart_wait, wait) 370*41480Smckusick return (1); 371*41480Smckusick } 372*41480Smckusick 373*41480Smckusick static int 374*41480Smckusick ixfer_out(hd, len, buf) 375*41480Smckusick volatile register struct scsidevice *hd; 376*41480Smckusick int len; 377*41480Smckusick register u_char *buf; 378*41480Smckusick { 379*41480Smckusick register int wait = scsi_data_wait; 380*41480Smckusick 381*41480Smckusick for (; len > 0; --len) { 382*41480Smckusick while (hd->scsi_ssts & SSTS_DREG_FULL) { 383*41480Smckusick if (hd->scsi_ints || --wait < 0) { 384*41480Smckusick #ifdef DEBUG 385*41480Smckusick if (scsi_debug) 386*41480Smckusick printf("ixfer_out fail: l%d i%x w%d\n", 387*41480Smckusick len, hd->scsi_ints, wait); 388*41480Smckusick #endif 389*41480Smckusick HIST(ixout_wait, wait) 390*41480Smckusick return (len); 391*41480Smckusick } 392*41480Smckusick DELAY(1); 393*41480Smckusick } 394*41480Smckusick hd->scsi_dreg = *buf++; 395*41480Smckusick } 396*41480Smckusick HIST(ixout_wait, wait) 397*41480Smckusick return (0); 398*41480Smckusick } 399*41480Smckusick 400*41480Smckusick static void 401*41480Smckusick ixfer_in(hd, len, buf) 402*41480Smckusick volatile register struct scsidevice *hd; 403*41480Smckusick int len; 404*41480Smckusick register u_char *buf; 405*41480Smckusick { 406*41480Smckusick register int wait = scsi_data_wait; 407*41480Smckusick 408*41480Smckusick for (; len > 0; --len) { 409*41480Smckusick while (hd->scsi_ssts & SSTS_DREG_EMPTY) { 410*41480Smckusick if (hd->scsi_ints || --wait < 0) { 411*41480Smckusick while (! (hd->scsi_ssts & SSTS_DREG_EMPTY)) { 412*41480Smckusick *buf++ = hd->scsi_dreg; 413*41480Smckusick --len; 414*41480Smckusick } 415*41480Smckusick #ifdef DEBUG 416*41480Smckusick if (scsi_debug) 417*41480Smckusick printf("ixfer_in fail: l%d i%x w%d\n", 418*41480Smckusick len, hd->scsi_ints, wait); 419*41480Smckusick #endif 420*41480Smckusick HIST(ixin_wait, wait) 421*41480Smckusick return; 422*41480Smckusick } 423*41480Smckusick DELAY(1); 424*41480Smckusick } 425*41480Smckusick *buf++ = hd->scsi_dreg; 426*41480Smckusick } 427*41480Smckusick HIST(ixin_wait, wait) 428*41480Smckusick } 429*41480Smckusick 430*41480Smckusick static int 431*41480Smckusick mxfer_in(hd, len, buf, phase) 432*41480Smckusick volatile register struct scsidevice *hd; 433*41480Smckusick register int len; 434*41480Smckusick register u_char *buf; 435*41480Smckusick register u_char phase; 436*41480Smckusick { 437*41480Smckusick register int wait = scsi_cmd_wait; 438*41480Smckusick register int i; 439*41480Smckusick 440*41480Smckusick hd->scsi_tmod = 0; 441*41480Smckusick for (i = 0; i < len; ++i) { 442*41480Smckusick /* 443*41480Smckusick * wait for the request line (which says the target 444*41480Smckusick * wants to give us data). If the phase changes while 445*41480Smckusick * we're waiting, we're done. 446*41480Smckusick */ 447*41480Smckusick while ((hd->scsi_psns & PSNS_REQ) == 0) { 448*41480Smckusick if (--wait < 0) { 449*41480Smckusick HIST(mxin_wait, wait) 450*41480Smckusick return (-1); 451*41480Smckusick } 452*41480Smckusick if ((hd->scsi_psns & PHASE) != phase || 453*41480Smckusick (hd->scsi_ssts & SSTS_INITIATOR) == 0) 454*41480Smckusick goto out; 455*41480Smckusick 456*41480Smckusick DELAY(1); 457*41480Smckusick } 458*41480Smckusick /* 459*41480Smckusick * set ack (which says we're ready for the data, wait for 460*41480Smckusick * req to go away (target says data is available), grab the 461*41480Smckusick * data, then reset ack (say we've got the data). 462*41480Smckusick */ 463*41480Smckusick hd->scsi_pctl = phase; 464*41480Smckusick hd->scsi_scmd = SCMD_SET_ACK; 465*41480Smckusick while (hd->scsi_psns & PSNS_REQ) { 466*41480Smckusick if (--wait < 0) { 467*41480Smckusick HIST(mxin_wait, wait) 468*41480Smckusick return (-2); 469*41480Smckusick } 470*41480Smckusick DELAY(1); 471*41480Smckusick } 472*41480Smckusick *buf++ = hd->scsi_temp; 473*41480Smckusick hd->scsi_scmd = SCMD_RST_ACK; 474*41480Smckusick if (hd->scsi_psns & PSNS_ATN) 475*41480Smckusick hd->scsi_scmd = SCMD_RST_ATN; 476*41480Smckusick } 477*41480Smckusick out: 478*41480Smckusick HIST(mxin_wait, wait) 479*41480Smckusick return (i); 480*41480Smckusick } 481*41480Smckusick 482*41480Smckusick /* 483*41480Smckusick * SCSI 'immediate' command: issue a command to some SCSI device 484*41480Smckusick * and get back an 'immediate' response (i.e., do programmed xfer 485*41480Smckusick * to get the response data). 'cbuf' is a buffer containing a scsi 486*41480Smckusick * command of length clen bytes. 'buf' is a buffer of length 'len' 487*41480Smckusick * bytes for data. The transfer direction is determined by the device 488*41480Smckusick * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the 489*41480Smckusick * command must supply no data. 'xferphase' is the bus phase the 490*41480Smckusick * caller expects to happen after the command is issued. It should 491*41480Smckusick * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE. 492*41480Smckusick */ 493*41480Smckusick static int 494*41480Smckusick scsiicmd(hs, target, cbuf, clen, buf, len, xferphase) 495*41480Smckusick struct scsi_softc *hs; 496*41480Smckusick int target; 497*41480Smckusick u_char *cbuf; 498*41480Smckusick int clen; 499*41480Smckusick u_char *buf; 500*41480Smckusick int len; 501*41480Smckusick u_char xferphase; 502*41480Smckusick { 503*41480Smckusick volatile register struct scsidevice *hd = 504*41480Smckusick (struct scsidevice *)hs->sc_hc->hp_addr; 505*41480Smckusick u_char phase, ints; 506*41480Smckusick register int wait; 507*41480Smckusick 508*41480Smckusick /* select the SCSI bus (it's an error if bus isn't free) */ 509*41480Smckusick if (issue_select(hd, target, hs->sc_scsi_addr)) 510*41480Smckusick return (-1); 511*41480Smckusick if (wait_for_select(hd)) 512*41480Smckusick return (-1); 513*41480Smckusick /* 514*41480Smckusick * Wait for a phase change (or error) then let the device 515*41480Smckusick * sequence us through the various SCSI phases. 516*41480Smckusick */ 517*41480Smckusick hs->sc_stat[0] = 0xff; 518*41480Smckusick hs->sc_msg[0] = 0xff; 519*41480Smckusick phase = CMD_PHASE; 520*41480Smckusick while (1) { 521*41480Smckusick wait = scsi_cmd_wait; 522*41480Smckusick switch (phase) { 523*41480Smckusick 524*41480Smckusick case CMD_PHASE: 525*41480Smckusick if (ixfer_start(hd, clen, phase, wait)) 526*41480Smckusick if (ixfer_out(hd, clen, cbuf)) 527*41480Smckusick goto abort; 528*41480Smckusick phase = xferphase; 529*41480Smckusick break; 530*41480Smckusick 531*41480Smckusick case DATA_IN_PHASE: 532*41480Smckusick if (len <= 0) 533*41480Smckusick goto abort; 534*41480Smckusick wait = scsi_data_wait; 535*41480Smckusick if (ixfer_start(hd, len, phase, wait) || 536*41480Smckusick !(hd->scsi_ssts & SSTS_DREG_EMPTY)) 537*41480Smckusick ixfer_in(hd, len, buf); 538*41480Smckusick phase = STATUS_PHASE; 539*41480Smckusick break; 540*41480Smckusick 541*41480Smckusick case DATA_OUT_PHASE: 542*41480Smckusick if (len <= 0) 543*41480Smckusick goto abort; 544*41480Smckusick wait = scsi_data_wait; 545*41480Smckusick if (ixfer_start(hd, len, phase, wait)) { 546*41480Smckusick if (ixfer_out(hd, len, buf)) 547*41480Smckusick goto abort; 548*41480Smckusick } 549*41480Smckusick phase = STATUS_PHASE; 550*41480Smckusick break; 551*41480Smckusick 552*41480Smckusick case STATUS_PHASE: 553*41480Smckusick wait = scsi_data_wait; 554*41480Smckusick if (ixfer_start(hd, sizeof(hs->sc_stat), phase, wait) || 555*41480Smckusick !(hd->scsi_ssts & SSTS_DREG_EMPTY)) 556*41480Smckusick ixfer_in(hd, sizeof(hs->sc_stat), hs->sc_stat); 557*41480Smckusick phase = MESG_IN_PHASE; 558*41480Smckusick break; 559*41480Smckusick 560*41480Smckusick case MESG_IN_PHASE: 561*41480Smckusick if (ixfer_start(hd, sizeof(hs->sc_msg), phase, wait) || 562*41480Smckusick !(hd->scsi_ssts & SSTS_DREG_EMPTY)) { 563*41480Smckusick ixfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg); 564*41480Smckusick hd->scsi_scmd = SCMD_RST_ACK; 565*41480Smckusick } 566*41480Smckusick phase = BUS_FREE_PHASE; 567*41480Smckusick break; 568*41480Smckusick 569*41480Smckusick case BUS_FREE_PHASE: 570*41480Smckusick goto out; 571*41480Smckusick 572*41480Smckusick default: 573*41480Smckusick printf("scsi%d: unexpected phase %d in icmd from %d\n", 574*41480Smckusick hs->sc_hc->hp_unit, phase, target); 575*41480Smckusick goto abort; 576*41480Smckusick } 577*41480Smckusick /* wait for last command to complete */ 578*41480Smckusick while ((ints = hd->scsi_ints) == 0) { 579*41480Smckusick if (--wait < 0) { 580*41480Smckusick HIST(cxin_wait, wait) 581*41480Smckusick goto abort; 582*41480Smckusick } 583*41480Smckusick DELAY(1); 584*41480Smckusick } 585*41480Smckusick HIST(cxin_wait, wait) 586*41480Smckusick hd->scsi_ints = ints; 587*41480Smckusick if (ints & INTS_SRV_REQ) 588*41480Smckusick phase = hd->scsi_psns & PHASE; 589*41480Smckusick else if (ints & INTS_DISCON) 590*41480Smckusick goto out; 591*41480Smckusick else if ((ints & INTS_CMD_DONE) == 0) { 592*41480Smckusick scsierror(hs, hd, ints); 593*41480Smckusick goto abort; 594*41480Smckusick } 595*41480Smckusick } 596*41480Smckusick abort: 597*41480Smckusick scsiabort(hs, hd, "icmd"); 598*41480Smckusick out: 599*41480Smckusick return (hs->sc_stat[0]); 600*41480Smckusick } 601*41480Smckusick 602*41480Smckusick /* 603*41480Smckusick * Finish SCSI xfer command: After the completion interrupt from 604*41480Smckusick * a read/write operation, sequence through the final phases in 605*41480Smckusick * programmed i/o. This routine is a lot like scsiicmd except we 606*41480Smckusick * skip (and don't allow) the select, cmd out and data in/out phases. 607*41480Smckusick */ 608*41480Smckusick static void 609*41480Smckusick finishxfer(hs, hd, target) 610*41480Smckusick struct scsi_softc *hs; 611*41480Smckusick volatile register struct scsidevice *hd; 612*41480Smckusick int target; 613*41480Smckusick { 614*41480Smckusick u_char phase, ints; 615*41480Smckusick 616*41480Smckusick /* 617*41480Smckusick * We specified padding xfer so we ended with either a phase 618*41480Smckusick * change interrupt (normal case) or an error interrupt (handled 619*41480Smckusick * elsewhere). Reset the board dma logic then try to get the 620*41480Smckusick * completion status & command done msg. The reset confuses 621*41480Smckusick * the SPC REQ/ACK logic so we have to do any status/msg input 622*41480Smckusick * operations via 'manual xfer'. 623*41480Smckusick */ 624*41480Smckusick if (hd->scsi_ssts & SSTS_BUSY) { 625*41480Smckusick int wait = scsi_cmd_wait; 626*41480Smckusick 627*41480Smckusick /* wait for dma operation to finish */ 628*41480Smckusick while (hd->scsi_ssts & SSTS_BUSY) { 629*41480Smckusick if (--wait < 0) { 630*41480Smckusick #ifdef DEBUG 631*41480Smckusick if (scsi_debug) 632*41480Smckusick printf("finishxfer fail: ssts %x\n", 633*41480Smckusick hd->scsi_ssts); 634*41480Smckusick #endif 635*41480Smckusick HIST(fxfr_wait, wait) 636*41480Smckusick goto abort; 637*41480Smckusick } 638*41480Smckusick } 639*41480Smckusick HIST(fxfr_wait, wait) 640*41480Smckusick } 641*41480Smckusick hd->scsi_scmd |= SCMD_PROG_XFR; 642*41480Smckusick hd->scsi_sctl |= SCTL_CTRLRST; 643*41480Smckusick DELAY(1); 644*41480Smckusick hd->scsi_sctl &=~ SCTL_CTRLRST; 645*41480Smckusick hd->scsi_hconf = 0; 646*41480Smckusick hs->sc_stat[0] = 0xff; 647*41480Smckusick hs->sc_msg[0] = 0xff; 648*41480Smckusick hd->scsi_csr = 0; 649*41480Smckusick hd->scsi_ints = ints = hd->scsi_ints; 650*41480Smckusick while (1) { 651*41480Smckusick phase = hd->scsi_psns & PHASE; 652*41480Smckusick switch (phase) { 653*41480Smckusick 654*41480Smckusick case STATUS_PHASE: 655*41480Smckusick if (mxfer_in(hd, sizeof(hs->sc_stat), hs->sc_stat, 656*41480Smckusick phase) <= 0) 657*41480Smckusick goto abort; 658*41480Smckusick break; 659*41480Smckusick 660*41480Smckusick case MESG_IN_PHASE: 661*41480Smckusick if (mxfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg, 662*41480Smckusick phase) < 0) 663*41480Smckusick goto abort; 664*41480Smckusick break; 665*41480Smckusick 666*41480Smckusick case BUS_FREE_PHASE: 667*41480Smckusick return; 668*41480Smckusick 669*41480Smckusick default: 670*41480Smckusick printf("scsi%d: unexpected phase %d in finishxfer from %d\n", 671*41480Smckusick hs->sc_hc->hp_unit, phase, target); 672*41480Smckusick goto abort; 673*41480Smckusick } 674*41480Smckusick if (ints = hd->scsi_ints) { 675*41480Smckusick hd->scsi_ints = ints; 676*41480Smckusick if (ints & INTS_DISCON) 677*41480Smckusick return; 678*41480Smckusick else if (ints & ~(INTS_SRV_REQ|INTS_CMD_DONE)) { 679*41480Smckusick scsierror(hs, hd, ints); 680*41480Smckusick break; 681*41480Smckusick } 682*41480Smckusick } 683*41480Smckusick if ((hd->scsi_ssts & SSTS_INITIATOR) == 0) 684*41480Smckusick return; 685*41480Smckusick } 686*41480Smckusick abort: 687*41480Smckusick scsiabort(hs, hd, "finishxfer"); 688*41480Smckusick hs->sc_stat[0] = 0xfe; 689*41480Smckusick } 690*41480Smckusick 691*41480Smckusick int 692*41480Smckusick scsi_test_unit_rdy(ctlr, slave, unit) 693*41480Smckusick int ctlr, slave, unit; 694*41480Smckusick { 695*41480Smckusick register struct scsi_softc *hs = &scsi_softc[ctlr]; 696*41480Smckusick static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY }; 697*41480Smckusick 698*41480Smckusick cdb.lun = unit; 699*41480Smckusick return (scsiicmd(hs, slave, &cdb, sizeof(cdb), (u_char *)0, 0, 700*41480Smckusick STATUS_PHASE)); 701*41480Smckusick } 702*41480Smckusick 703*41480Smckusick int 704*41480Smckusick scsi_request_sense(ctlr, slave, unit, buf, len) 705*41480Smckusick int ctlr, slave, unit; 706*41480Smckusick u_char *buf; 707*41480Smckusick unsigned len; 708*41480Smckusick { 709*41480Smckusick register struct scsi_softc *hs = &scsi_softc[ctlr]; 710*41480Smckusick static struct scsi_cdb6 cdb = { CMD_REQUEST_SENSE }; 711*41480Smckusick 712*41480Smckusick cdb.lun = unit; 713*41480Smckusick cdb.len = len; 714*41480Smckusick return (scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE)); 715*41480Smckusick } 716*41480Smckusick 717*41480Smckusick int 718*41480Smckusick scsi_immed_command(ctlr, slave, unit, cdb, buf, len, rd) 719*41480Smckusick int ctlr, slave, unit; 720*41480Smckusick struct scsi_fmt_cdb *cdb; 721*41480Smckusick u_char *buf; 722*41480Smckusick unsigned len; 723*41480Smckusick { 724*41480Smckusick register struct scsi_softc *hs = &scsi_softc[ctlr]; 725*41480Smckusick 726*41480Smckusick cdb->cdb[1] |= unit << 5; 727*41480Smckusick return (scsiicmd(hs, slave, cdb->cdb, cdb->len, buf, len, 728*41480Smckusick rd != 0? DATA_IN_PHASE : DATA_OUT_PHASE)); 729*41480Smckusick } 730*41480Smckusick 731*41480Smckusick /* 732*41480Smckusick * The following routines are test-and-transfer i/o versions of read/write 733*41480Smckusick * for things like reading disk labels and writing core dumps. The 734*41480Smckusick * routine scsigo should be used for normal data transfers, NOT these 735*41480Smckusick * routines. 736*41480Smckusick */ 737*41480Smckusick int 738*41480Smckusick scsi_tt_read(ctlr, slave, unit, buf, len, blk, bshift) 739*41480Smckusick int ctlr, slave, unit; 740*41480Smckusick u_char *buf; 741*41480Smckusick u_int len; 742*41480Smckusick daddr_t blk; 743*41480Smckusick int bshift; 744*41480Smckusick { 745*41480Smckusick register struct scsi_softc *hs = &scsi_softc[ctlr]; 746*41480Smckusick struct scsi_cdb10 cdb; 747*41480Smckusick int stat; 748*41480Smckusick int old_wait = scsi_data_wait; 749*41480Smckusick 750*41480Smckusick scsi_data_wait = 300000; 751*41480Smckusick bzero(&cdb, sizeof(cdb)); 752*41480Smckusick cdb.cmd = CMD_READ_EXT; 753*41480Smckusick cdb.lun = unit; 754*41480Smckusick blk >>= bshift; 755*41480Smckusick cdb.lbah = blk >> 24; 756*41480Smckusick cdb.lbahm = blk >> 16; 757*41480Smckusick cdb.lbalm = blk >> 8; 758*41480Smckusick cdb.lbal = blk; 759*41480Smckusick cdb.lenh = len >> (8 + DEV_BSHIFT + bshift); 760*41480Smckusick cdb.lenl = len >> (DEV_BSHIFT + bshift); 761*41480Smckusick stat = scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE); 762*41480Smckusick scsi_data_wait = old_wait; 763*41480Smckusick return (stat); 764*41480Smckusick } 765*41480Smckusick 766*41480Smckusick int 767*41480Smckusick scsi_tt_write(ctlr, slave, unit, buf, len, blk, bshift) 768*41480Smckusick int ctlr, slave, unit; 769*41480Smckusick u_char *buf; 770*41480Smckusick u_int len; 771*41480Smckusick daddr_t blk; 772*41480Smckusick int bshift; 773*41480Smckusick { 774*41480Smckusick register struct scsi_softc *hs = &scsi_softc[ctlr]; 775*41480Smckusick struct scsi_cdb10 cdb; 776*41480Smckusick int stat; 777*41480Smckusick int old_wait = scsi_data_wait; 778*41480Smckusick 779*41480Smckusick scsi_data_wait = 300000; 780*41480Smckusick 781*41480Smckusick bzero(&cdb, sizeof(cdb)); 782*41480Smckusick cdb.cmd = CMD_WRITE_EXT; 783*41480Smckusick cdb.lun = unit; 784*41480Smckusick blk >>= bshift; 785*41480Smckusick cdb.lbah = blk >> 24; 786*41480Smckusick cdb.lbahm = blk >> 16; 787*41480Smckusick cdb.lbalm = blk >> 8; 788*41480Smckusick cdb.lbal = blk; 789*41480Smckusick cdb.lenh = len >> (8 + DEV_BSHIFT + bshift); 790*41480Smckusick cdb.lenl = len >> (DEV_BSHIFT + bshift); 791*41480Smckusick stat = scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_OUT_PHASE); 792*41480Smckusick scsi_data_wait = old_wait; 793*41480Smckusick return (stat); 794*41480Smckusick } 795*41480Smckusick 796*41480Smckusick 797*41480Smckusick int 798*41480Smckusick scsireq(dq) 799*41480Smckusick register struct devqueue *dq; 800*41480Smckusick { 801*41480Smckusick register struct devqueue *hq; 802*41480Smckusick 803*41480Smckusick hq = &scsi_softc[dq->dq_ctlr].sc_sq; 804*41480Smckusick insque(dq, hq->dq_back); 805*41480Smckusick if (dq->dq_back == hq) 806*41480Smckusick return(1); 807*41480Smckusick return(0); 808*41480Smckusick } 809*41480Smckusick 810*41480Smckusick int 811*41480Smckusick scsiustart(unit) 812*41480Smckusick int unit; 813*41480Smckusick { 814*41480Smckusick register struct scsi_softc *hs = &scsi_softc[unit]; 815*41480Smckusick 816*41480Smckusick hs->sc_dq.dq_ctlr = DMA0 | DMA1; 817*41480Smckusick if (dmareq(&hs->sc_dq)) 818*41480Smckusick return(1); 819*41480Smckusick return(0); 820*41480Smckusick } 821*41480Smckusick 822*41480Smckusick void 823*41480Smckusick scsistart(unit) 824*41480Smckusick int unit; 825*41480Smckusick { 826*41480Smckusick register struct devqueue *dq; 827*41480Smckusick 828*41480Smckusick dq = scsi_softc[unit].sc_sq.dq_forw; 829*41480Smckusick (dq->dq_driver->d_go)(dq->dq_unit); 830*41480Smckusick } 831*41480Smckusick 832*41480Smckusick int 833*41480Smckusick scsigo(ctlr, slave, unit, bp, cdb, pad) 834*41480Smckusick int ctlr, slave, unit; 835*41480Smckusick struct buf *bp; 836*41480Smckusick struct scsi_fmt_cdb *cdb; 837*41480Smckusick int pad; 838*41480Smckusick { 839*41480Smckusick register struct scsi_softc *hs = &scsi_softc[ctlr]; 840*41480Smckusick volatile register struct scsidevice *hd = 841*41480Smckusick (struct scsidevice *)hs->sc_hc->hp_addr; 842*41480Smckusick int i, dmaflags; 843*41480Smckusick u_char phase, ints, cmd; 844*41480Smckusick 845*41480Smckusick cdb->cdb[1] |= unit << 5; 846*41480Smckusick 847*41480Smckusick /* select the SCSI bus (it's an error if bus isn't free) */ 848*41480Smckusick if (issue_select(hd, slave, hs->sc_scsi_addr) || wait_for_select(hd)) { 849*41480Smckusick dmafree(&hs->sc_dq); 850*41480Smckusick return (1); 851*41480Smckusick } 852*41480Smckusick /* 853*41480Smckusick * Wait for a phase change (or error) then let the device 854*41480Smckusick * sequence us through command phase (we may have to take 855*41480Smckusick * a msg in/out before doing the command). If the disk has 856*41480Smckusick * to do a seek, it may be a long time until we get a change 857*41480Smckusick * to data phase so, in the absense of an explicit phase 858*41480Smckusick * change, we assume data phase will be coming up and tell 859*41480Smckusick * the SPC to start a transfer whenever it does. We'll get 860*41480Smckusick * a service required interrupt later if this assumption is 861*41480Smckusick * wrong. Otherwise we'll get a service required int when 862*41480Smckusick * the transfer changes to status phase. 863*41480Smckusick */ 864*41480Smckusick phase = CMD_PHASE; 865*41480Smckusick while (1) { 866*41480Smckusick register int wait = scsi_cmd_wait; 867*41480Smckusick 868*41480Smckusick switch (phase) { 869*41480Smckusick 870*41480Smckusick case CMD_PHASE: 871*41480Smckusick if (ixfer_start(hd, cdb->len, phase, wait)) 872*41480Smckusick if (ixfer_out(hd, cdb->len, cdb->cdb)) 873*41480Smckusick goto abort; 874*41480Smckusick break; 875*41480Smckusick 876*41480Smckusick case MESG_IN_PHASE: 877*41480Smckusick if (ixfer_start(hd, sizeof(hs->sc_msg), phase, wait)|| 878*41480Smckusick !(hd->scsi_ssts & SSTS_DREG_EMPTY)) { 879*41480Smckusick ixfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg); 880*41480Smckusick hd->scsi_scmd = SCMD_RST_ACK; 881*41480Smckusick } 882*41480Smckusick phase = BUS_FREE_PHASE; 883*41480Smckusick break; 884*41480Smckusick 885*41480Smckusick case DATA_IN_PHASE: 886*41480Smckusick case DATA_OUT_PHASE: 887*41480Smckusick goto out; 888*41480Smckusick 889*41480Smckusick default: 890*41480Smckusick printf("scsi%d: unexpected phase %d in go from %d\n", 891*41480Smckusick hs->sc_hc->hp_unit, phase, slave); 892*41480Smckusick goto abort; 893*41480Smckusick } 894*41480Smckusick while ((ints = hd->scsi_ints) == 0) { 895*41480Smckusick if (--wait < 0) { 896*41480Smckusick HIST(sgo_wait, wait) 897*41480Smckusick goto abort; 898*41480Smckusick } 899*41480Smckusick DELAY(1); 900*41480Smckusick } 901*41480Smckusick HIST(sgo_wait, wait) 902*41480Smckusick hd->scsi_ints = ints; 903*41480Smckusick if (ints & INTS_SRV_REQ) 904*41480Smckusick phase = hd->scsi_psns & PHASE; 905*41480Smckusick else if (ints & INTS_CMD_DONE) 906*41480Smckusick goto out; 907*41480Smckusick else { 908*41480Smckusick scsierror(hs, hd, ints); 909*41480Smckusick goto abort; 910*41480Smckusick } 911*41480Smckusick } 912*41480Smckusick out: 913*41480Smckusick /* 914*41480Smckusick * Reset the card dma logic, setup the dma channel then 915*41480Smckusick * get the dio part of the card set for a dma xfer. 916*41480Smckusick */ 917*41480Smckusick hd->scsi_hconf = 0; 918*41480Smckusick cmd = CSR_IE | (CSR_DE0 << hs->sc_dq.dq_ctlr); 919*41480Smckusick dmaflags = DMAGO_NOINT; 920*41480Smckusick if (bp->b_flags & B_READ) 921*41480Smckusick dmaflags |= DMAGO_READ; 922*41480Smckusick if ((hs->sc_flags & SCSI_DMA32) && 923*41480Smckusick ((int)bp->b_un.b_addr & 3) == 0 && (bp->b_bcount & 3) == 0) { 924*41480Smckusick cmd |= CSR_DMA32; 925*41480Smckusick dmaflags |= DMAGO_LWORD; 926*41480Smckusick } else 927*41480Smckusick dmaflags |= DMAGO_WORD; 928*41480Smckusick dmago(hs->sc_dq.dq_ctlr, bp->b_un.b_addr, bp->b_bcount, dmaflags); 929*41480Smckusick 930*41480Smckusick if (bp->b_flags & B_READ) { 931*41480Smckusick cmd |= CSR_DMAIN; 932*41480Smckusick phase = DATA_IN_PHASE; 933*41480Smckusick } else 934*41480Smckusick phase = DATA_OUT_PHASE; 935*41480Smckusick hd->scsi_csr = cmd; 936*41480Smckusick /* 937*41480Smckusick * Setup the SPC for the transfer. We don't want to take 938*41480Smckusick * first a command complete then a service required interrupt 939*41480Smckusick * at the end of the transfer so we try to disable the cmd 940*41480Smckusick * complete by setting the transfer counter to more bytes 941*41480Smckusick * than we expect. (XXX - This strategy may have to be 942*41480Smckusick * modified to deal with devices that return variable length 943*41480Smckusick * blocks, e.g., some tape drives.) 944*41480Smckusick */ 945*41480Smckusick cmd = SCMD_XFR; 946*41480Smckusick i = (unsigned)bp->b_bcount; 947*41480Smckusick if (pad) { 948*41480Smckusick cmd |= SCMD_PAD; 949*41480Smckusick /* 950*41480Smckusick * XXX - If we don't do this, the last 2 or 4 bytes 951*41480Smckusick * (depending on word/lword DMA) of a read get trashed. 952*41480Smckusick * It looks like it is necessary for the DMA to complete 953*41480Smckusick * before the SPC goes into "pad mode"??? Note: if we 954*41480Smckusick * also do this on a write, the request never completes. 955*41480Smckusick */ 956*41480Smckusick if (bp->b_flags & B_READ) 957*41480Smckusick i += 2; 958*41480Smckusick #ifdef DEBUG 959*41480Smckusick hs->sc_flags |= SCSI_PAD; 960*41480Smckusick if (i & 1) 961*41480Smckusick printf("scsi%d: odd byte count: %d bytes @ %d\n", 962*41480Smckusick ctlr, i, bp->b_cylin); 963*41480Smckusick #endif 964*41480Smckusick } else 965*41480Smckusick i += 4; 966*41480Smckusick hd->scsi_tch = i >> 16; 967*41480Smckusick hd->scsi_tcm = i >> 8; 968*41480Smckusick hd->scsi_tcl = i; 969*41480Smckusick hd->scsi_pctl = phase; 970*41480Smckusick hd->scsi_tmod = 0; 971*41480Smckusick hd->scsi_scmd = cmd; 972*41480Smckusick hs->sc_flags |= SCSI_IO; 973*41480Smckusick return (0); 974*41480Smckusick abort: 975*41480Smckusick scsiabort(hs, hd, "go"); 976*41480Smckusick dmafree(&hs->sc_dq); 977*41480Smckusick return (1); 978*41480Smckusick } 979*41480Smckusick 980*41480Smckusick void 981*41480Smckusick scsidone(unit) 982*41480Smckusick register int unit; 983*41480Smckusick { 984*41480Smckusick volatile register struct scsidevice *hd = 985*41480Smckusick (struct scsidevice *)scsi_softc[unit].sc_hc->hp_addr; 986*41480Smckusick 987*41480Smckusick /* dma operation is done -- turn off card dma */ 988*41480Smckusick hd->scsi_csr &=~ (CSR_DE1|CSR_DE0); 989*41480Smckusick } 990*41480Smckusick 991*41480Smckusick int 992*41480Smckusick scsiintr(unit) 993*41480Smckusick register int unit; 994*41480Smckusick { 995*41480Smckusick register struct scsi_softc *hs = &scsi_softc[unit]; 996*41480Smckusick volatile register struct scsidevice *hd = 997*41480Smckusick (struct scsidevice *)hs->sc_hc->hp_addr; 998*41480Smckusick register u_char ints; 999*41480Smckusick register struct devqueue *dq; 1000*41480Smckusick 1001*41480Smckusick if ((hd->scsi_csr & (CSR_IE|CSR_IR)) != (CSR_IE|CSR_IR)) 1002*41480Smckusick return (0); 1003*41480Smckusick 1004*41480Smckusick ints = hd->scsi_ints; 1005*41480Smckusick if ((ints & INTS_SRV_REQ) && (hs->sc_flags & SCSI_IO)) { 1006*41480Smckusick /* 1007*41480Smckusick * this should be the normal i/o completion case. 1008*41480Smckusick * get the status & cmd complete msg then let the 1009*41480Smckusick * device driver look at what happened. 1010*41480Smckusick */ 1011*41480Smckusick #ifdef DEBUG 1012*41480Smckusick int len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | 1013*41480Smckusick hd->scsi_tcl; 1014*41480Smckusick if (!(hs->sc_flags & SCSI_PAD)) 1015*41480Smckusick len -= 4; 1016*41480Smckusick if (len) 1017*41480Smckusick printf("scsi%d: transfer length error %d\n", unit, len); 1018*41480Smckusick hs->sc_flags &=~ SCSI_PAD; 1019*41480Smckusick #endif 1020*41480Smckusick dq = hs->sc_sq.dq_forw; 1021*41480Smckusick finishxfer(hs, hd, dq->dq_unit); 1022*41480Smckusick hs->sc_flags &=~ SCSI_IO; 1023*41480Smckusick dmafree(&hs->sc_dq); 1024*41480Smckusick (dq->dq_driver->d_intr)(dq->dq_unit, hs->sc_stat[0]); 1025*41480Smckusick } else { 1026*41480Smckusick /* Something unexpected happened -- deal with it. */ 1027*41480Smckusick hd->scsi_ints = ints; 1028*41480Smckusick hd->scsi_csr = 0; 1029*41480Smckusick scsierror(hs, hd, ints); 1030*41480Smckusick scsiabort(hs, hd, "intr"); 1031*41480Smckusick if (hs->sc_flags & SCSI_IO) { 1032*41480Smckusick hs->sc_flags &=~ SCSI_IO; 1033*41480Smckusick dmafree(&hs->sc_dq); 1034*41480Smckusick dq = hs->sc_sq.dq_forw; 1035*41480Smckusick (dq->dq_driver->d_intr)(dq->dq_unit, -1); 1036*41480Smckusick } 1037*41480Smckusick } 1038*41480Smckusick return(1); 1039*41480Smckusick } 1040*41480Smckusick 1041*41480Smckusick void 1042*41480Smckusick scsifree(dq) 1043*41480Smckusick register struct devqueue *dq; 1044*41480Smckusick { 1045*41480Smckusick register struct devqueue *hq; 1046*41480Smckusick 1047*41480Smckusick hq = &scsi_softc[dq->dq_ctlr].sc_sq; 1048*41480Smckusick remque(dq); 1049*41480Smckusick if ((dq = hq->dq_forw) != hq) 1050*41480Smckusick (dq->dq_driver->d_start)(dq->dq_unit); 1051*41480Smckusick } 1052*41480Smckusick #endif 1053