|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1990 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Van Jacobson of Lawrence Berkeley Laboratory. ! 7: * ! 8: * Redistribution and use in source and binary forms, with or without ! 9: * modification, are permitted provided that the following conditions ! 10: * are met: ! 11: * 1. Redistributions of source code must retain the above copyright ! 12: * notice, this list of conditions and the following disclaimer. ! 13: * 2. Redistributions in binary form must reproduce the above copyright ! 14: * notice, this list of conditions and the following disclaimer in the ! 15: * documentation and/or other materials provided with the distribution. ! 16: * 3. All advertising materials mentioning features or use of this software ! 17: * must display the following acknowledgement: ! 18: * This product includes software developed by the University of ! 19: * California, Berkeley and its contributors. ! 20: * 4. Neither the name of the University nor the names of its contributors ! 21: * may be used to endorse or promote products derived from this software ! 22: * without specific prior written permission. ! 23: * ! 24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 34: * SUCH DAMAGE. ! 35: * ! 36: * @(#)scsi.c 7.5 (Berkeley) 5/4/91 ! 37: */ ! 38: ! 39: /* ! 40: * AMIGA AMD 33C93 scsi adaptor driver ! 41: */ ! 42: #include "scsi.h" ! 43: #if NSCSI > 0 ! 44: ! 45: #ifndef lint ! 46: static char rcsid[] = "/b/source/CVS/src/sys/arch/amiga/dev/scsi.c,v 1.1.1.1 1993/07/05 19:19:44 mw Exp"; ! 47: #endif ! 48: ! 49: #include "sys/param.h" ! 50: #include "sys/systm.h" ! 51: #include "sys/buf.h" ! 52: #include "device.h" ! 53: ! 54: #include "scsivar.h" ! 55: #include "scsireg.h" ! 56: #include "dmavar.h" ! 57: #include "dmareg.h" ! 58: ! 59: #include "../amiga/custom.h" ! 60: ! 61: #include "machine/cpu.h" ! 62: ! 63: static int sbic_wait (volatile sbic_padded_regmap_t *regs, char until, int timeo, int line); ! 64: static void scsiabort (register struct scsi_softc *dev, register volatile sbic_padded_regmap_t *regs, char *where); ! 65: static void scsierror (register struct scsi_softc *dev, register volatile sbic_padded_regmap_t *regs, u_char csr); ! 66: static int issue_select (register volatile sbic_padded_regmap_t *regs, u_char target, u_char our_addr); ! 67: static int wait_for_select (register volatile sbic_padded_regmap_t *regs); ! 68: static int ixfer_start (register volatile sbic_padded_regmap_t *regs, int len, u_char phase, register int wait); ! 69: static int ixfer_out (register volatile sbic_padded_regmap_t *regs, int len, register u_char *buf, int phase); ! 70: static void ixfer_in (register volatile sbic_padded_regmap_t *regs, int len, register u_char *buf); ! 71: static int scsiicmd (struct scsi_softc *dev, int target, u_char *cbuf, int clen, u_char *buf, int len, u_char xferphase); ! 72: static void finishxfer (struct scsi_softc *dev, register volatile sbic_padded_regmap_t *regs, int target); ! 73: ! 74: ! 75: ! 76: /* ! 77: * SCSI delays ! 78: * In u-seconds, primarily for state changes on the SPC. ! 79: */ ! 80: #define SCSI_CMD_WAIT 1000 /* wait per step of 'immediate' cmds */ ! 81: #define SCSI_DATA_WAIT 1000 /* wait per data in/out step */ ! 82: #define SCSI_INIT_WAIT 50000 /* wait per step (both) during init */ ! 83: ! 84: extern void _insque(); ! 85: extern void _remque(); ! 86: ! 87: int scsiinit(), scsigo(), scsiintr(), scsixfer(); ! 88: void scsistart(), scsidone(), scsifree(), scsireset(); ! 89: struct driver scsidriver = { ! 90: scsiinit, "scsi", (int (*)())scsistart, scsigo, scsiintr, ! 91: (int (*)())scsidone, ! 92: }; ! 93: ! 94: struct scsi_softc scsi_softc; ! 95: ! 96: int scsi_cmd_wait = SCSI_CMD_WAIT; ! 97: int scsi_data_wait = SCSI_DATA_WAIT; ! 98: int scsi_init_wait = SCSI_INIT_WAIT; ! 99: ! 100: int scsi_nosync = 1; /* inhibit sync xfers if 1 */ ! 101: ! 102: /* these devices want to be reset before first data transfer access. ! 103: This is site specific, you'll know when your drive locks up because it's ! 104: still using AmigaDOS sync values... */ ! 105: static u_char reset_devices[] = { 1, 1, 0, 0, 0, 1, 1, 0 }; ! 106: ! 107: ! 108: #ifdef DEBUG ! 109: int scsi_debug = 0; ! 110: #define WAITHIST ! 111: #define QUASEL ! 112: #endif ! 113: ! 114: #ifdef QUASEL ! 115: #define QPRINTF(a) if (scsi_debug) printf a ! 116: #else ! 117: #define QPRINTF ! 118: #endif ! 119: ! 120: #ifdef WAITHIST ! 121: #define MAXWAIT 1022 ! 122: u_int ixstart_wait[MAXWAIT+2]; ! 123: u_int ixin_wait[MAXWAIT+2]; ! 124: u_int ixout_wait[MAXWAIT+2]; ! 125: u_int mxin_wait[MAXWAIT+2]; ! 126: u_int mxin2_wait[MAXWAIT+2]; ! 127: u_int cxin_wait[MAXWAIT+2]; ! 128: u_int fxfr_wait[MAXWAIT+2]; ! 129: u_int sgo_wait[MAXWAIT+2]; ! 130: #define HIST(h,w) (++h[((w)>MAXWAIT? MAXWAIT : ((w) < 0 ? -1 : (w))) + 1]); ! 131: #else ! 132: #define HIST(h,w) ! 133: #endif ! 134: ! 135: #define b_cylin b_resid ! 136: ! 137: static sbic_wait (regs, until, timeo, line) ! 138: volatile sbic_padded_regmap_t *regs; ! 139: char until; ! 140: int timeo; ! 141: int line; ! 142: { ! 143: register unsigned char val; ! 144: ! 145: if (! timeo) ! 146: timeo = 1000000; /* some large value.. */ ! 147: ! 148: GET_SBIC_asr (regs,val); ! 149: while ((val & until) == 0) ! 150: { ! 151: if (!timeo--) ! 152: { ! 153: int csr; ! 154: GET_SBIC_csr (regs, csr); ! 155: printf("sbic_wait TIMEO @%d with asr=x%x csr=x%x\n", line, val, csr); ! 156: break; ! 157: } ! 158: DELAY(1); ! 159: GET_SBIC_asr(regs,val); ! 160: } ! 161: return val; ! 162: } ! 163: ! 164: #define SBIC_WAIT(regs, until, timeo) sbic_wait (regs, until, timeo, __LINE__) ! 165: ! 166: ! 167: static void ! 168: scsiabort(dev, regs, where) ! 169: register struct scsi_softc *dev; ! 170: volatile register sbic_padded_regmap_t *regs; ! 171: char *where; ! 172: { ! 173: u_char csr, asr; ! 174: ! 175: GET_SBIC_csr (regs, csr); ! 176: GET_SBIC_asr (regs, asr); ! 177: ! 178: printf ("scsi: abort %s: csr = 0x%02x, asr = 0x%02x\n", where, csr, asr); ! 179: ! 180: if (dev->sc_flags & SCSI_SELECTED) ! 181: { ! 182: SET_SBIC_cmd (regs, SBIC_CMD_ABORT); ! 183: WAIT_CIP (regs); ! 184: ! 185: GET_SBIC_asr (regs, asr); ! 186: if (asr & (SBIC_ASR_BSY|SBIC_ASR_LCI)) ! 187: { ! 188: /* ok, get more drastic.. */ ! 189: ! 190: SET_SBIC_cmd (regs, SBIC_CMD_RESET); ! 191: DELAY(25); ! 192: SBIC_WAIT(regs, SBIC_ASR_INT, 0); ! 193: GET_SBIC_csr (regs, csr); /* clears interrupt also */ ! 194: ! 195: dev->sc_flags &= ~SCSI_SELECTED; ! 196: return; ! 197: } ! 198: ! 199: do ! 200: { ! 201: SBIC_WAIT (regs, SBIC_ASR_INT, 0); ! 202: GET_SBIC_csr (regs, csr); ! 203: } ! 204: while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1) ! 205: && (csr != SBIC_CSR_CMD_INVALID)); ! 206: ! 207: /* lets just hope it worked.. */ ! 208: dev->sc_flags &= ~SCSI_SELECTED; ! 209: } ! 210: } ! 211: ! 212: /* ! 213: * XXX Set/reset long delays. ! 214: * ! 215: * if delay == 0, reset default delays ! 216: * if delay < 0, set both delays to default long initialization values ! 217: * if delay > 0, set both delays to this value ! 218: * ! 219: * Used when a devices is expected to respond slowly (e.g. during ! 220: * initialization). ! 221: */ ! 222: void ! 223: scsi_delay(delay) ! 224: int delay; ! 225: { ! 226: static int saved_cmd_wait, saved_data_wait; ! 227: ! 228: if (delay) { ! 229: saved_cmd_wait = scsi_cmd_wait; ! 230: saved_data_wait = scsi_data_wait; ! 231: if (delay > 0) ! 232: scsi_cmd_wait = scsi_data_wait = delay; ! 233: else ! 234: scsi_cmd_wait = scsi_data_wait = scsi_init_wait; ! 235: } else { ! 236: scsi_cmd_wait = saved_cmd_wait; ! 237: scsi_data_wait = saved_data_wait; ! 238: } ! 239: } ! 240: ! 241: int ! 242: scsiinit(ac) ! 243: register struct amiga_ctlr *ac; ! 244: { ! 245: register struct scsi_softc *dev = &scsi_softc; ! 246: register sbic_padded_regmap_t *regs; ! 247: extern void *SCSI_address; ! 248: static int initialized = 0; ! 249: ! 250: if (initialized) ! 251: return 0; ! 252: ! 253: initialized = 1; ! 254: ! 255: SDMAC_setup (); ! 256: ac->amiga_addr = (caddr_t) regs = (sbic_padded_regmap_t *) SCSI_address; ! 257: ! 258: /* hardwired IPL */ ! 259: ac->amiga_ipl = 2; ! 260: dev->sc_ac = ac; ! 261: dev->sc_dq.dq_driver = &scsidriver; ! 262: dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq; ! 263: scsireset (); ! 264: ! 265: /* make sure IPL2 interrupts are delivered to the cpu when the sbic ! 266: generates some. Note that this does not yet enable sbic-interrupts, ! 267: this is handled in dma.c, which selectively enables interrupts only ! 268: while DMA requests are pending. ! 269: ! 270: Note that enabling PORTS interrupts also enables keyboard interrupts ! 271: as soon as the corresponding int-enable bit in CIA-A is set. */ ! 272: ! 273: custom.intreq = INTF_PORTS; ! 274: custom.intena = INTF_SETCLR | INTF_PORTS; ! 275: return(1); ! 276: } ! 277: ! 278: void ! 279: scsireset() ! 280: { ! 281: register struct scsi_softc *dev = &scsi_softc; ! 282: volatile register sbic_padded_regmap_t *regs = ! 283: (sbic_padded_regmap_t *)dev->sc_ac->amiga_addr; ! 284: u_int i, s; ! 285: u_char my_id, csr; ! 286: ! 287: if (dev->sc_flags & SCSI_ALIVE) ! 288: scsiabort(dev, regs, "reset"); ! 289: ! 290: printf("scsi: "); ! 291: ! 292: /* preserve our ID for now */ ! 293: GET_SBIC_myid (regs, my_id); ! 294: my_id &= SBIC_ID_MASK; ! 295: ! 296: if (SBIC_CLOCK_FREQUENCY < 110) ! 297: my_id |= SBIC_ID_FS_8_10; ! 298: else if (SBIC_CLOCK_FREQUENCY < 160) ! 299: my_id |= SBIC_ID_FS_12_15; ! 300: else if (SBIC_CLOCK_FREQUENCY < 210) ! 301: my_id |= SBIC_ID_FS_16_20; ! 302: ! 303: my_id |= SBIC_ID_EAF/* |SBIC_ID_EHP*/; ! 304: ! 305: SET_SBIC_myid (regs, my_id); ! 306: ! 307: /* ! 308: * Disable interrupts (in dmainit) then reset the chip ! 309: */ ! 310: SET_SBIC_cmd (regs, SBIC_CMD_RESET); ! 311: DELAY(25); ! 312: SBIC_WAIT(regs, SBIC_ASR_INT, 0); ! 313: GET_SBIC_csr (regs, csr); /* clears interrupt also */ ! 314: ! 315: /* ! 316: * Set up various chip parameters ! 317: */ ! 318: SET_SBIC_control (regs, (/*SBIC_CTL_HHP |*/ SBIC_CTL_EDI | SBIC_CTL_IDI | ! 319: /* | SBIC_CTL_HSP | */ SBIC_MACHINE_DMA_MODE)); ! 320: /* don't allow (re)selection (SBIC_RID_ES) until we can handle target mode!! */ ! 321: SET_SBIC_rselid (regs, 0 /* | SBIC_RID_ER | SBIC_RID_ES | SBIC_RID_DSP */); ! 322: SET_SBIC_syn (regs, 0); /* asynch for now */ ! 323: ! 324: /* anything else was zeroed by reset */ ! 325: ! 326: /* go async for now */ ! 327: dev->sc_sync = 0; ! 328: printf ("async"); ! 329: ! 330: printf(", scsi id %d\n", my_id & SBIC_ID_MASK); ! 331: dev->sc_flags |= SCSI_ALIVE; ! 332: dev->sc_flags &= ~SCSI_SELECTED; ! 333: } ! 334: ! 335: static void ! 336: scsierror(dev, regs, csr) ! 337: register struct scsi_softc *dev; ! 338: volatile register sbic_padded_regmap_t *regs; ! 339: u_char csr; ! 340: { ! 341: char *sep = ""; ! 342: ! 343: printf("scsi: "); ! 344: #if 0 ! 345: if (ints & INTS_RST) { ! 346: DELAY(100); ! 347: if (regs->scsi_aconf & HCONF_SD) ! 348: printf("spurious RST interrupt"); ! 349: else ! 350: printf("hardware error - check fuse"); ! 351: sep = ", "; ! 352: } ! 353: if ((ints & INTS_HARD_ERR) || regs->scsi_serr) { ! 354: if (regs->scsi_serr & SERR_SCSI_PAR) { ! 355: printf("%sparity err", sep); ! 356: sep = ", "; ! 357: } ! 358: if (regs->scsi_serr & SERR_SPC_PAR) { ! 359: printf("%sSPC parity err", sep); ! 360: sep = ", "; ! 361: } ! 362: if (regs->scsi_serr & SERR_TC_PAR) { ! 363: printf("%sTC parity err", sep); ! 364: sep = ", "; ! 365: } ! 366: if (regs->scsi_serr & SERR_PHASE_ERR) { ! 367: printf("%sphase err", sep); ! 368: sep = ", "; ! 369: } ! 370: if (regs->scsi_serr & SERR_SHORT_XFR) { ! 371: printf("%ssync short transfer err", sep); ! 372: sep = ", "; ! 373: } ! 374: if (regs->scsi_serr & SERR_OFFSET) { ! 375: printf("%ssync offset error", sep); ! 376: sep = ", "; ! 377: } ! 378: } ! 379: if (ints & INTS_TIMEOUT) ! 380: printf("%sSPC select timeout error", sep); ! 381: if (ints & INTS_SRV_REQ) ! 382: printf("%sspurious SRV_REQ interrupt", sep); ! 383: if (ints & INTS_CMD_DONE) ! 384: printf("%sspurious CMD_DONE interrupt", sep); ! 385: if (ints & INTS_DISCON) ! 386: printf("%sspurious disconnect interrupt", sep); ! 387: if (ints & INTS_RESEL) ! 388: printf("%sspurious reselect interrupt", sep); ! 389: if (ints & INTS_SEL) ! 390: printf("%sspurious select interrupt", sep); ! 391: #else ! 392: printf ("csr == 0x%02x", csr); /* XXX */ ! 393: #endif ! 394: printf("\n"); ! 395: } ! 396: ! 397: static int ! 398: issue_select(regs, target, our_addr) ! 399: volatile register sbic_padded_regmap_t *regs; ! 400: u_char target, our_addr; ! 401: { ! 402: u_char asr, csr; ! 403: ! 404: QPRINTF (("issue_select %d\n", target)); ! 405: ! 406: /* if we're already selected, return */ ! 407: if (scsi_softc.sc_flags & SCSI_SELECTED) /* XXXX */ ! 408: return 1; ! 409: ! 410: SBIC_TC_PUT (regs, 0); ! 411: SET_SBIC_selid (regs, target); ! 412: SET_SBIC_timeo (regs, SBIC_TIMEOUT(250,SBIC_CLOCK_FREQUENCY)); ! 413: SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN); ! 414: ! 415: return (0); ! 416: } ! 417: ! 418: static int ! 419: wait_for_select(regs) ! 420: volatile register sbic_padded_regmap_t *regs; ! 421: { ! 422: u_char asr, csr; ! 423: ! 424: QPRINTF (("wait_for_select: ")); ! 425: ! 426: WAIT_CIP (regs); ! 427: do ! 428: { ! 429: SBIC_WAIT (regs, SBIC_ASR_INT, 0); ! 430: GET_SBIC_csr (regs, csr); ! 431: QPRINTF (("%02x ", csr)); ! 432: } ! 433: while (csr != (SBIC_CSR_MIS_2|MESG_OUT_PHASE) ! 434: && csr != SBIC_CSR_SEL_TIMEO); ! 435: ! 436: /* Send identify message (SCSI-2 requires an identify msg (?)) */ ! 437: if (csr == (SBIC_CSR_MIS_2|MESG_OUT_PHASE)) ! 438: { ! 439: /* to get rid of amigados sync-settings... a bit kludgy I know.. */ ! 440: static char sent_reset[8]; ! 441: int id; ! 442: ! 443: GET_SBIC_selid (regs, id); ! 444: id &= 7; ! 445: if (reset_devices[id] && ! sent_reset [id]) ! 446: { ! 447: /* prevent endless recursion.. */ ! 448: sent_reset[id] = 1; ! 449: ! 450: SEND_BYTE (regs, MSG_BUS_DEVICE_RESET); ! 451: do ! 452: { ! 453: SBIC_WAIT (regs, SBIC_ASR_INT, 0); ! 454: GET_SBIC_csr (regs, csr); ! 455: } ! 456: while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1)); ! 457: /* give the device 5s time to get back to life.. might be ! 458: too long for many drives, and certainly too short for others, ! 459: sigh.. */ ! 460: DELAY(5000000); ! 461: QPRINTF (("[%02x]", csr)); ! 462: while (issue_select (regs, id, 7) == 1) ! 463: { ! 464: printf ("select failed, retrying...\n"); ! 465: DELAY(1000); ! 466: } ! 467: wait_for_select (regs); ! 468: } ! 469: ! 470: SEND_BYTE (regs, MSG_IDENTIFY); /* no MSG_IDENTIFY_DR yet */ ! 471: SBIC_WAIT (regs, SBIC_ASR_INT, 0); ! 472: GET_SBIC_csr (regs, csr); ! 473: QPRINTF (("[%02x]", csr)); ! 474: ! 475: scsi_softc.sc_flags |= SCSI_SELECTED; ! 476: } ! 477: ! 478: QPRINTF(("\n")); ! 479: ! 480: return csr == SBIC_CSR_SEL_TIMEO; ! 481: } ! 482: ! 483: static int ! 484: ixfer_start(regs, len, phase, wait) ! 485: volatile register sbic_padded_regmap_t *regs; ! 486: int len; ! 487: u_char phase; ! 488: register int wait; ! 489: { ! 490: #if 0 ! 491: regs->scsi_tch = len >> 16; ! 492: regs->scsi_tcm = len >> 8; ! 493: regs->scsi_tcl = len; ! 494: regs->scsi_pctl = phase; ! 495: regs->scsi_tmod = 0; /*XXX*/ ! 496: regs->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR; ! 497: ! 498: /* wait for xfer to start or svc_req interrupt */ ! 499: while ((regs->scsi_ssts & SSTS_BUSY) == 0) { ! 500: if (regs->scsi_ints || --wait < 0) { ! 501: #ifdef DEBUG ! 502: if (scsi_debug) ! 503: printf("ixfer_start fail: i%x, w%d\n", ! 504: regs->scsi_ints, wait); ! 505: #endif ! 506: HIST(ixstart_wait, wait) ! 507: return (0); ! 508: } ! 509: DELAY(1); ! 510: } ! 511: HIST(ixstart_wait, wait) ! 512: return (1); ! 513: #else ! 514: if (phase == DATA_IN_PHASE || phase == MESG_IN_PHASE) ! 515: { ! 516: u_char id; ! 517: ! 518: GET_SBIC_selid (regs, id); ! 519: id |= SBIC_SID_FROM_SCSI; ! 520: SET_SBIC_selid (regs, id); ! 521: ! 522: SBIC_TC_PUT (regs, (unsigned)len); ! 523: } ! 524: else if (phase == DATA_OUT_PHASE || phase == MESG_OUT_PHASE ! 525: || phase == CMD_PHASE ) ! 526: { ! 527: SBIC_TC_PUT (regs, (unsigned)len); ! 528: } ! 529: else ! 530: { ! 531: SBIC_TC_PUT (regs, 0); ! 532: } ! 533: ! 534: QPRINTF(("ixfer_start %d, %d, %d\n", len, phase, wait)); ! 535: ! 536: return 1; ! 537: #endif ! 538: } ! 539: ! 540: static int ! 541: ixfer_out(regs, len, buf, phase) ! 542: volatile register sbic_padded_regmap_t *regs; ! 543: int len; ! 544: register u_char *buf; ! 545: int phase; ! 546: { ! 547: register int wait = scsi_data_wait; ! 548: u_char orig_csr, csr, asr; ! 549: ! 550: QPRINTF(("ixfer_out {%d} %02x %02x %02x %02x %02x %02x\n", ! 551: len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5])); ! 552: ! 553: GET_SBIC_csr (regs, orig_csr); ! 554: ! 555: /* sigh.. WD-PROTO strikes again.. sending the command in one go causes ! 556: the chip to lock up if talking to certain (misbehaving?) targets. ! 557: Anyway, this procedure should work for all targets, but it's slightly ! 558: slower due to the overhead */ ! 559: #if 0 ! 560: if (phase == CMD_PHASE) ! 561: { ! 562: WAIT_CIP (regs); ! 563: #if 0 ! 564: for (; len > 0; len--) ! 565: { ! 566: /* clear possible last interrupt */ ! 567: GET_SBIC_csr (regs, csr); ! 568: ! 569: /* send the byte, and expect an interrupt afterwards */ ! 570: SEND_BYTE (regs, *buf); ! 571: buf++; ! 572: SBIC_WAIT (regs, SBIC_ASR_INT, 0); /* XXX */ ! 573: } ! 574: #else ! 575: SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO); ! 576: for (;len > 0; len--) ! 577: { ! 578: WAIT_CIP (regs); ! 579: GET_SBIC_csr (regs, csr); ! 580: SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO | SBIC_CMD_SBT); ! 581: GET_SBIC_asr (regs, asr); ! 582: while (!(asr & SBIC_ASR_DBR)) ! 583: { ! 584: DELAY(1); ! 585: GET_SBIC_asr (regs, asr); ! 586: } ! 587: ! 588: SET_SBIC_data (regs, *buf); ! 589: buf++; ! 590: while (!(asr & SBIC_ASR_INT)) ! 591: { ! 592: DELAY(1); ! 593: GET_SBIC_asr (regs, asr); ! 594: } ! 595: ! 596: } ! 597: ! 598: #endif ! 599: } ! 600: else ! 601: #endif ! 602: { ! 603: WAIT_CIP (regs); ! 604: SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO); ! 605: for (;len > 0; len--) ! 606: { ! 607: GET_SBIC_asr (regs, asr); ! 608: while (!(asr & SBIC_ASR_DBR)) ! 609: { ! 610: if ((asr & SBIC_ASR_INT) || --wait < 0) ! 611: { ! 612: #ifdef DEBUG ! 613: if (scsi_debug) ! 614: printf("ixfer_out fail: l%d i%x w%d\n", ! 615: len, asr, wait); ! 616: #endif ! 617: HIST(ixout_wait, wait) ! 618: return (len); ! 619: } ! 620: DELAY(1); ! 621: GET_SBIC_asr (regs, asr); ! 622: } ! 623: ! 624: SET_SBIC_data (regs, *buf); ! 625: buf++; ! 626: } ! 627: } ! 628: ! 629: QPRINTF(("ixfer_out done\n")); ! 630: /* this leaves with one csr to be read */ ! 631: HIST(ixout_wait, wait) ! 632: return (0); ! 633: } ! 634: ! 635: static void ! 636: ixfer_in(regs, len, buf) ! 637: volatile register sbic_padded_regmap_t *regs; ! 638: int len; ! 639: register u_char *buf; ! 640: { ! 641: register int wait = scsi_data_wait; ! 642: u_char *obp = buf; ! 643: u_char orig_csr, csr, asr; ! 644: ! 645: GET_SBIC_csr (regs, orig_csr); ! 646: ! 647: QPRINTF(("ixfer_in %d, csr=%02x\n", len, orig_csr)); ! 648: ! 649: WAIT_CIP (regs); ! 650: SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO); ! 651: for (;len > 0; len--) ! 652: { ! 653: GET_SBIC_asr (regs, asr); ! 654: while (!(asr & SBIC_ASR_DBR)) ! 655: { ! 656: if ((asr & SBIC_ASR_INT) || --wait < 0) ! 657: { ! 658: #ifdef DEBUG ! 659: if (scsi_debug) ! 660: printf("ixfer_in fail: l%d i%x w%d\n", ! 661: len, asr, wait); ! 662: #endif ! 663: HIST(ixin_wait, wait) ! 664: return; ! 665: } ! 666: ! 667: DELAY(1); ! 668: GET_SBIC_asr (regs, asr); ! 669: } ! 670: ! 671: GET_SBIC_data (regs, *buf); ! 672: buf++; ! 673: } ! 674: ! 675: QPRINTF(("ixfer_in {%d} %02x %02x %02x %02x %02x %02x\n", ! 676: len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5])); ! 677: ! 678: /* this leaves with one csr to be read */ ! 679: HIST(ixin_wait, wait) ! 680: } ! 681: ! 682: ! 683: /* ! 684: * SCSI 'immediate' command: issue a command to some SCSI device ! 685: * and get back an 'immediate' response (i.e., do programmed xfer ! 686: * to get the response data). 'cbuf' is a buffer containing a scsi ! 687: * command of length clen bytes. 'buf' is a buffer of length 'len' ! 688: * bytes for data. The transfer direction is determined by the device ! 689: * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the ! 690: * command must supply no data. 'xferphase' is the bus phase the ! 691: * caller expects to happen after the command is issued. It should ! 692: * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE. ! 693: */ ! 694: static int ! 695: scsiicmd(dev, target, cbuf, clen, buf, len, xferphase) ! 696: struct scsi_softc *dev; ! 697: int target; ! 698: u_char *cbuf; ! 699: int clen; ! 700: u_char *buf; ! 701: int len; ! 702: u_char xferphase; ! 703: { ! 704: volatile register sbic_padded_regmap_t *regs = ! 705: (sbic_padded_regmap_t *)dev->sc_ac->amiga_addr; ! 706: u_char phase, csr, asr; ! 707: register int wait; ! 708: ! 709: ! 710: #if 0 ! 711: /* XXXXXXXX */ ! 712: if (target != 6 && target != 4) ! 713: return -1; ! 714: /* XXXXXXXX */ ! 715: #endif ! 716: ! 717: /* set the sbic into non-DMA mode */ ! 718: SET_SBIC_control (regs, (/*SBIC_CTL_HHP |*/ SBIC_CTL_EDI | SBIC_CTL_IDI | ! 719: /* | SBIC_CTL_HSP | */ 0)); ! 720: ! 721: /* select the SCSI bus (it's an error if bus isn't free) */ ! 722: if (issue_select (regs, target, dev->sc_scsi_addr)) ! 723: return -1; ! 724: if (wait_for_select (regs)) ! 725: return -1; ! 726: /* ! 727: * Wait for a phase change (or error) then let the device ! 728: * sequence us through the various SCSI phases. ! 729: */ ! 730: dev->sc_stat[0] = 0xff; ! 731: dev->sc_msg[0] = 0xff; ! 732: phase = CMD_PHASE; ! 733: while (1) ! 734: { ! 735: wait = scsi_cmd_wait; ! 736: switch (phase) ! 737: { ! 738: case CMD_PHASE: ! 739: if (ixfer_start (regs, clen, phase, wait)) ! 740: if (ixfer_out (regs, clen, cbuf, phase)) ! 741: goto abort; ! 742: phase = xferphase; ! 743: break; ! 744: ! 745: case DATA_IN_PHASE: ! 746: if (len <= 0) ! 747: goto abort; ! 748: wait = scsi_data_wait; ! 749: if (ixfer_start (regs, len, phase, wait)) ! 750: ixfer_in (regs, len, buf); ! 751: phase = STATUS_PHASE; ! 752: break; ! 753: ! 754: case MESG_IN_PHASE: ! 755: if (ixfer_start (regs, sizeof (dev->sc_msg), phase, wait)) ! 756: { ! 757: ixfer_in (regs, sizeof (dev->sc_msg), dev->sc_msg); ! 758: /* prepare to reject any mesgin, no matter what it might be.. */ ! 759: SET_SBIC_cmd (regs, SBIC_CMD_SET_ATN); ! 760: WAIT_CIP (regs); ! 761: SET_SBIC_cmd (regs, SBIC_CMD_CLR_ACK); ! 762: phase = MESG_OUT_PHASE; ! 763: } ! 764: break; ! 765: ! 766: case MESG_OUT_PHASE: ! 767: SEND_BYTE (regs, MSG_REJECT); ! 768: phase = STATUS_PHASE; ! 769: break; ! 770: ! 771: case DATA_OUT_PHASE: ! 772: if (len <= 0) ! 773: goto abort; ! 774: wait = scsi_data_wait; ! 775: if (ixfer_start (regs, len, phase, wait)) ! 776: { ! 777: if (ixfer_out (regs, len, buf, phase)) ! 778: goto abort; ! 779: } ! 780: phase = STATUS_PHASE; ! 781: break; ! 782: ! 783: case STATUS_PHASE: ! 784: /* the sbic does the status/cmd-complete reading ok, so do this ! 785: with its hi-level commands. */ ! 786: SBIC_TC_PUT (regs, 0); ! 787: SET_SBIC_cmd_phase (regs, 0x46); ! 788: SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); ! 789: phase = BUS_FREE_PHASE; ! 790: break; ! 791: ! 792: case BUS_FREE_PHASE: ! 793: goto out; ! 794: ! 795: default: ! 796: printf("scsi: unexpected phase %d in icmd from %d\n", ! 797: phase, target); ! 798: goto abort; ! 799: } ! 800: ! 801: /* make sure the last command was taken, ie. we're not hunting after ! 802: an ignored command.. */ ! 803: GET_SBIC_asr (regs, asr); ! 804: if (asr & SBIC_ASR_LCI) ! 805: goto abort; ! 806: ! 807: /* tapes may take a loooong time.. */ ! 808: while (asr & SBIC_ASR_BSY) ! 809: { ! 810: DELAY(1); ! 811: GET_SBIC_asr (regs, asr); ! 812: } ! 813: ! 814: if (wait <= 0) ! 815: goto abort; ! 816: ! 817: /* wait for last command to complete */ ! 818: SBIC_WAIT (regs, SBIC_ASR_INT, wait); ! 819: ! 820: GET_SBIC_csr (regs, csr); ! 821: QPRINTF((">CSR:%02x<", csr)); ! 822: ! 823: HIST(cxin_wait, wait); ! 824: if ((csr != 0xff) && (csr & 0xf0) && (csr & 0x08)) /* requesting some new phase */ ! 825: phase = csr & PHASE; ! 826: else if ((csr == SBIC_CSR_DISC) || (csr == SBIC_CSR_DISC_1) ! 827: || (csr == SBIC_CSR_S_XFERRED)) ! 828: { ! 829: dev->sc_flags &= ~SCSI_SELECTED; ! 830: GET_SBIC_cmd_phase (regs, phase); ! 831: if (phase == 0x60) ! 832: GET_SBIC_tlun (regs, dev->sc_stat[0]); ! 833: else ! 834: return -1; ! 835: ! 836: goto out; ! 837: } ! 838: else ! 839: { ! 840: scsierror(dev, regs, csr); ! 841: goto abort; ! 842: } ! 843: } ! 844: ! 845: abort: ! 846: scsiabort(dev, regs, "icmd"); ! 847: out: ! 848: return (dev->sc_stat[0]); ! 849: } ! 850: ! 851: /* ! 852: * Finish SCSI xfer command: After the completion interrupt from ! 853: * a read/write operation, sequence through the final phases in ! 854: * programmed i/o. This routine is a lot like scsiicmd except we ! 855: * skip (and don't allow) the select, cmd out and data in/out phases. ! 856: */ ! 857: static void ! 858: finishxfer(dev, regs, target) ! 859: struct scsi_softc *dev; ! 860: volatile register sbic_padded_regmap_t *regs; ! 861: int target; ! 862: { ! 863: u_char phase, csr; ! 864: int s; ! 865: ! 866: s = splbio(); ! 867: /* have the sbic complete on its own */ ! 868: SBIC_TC_PUT (regs, 0); ! 869: SET_SBIC_cmd_phase (regs, 0x46); ! 870: SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); ! 871: ! 872: do ! 873: { ! 874: SBIC_WAIT (regs, SBIC_ASR_INT, 0); ! 875: GET_SBIC_csr (regs, csr); ! 876: } ! 877: while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1) ! 878: && (csr != SBIC_CSR_S_XFERRED)); ! 879: ! 880: dev->sc_flags &= ~SCSI_SELECTED; ! 881: GET_SBIC_cmd_phase (regs, phase); ! 882: if (phase == 0x60) ! 883: GET_SBIC_tlun (regs, dev->sc_stat[0]); ! 884: else ! 885: scsierror (dev, regs, csr); ! 886: ! 887: splx (s); ! 888: } ! 889: ! 890: int ! 891: scsi_test_unit_rdy(slave) ! 892: int slave; ! 893: { ! 894: register struct scsi_softc *dev = &scsi_softc; ! 895: static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY }; ! 896: ! 897: return (scsiicmd(dev, slave, (u_char *)&cdb, sizeof(cdb), (u_char *)0, 0, ! 898: STATUS_PHASE)); ! 899: } ! 900: ! 901: int ! 902: scsi_request_sense(slave, buf, len) ! 903: int slave; ! 904: u_char *buf; ! 905: unsigned len; ! 906: { ! 907: register struct scsi_softc *dev = &scsi_softc; ! 908: static struct scsi_cdb6 cdb = { CMD_REQUEST_SENSE }; ! 909: ! 910: cdb.len = len; ! 911: return (scsiicmd(dev, slave, (u_char *)&cdb, sizeof(cdb), buf, len, DATA_IN_PHASE)); ! 912: } ! 913: ! 914: int ! 915: scsi_immed_command(slave, cdb, buf, len, rd) ! 916: int slave; ! 917: struct scsi_fmt_cdb *cdb; ! 918: u_char *buf; ! 919: unsigned len; ! 920: { ! 921: register struct scsi_softc *dev = &scsi_softc; ! 922: ! 923: return (scsiicmd(dev, slave, (u_char *) cdb->cdb, cdb->len, buf, len, ! 924: rd != 0? DATA_IN_PHASE : DATA_OUT_PHASE)); ! 925: } ! 926: ! 927: /* ! 928: * The following routines are test-and-transfer i/o versions of read/write ! 929: * for things like reading disk labels and writing core dumps. The ! 930: * routine scsigo should be used for normal data transfers, NOT these ! 931: * routines. ! 932: */ ! 933: int ! 934: scsi_tt_read(slave, buf, len, blk, bshift) ! 935: int slave; ! 936: u_char *buf; ! 937: u_int len; ! 938: daddr_t blk; ! 939: int bshift; ! 940: { ! 941: register struct scsi_softc *dev = &scsi_softc; ! 942: struct scsi_cdb10 cdb; ! 943: int stat; ! 944: int old_wait = scsi_data_wait; ! 945: ! 946: scsi_data_wait = 300000; ! 947: bzero(&cdb, sizeof(cdb)); ! 948: cdb.cmd = CMD_READ_EXT; ! 949: blk >>= bshift; ! 950: cdb.lbah = blk >> 24; ! 951: cdb.lbahm = blk >> 16; ! 952: cdb.lbalm = blk >> 8; ! 953: cdb.lbal = blk; ! 954: cdb.lenh = len >> (8 + DEV_BSHIFT + bshift); ! 955: cdb.lenl = len >> (DEV_BSHIFT + bshift); ! 956: stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE); ! 957: scsi_data_wait = old_wait; ! 958: return (stat); ! 959: } ! 960: ! 961: int ! 962: scsi_tt_write(slave, buf, len, blk, bshift) ! 963: int slave; ! 964: u_char *buf; ! 965: u_int len; ! 966: daddr_t blk; ! 967: int bshift; ! 968: { ! 969: register struct scsi_softc *dev = &scsi_softc; ! 970: struct scsi_cdb10 cdb; ! 971: int stat; ! 972: int old_wait = scsi_data_wait; ! 973: ! 974: scsi_data_wait = 300000; ! 975: ! 976: bzero(&cdb, sizeof(cdb)); ! 977: cdb.cmd = CMD_WRITE_EXT; ! 978: blk >>= bshift; ! 979: cdb.lbah = blk >> 24; ! 980: cdb.lbahm = blk >> 16; ! 981: cdb.lbalm = blk >> 8; ! 982: cdb.lbal = blk; ! 983: cdb.lenh = len >> (8 + DEV_BSHIFT + bshift); ! 984: cdb.lenl = len >> (DEV_BSHIFT + bshift); ! 985: stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, DATA_OUT_PHASE); ! 986: scsi_data_wait = old_wait; ! 987: return (stat); ! 988: } ! 989: ! 990: int ! 991: scsireq(dq) ! 992: register struct devqueue *dq; ! 993: { ! 994: register struct devqueue *hq; ! 995: ! 996: hq = &scsi_softc.sc_sq; ! 997: insque(dq, hq->dq_back); ! 998: if (dq->dq_back == hq) ! 999: return(1); ! 1000: return(0); ! 1001: } ! 1002: ! 1003: int ! 1004: scsiustart (int unit) ! 1005: { ! 1006: register struct scsi_softc *dev = &scsi_softc; ! 1007: ! 1008: if (dmareq(&dev->sc_dq)) ! 1009: return(1); ! 1010: return(0); ! 1011: } ! 1012: ! 1013: void ! 1014: scsistart (int unit) ! 1015: { ! 1016: register struct devqueue *dq; ! 1017: ! 1018: dq = scsi_softc.sc_sq.dq_forw; ! 1019: (dq->dq_driver->d_go)(dq->dq_unit); ! 1020: } ! 1021: ! 1022: int ! 1023: scsigo(unit, slave, bp, cdb, pad) ! 1024: int unit, slave; ! 1025: struct buf *bp; ! 1026: struct scsi_fmt_cdb *cdb; ! 1027: int pad; ! 1028: { ! 1029: register struct scsi_softc *dev = &scsi_softc; ! 1030: volatile register sbic_padded_regmap_t *regs = ! 1031: (sbic_padded_regmap_t *)dev->sc_ac->amiga_addr; ! 1032: int i, dmaflags; ! 1033: u_char phase, csr, asr, cmd; ! 1034: ! 1035: #if 0 ! 1036: /* XXXXXXXX */ ! 1037: if (slave != 6 && slave != 4) ! 1038: return -1; ! 1039: /* XXXXXXXX */ ! 1040: #endif ! 1041: ! 1042: /* this should only happen on character devices, and there only if user ! 1043: programs have not been written taking care of not passing odd aligned ! 1044: buffers. dd was a bad example of this sin.. */ ! 1045: ! 1046: /* XXXX do all with polled I/O */ ! 1047: ! 1048: if ((((int)bp->b_un.b_addr & 3) || (bp->b_bcount & 1))) ! 1049: { ! 1050: register struct devqueue *dq; ! 1051: ! 1052: dmafree(&dev->sc_dq); ! 1053: ! 1054: /* in this case do the transfer with programmed I/O :-( This is ! 1055: probably still faster than doing the transfer with DMA into a ! 1056: buffer and copying it later to its final destination, comments? */ ! 1057: scsiicmd (dev, slave, (u_char *) cdb->cdb, cdb->len, ! 1058: bp->b_un.b_addr, bp->b_bcount, ! 1059: bp->b_flags & B_READ ? DATA_IN_PHASE : DATA_OUT_PHASE); ! 1060: ! 1061: dq = dev->sc_sq.dq_forw; ! 1062: dev->sc_flags &=~ SCSI_IO; ! 1063: (dq->dq_driver->d_intr)(dq->dq_unit, dev->sc_stat[0]); ! 1064: return dev->sc_stat[0]; ! 1065: } ! 1066: ! 1067: /* set the sbic into DMA mode */ ! 1068: SET_SBIC_control (regs, (/*SBIC_CTL_HHP |*/ SBIC_CTL_EDI | SBIC_CTL_IDI | ! 1069: /* | SBIC_CTL_HSP | */ SBIC_MACHINE_DMA_MODE)); ! 1070: ! 1071: /* select the SCSI bus (it's an error if bus isn't free) */ ! 1072: if (issue_select(regs, slave, dev->sc_scsi_addr) || wait_for_select(regs)) ! 1073: { ! 1074: dmafree(&dev->sc_dq); ! 1075: return (1); ! 1076: } ! 1077: /* ! 1078: * Wait for a phase change (or error) then let the device ! 1079: * sequence us through command phase (we may have to take ! 1080: * a msg in/out before doing the command). If the disk has ! 1081: * to do a seek, it may be a long time until we get a change ! 1082: * to data phase so, in the absense of an explicit phase ! 1083: * change, we assume data phase will be coming up and tell ! 1084: * the SPC to start a transfer whenever it does. We'll get ! 1085: * a service required interrupt later if this assumption is ! 1086: * wrong. Otherwise we'll get a service required int when ! 1087: * the transfer changes to status phase. ! 1088: */ ! 1089: phase = CMD_PHASE; ! 1090: while (1) ! 1091: { ! 1092: register int wait = scsi_cmd_wait; ! 1093: register struct devqueue *dq; ! 1094: ! 1095: switch (phase) ! 1096: { ! 1097: case CMD_PHASE: ! 1098: if (ixfer_start(regs, cdb->len, phase, wait)) ! 1099: if (ixfer_out(regs, cdb->len, cdb->cdb, phase)) ! 1100: goto abort; ! 1101: break; ! 1102: ! 1103: case MESG_IN_PHASE: ! 1104: if (ixfer_start (regs, sizeof (dev->sc_msg), phase, wait)) ! 1105: { ! 1106: ixfer_in (regs, sizeof (dev->sc_msg), dev->sc_msg); ! 1107: /* prepare to reject any mesgin, no matter what it might be.. */ ! 1108: SET_SBIC_cmd (regs, SBIC_CMD_SET_ATN); ! 1109: WAIT_CIP (regs); ! 1110: SET_SBIC_cmd (regs, SBIC_CMD_CLR_ACK); ! 1111: phase = MESG_OUT_PHASE; ! 1112: } ! 1113: break; ! 1114: ! 1115: case MESG_OUT_PHASE: ! 1116: SEND_BYTE (regs, MSG_REJECT); ! 1117: phase = STATUS_PHASE; ! 1118: break; ! 1119: ! 1120: case DATA_IN_PHASE: ! 1121: case DATA_OUT_PHASE: ! 1122: goto out; ! 1123: ! 1124: /* status phase can happen, if the issued read/write command is ! 1125: illegal (for example, reading after EOT on tape) and the device ! 1126: doesn't even go to data in/out phase. So handle this here ! 1127: normally, instead of going thru abort-handling. */ ! 1128: case STATUS_PHASE: ! 1129: dmafree(&dev->sc_dq); ! 1130: finishxfer (dev, regs, slave); ! 1131: dq = dev->sc_sq.dq_forw; ! 1132: dev->sc_flags &=~ SCSI_IO; ! 1133: (dq->dq_driver->d_intr)(dq->dq_unit, dev->sc_stat[0]); ! 1134: return 0; ! 1135: ! 1136: default: ! 1137: printf("scsi: unexpected phase %d in go from %d\n", ! 1138: phase, slave); ! 1139: goto abort; ! 1140: } ! 1141: ! 1142: /* make sure the last command was taken, ie. we're not hunting after ! 1143: an ignored command.. */ ! 1144: GET_SBIC_asr (regs, asr); ! 1145: if (asr & SBIC_ASR_LCI) ! 1146: goto abort; ! 1147: ! 1148: /* tapes may take a loooong time.. */ ! 1149: while (asr & SBIC_ASR_BSY) ! 1150: { ! 1151: DELAY(1); ! 1152: GET_SBIC_asr (regs, asr); ! 1153: } ! 1154: ! 1155: if (wait <= 0) ! 1156: goto abort; ! 1157: ! 1158: /* wait for last command to complete */ ! 1159: SBIC_WAIT (regs, SBIC_ASR_INT, wait); ! 1160: ! 1161: GET_SBIC_csr (regs, csr); ! 1162: QPRINTF((">CSR:%02x<", csr)); ! 1163: ! 1164: HIST(sgo_wait, wait); ! 1165: if ((csr != 0xff) && (csr & 0xf0) && (csr & 0x08)) /* requesting some new phase */ ! 1166: phase = csr & PHASE; ! 1167: else ! 1168: { ! 1169: scsierror(dev, regs, csr); ! 1170: goto abort; ! 1171: } ! 1172: } ! 1173: ! 1174: out: ! 1175: dmaflags = DMAGO_NOINT; ! 1176: if (bp->b_flags & B_READ) ! 1177: dmaflags |= DMAGO_READ; ! 1178: if ((int)bp->b_un.b_addr & 3) ! 1179: panic ("not long-aligned buffer address in scsi_go"); ! 1180: if (bp->b_bcount & 1) ! 1181: panic ("odd transfer count in scsi_go"); ! 1182: ! 1183: /* dmago() also enables interrupts for the sbic */ ! 1184: i = dmago(bp->b_un.b_addr, bp->b_bcount, dmaflags); ! 1185: ! 1186: SBIC_TC_PUT (regs, (unsigned)i); ! 1187: SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO); ! 1188: ! 1189: return (0); ! 1190: ! 1191: abort: ! 1192: scsiabort(dev, regs, "go"); ! 1193: dmafree(&dev->sc_dq); ! 1194: return (1); ! 1195: } ! 1196: ! 1197: void ! 1198: scsidone (int unit) ! 1199: { ! 1200: volatile register sbic_padded_regmap_t *regs = ! 1201: (sbic_padded_regmap_t *)scsi_softc.sc_ac->amiga_addr; ! 1202: ! 1203: #ifdef DEBUG ! 1204: if (scsi_debug) ! 1205: printf("scsi: done called!\n"); ! 1206: #endif ! 1207: } ! 1208: ! 1209: int ! 1210: scsiintr (int unit) ! 1211: { ! 1212: register struct scsi_softc *dev = &scsi_softc; ! 1213: volatile register sbic_padded_regmap_t *regs = ! 1214: (sbic_padded_regmap_t *)dev->sc_ac->amiga_addr; ! 1215: register u_char asr, csr, phase; ! 1216: register struct devqueue *dq; ! 1217: int i; ! 1218: ! 1219: GET_SBIC_asr (regs, asr); ! 1220: if (! (asr & SBIC_ASR_INT)) ! 1221: return 0; ! 1222: ! 1223: GET_SBIC_csr (regs, csr); ! 1224: QPRINTF(("[0x%x]", csr)); ! 1225: ! 1226: if (csr == (SBIC_CSR_XFERRED|STATUS_PHASE) ! 1227: || csr == (SBIC_CSR_MIS|STATUS_PHASE) ! 1228: || csr == (SBIC_CSR_MIS_1|STATUS_PHASE) ! 1229: || csr == (SBIC_CSR_MIS_2|STATUS_PHASE)) ! 1230: { ! 1231: /* ! 1232: * this should be the normal i/o completion case. ! 1233: * get the status & cmd complete msg then let the ! 1234: * device driver look at what happened. ! 1235: */ ! 1236: dq = dev->sc_sq.dq_forw; ! 1237: finishxfer(dev, regs, dq->dq_slave); ! 1238: dev->sc_flags &=~ SCSI_IO; ! 1239: dmafree (&dev->sc_dq); ! 1240: (dq->dq_driver->d_intr)(dq->dq_unit, dev->sc_stat[0]); ! 1241: } ! 1242: else if (csr == (SBIC_CSR_XFERRED|DATA_OUT_PHASE) || csr == (SBIC_CSR_XFERRED|DATA_IN_PHASE) ! 1243: || csr == (SBIC_CSR_MIS|DATA_OUT_PHASE) || csr == (SBIC_CSR_MIS|DATA_IN_PHASE) ! 1244: || csr == (SBIC_CSR_MIS_1|DATA_OUT_PHASE) || csr == (SBIC_CSR_MIS_1|DATA_IN_PHASE) ! 1245: || csr == (SBIC_CSR_MIS_2|DATA_OUT_PHASE) || csr == (SBIC_CSR_MIS_2|DATA_IN_PHASE)) ! 1246: { ! 1247: /* do scatter-gather dma hacking the controller chip, ouch.. */ ! 1248: i = dmanext (); ! 1249: SBIC_TC_PUT (regs, (unsigned)i); ! 1250: SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO); ! 1251: } ! 1252: else ! 1253: { ! 1254: /* Something unexpected happened -- deal with it. */ ! 1255: dmastop (); ! 1256: scsierror(dev, regs, csr); ! 1257: scsiabort(dev, regs, "intr"); ! 1258: if (dev->sc_flags & SCSI_IO) ! 1259: { ! 1260: dev->sc_flags &=~ SCSI_IO; ! 1261: dmafree (&dev->sc_dq); ! 1262: dq = dev->sc_sq.dq_forw; ! 1263: (dq->dq_driver->d_intr)(dq->dq_unit, -1); ! 1264: } ! 1265: } ! 1266: ! 1267: return 1; ! 1268: } ! 1269: ! 1270: void ! 1271: scsifree(dq) ! 1272: register struct devqueue *dq; ! 1273: { ! 1274: register struct devqueue *hq; ! 1275: ! 1276: hq = &scsi_softc.sc_sq; ! 1277: remque(dq); ! 1278: if ((dq = hq->dq_forw) != hq) ! 1279: (dq->dq_driver->d_start)(dq->dq_unit); ! 1280: } ! 1281: ! 1282: /* ! 1283: * (XXX) The following routine is needed for the SCSI tape driver ! 1284: * to read odd-size records. ! 1285: */ ! 1286: ! 1287: #include "st.h" ! 1288: #if NST > 0 ! 1289: int ! 1290: scsi_tt_oddio(slave, buf, len, b_flags, freedma) ! 1291: int slave, b_flags; ! 1292: u_char *buf; ! 1293: u_int len; ! 1294: { ! 1295: register struct scsi_softc *dev = &scsi_softc; ! 1296: struct scsi_cdb6 cdb; ! 1297: u_char iphase; ! 1298: int stat; ! 1299: ! 1300: /* ! 1301: * First free any DMA channel that was allocated. ! 1302: * We can't use DMA to do this transfer. ! 1303: */ ! 1304: if (freedma) ! 1305: dmafree(&dev->sc_dq); ! 1306: /* ! 1307: * Initialize command block ! 1308: */ ! 1309: bzero(&cdb, sizeof(cdb)); ! 1310: cdb.lbam = (len >> 16) & 0xff; ! 1311: cdb.lbal = (len >> 8) & 0xff; ! 1312: cdb.len = len & 0xff; ! 1313: if (buf == 0) { ! 1314: cdb.cmd = CMD_SPACE; ! 1315: cdb.lun |= 0x00; ! 1316: len = 0; ! 1317: iphase = MESG_IN_PHASE; ! 1318: } else if (b_flags & B_READ) { ! 1319: cdb.cmd = CMD_READ; ! 1320: iphase = DATA_IN_PHASE; ! 1321: } else { ! 1322: cdb.cmd = CMD_WRITE; ! 1323: iphase = DATA_OUT_PHASE; ! 1324: } ! 1325: /* ! 1326: * Perform command (with very long delays) ! 1327: */ ! 1328: scsi_delay(30000000); ! 1329: stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, iphase); ! 1330: scsi_delay(0); ! 1331: return (stat); ! 1332: } ! 1333: #endif ! 1334: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.