Annotation of Net2/arch/amiga/dev/scsi.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.