[BACK]Return to seagate.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / isa

Annotation of src/sys/dev/isa/seagate.c, Revision 1.65.6.1

1.65.6.1! skrll       1: /*     $NetBSD: seagate.c,v 1.67 2009/03/16 09:34:17 cegger Exp $      */
1.24      perry       2:
1.1       mycroft     3: /*
                      4:  * ST01/02, Future Domain TMC-885, TMC-950 SCSI driver
                      5:  *
1.28      mycroft     6:  * Copyright 1994, Charles M. Hannum (mycroft@ai.mit.edu)
1.1       mycroft     7:  * Copyright 1994, Kent Palmkvist (kentp@isy.liu.se)
1.57      perry       8:  * Copyright 1994, Robert Knier (rknier@qgraph.com)
1.1       mycroft     9:  * Copyright 1992, 1994 Drew Eckhardt (drew@colorado.edu)
                     10:  * Copyright 1994, Julian Elischer (julian@tfs.com)
                     11:  *
                     12:  * Others that has contributed by example code is
                     13:  *             Glen Overby (overby@cray.com)
                     14:  *             Tatu Yllnen
                     15:  *             Brian E Litzinger
                     16:  *
                     17:  * Redistribution and use in source and binary forms, with or without
                     18:  * modification, are permitted provided that the following conditions
                     19:  * are met:
                     20:  * 1. Redistributions of source code must retain the above copyright
                     21:  *    notice, this list of conditions and the following disclaimer.
                     22:  * 2. Redistributions in binary form must reproduce the above copyright
                     23:  *    notice, this list of conditions and the following disclaimer in the
                     24:  *    documentation and/or other materials provided with the distribution.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND
                     27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE DEVELOPERS BE LIABLE
                     30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     36:  * SUCH DAMAGE.
                     37:  */
                     38:
                     39: /*
                     40:  * kentp  940307 alpha version based on newscsi-03 version of Julians SCSI-code
                     41:  * kentp  940314 Added possibility to not use messages
1.57      perry      42:  * rknier 940331 Added fast transfer code
                     43:  * rknier 940407 Added assembler coded data transfers
1.1       mycroft    44:  */
                     45:
                     46: /*
                     47:  * What should really be done:
1.57      perry      48:  *
1.1       mycroft    49:  * Add missing tests for timeouts
                     50:  * Restructure interrupt enable/disable code (runs to long with int disabled)
                     51:  * Find bug? giving problem with tape status
                     52:  * Add code to handle Future Domain 840, 841, 880 and 881
                     53:  * adjust timeouts (startup is very slow)
                     54:  * add code to use tagged commands in SCSI2
                     55:  * Add code to handle slow devices better (sleep if device not disconnecting)
                     56:  * Fix unnecessary interrupts
                     57:  */
                     58:
                     59: /*
                     60:  * Note to users trying to share a disk between DOS and unix:
                     61:  * The ST01/02 is a translating host-adapter. It is not giving DOS
                     62:  * the same number of heads/tracks/sectors as specified by the disk.
                     63:  * It is therefore important to look at what numbers DOS thinks the
                     64:  * disk has. Use these to disklabel your disk in an appropriate manner
                     65:  */
1.57      perry      66:
1.43      lukem      67: #include <sys/cdefs.h>
1.65.6.1! skrll      68: __KERNEL_RCSID(0, "$NetBSD: seagate.c,v 1.67 2009/03/16 09:34:17 cegger Exp $");
1.43      lukem      69:
1.1       mycroft    70: #include <sys/param.h>
                     71: #include <sys/systm.h>
                     72: #include <sys/kernel.h>
                     73: #include <sys/errno.h>
                     74: #include <sys/ioctl.h>
1.3       mycroft    75: #include <sys/device.h>
1.1       mycroft    76: #include <sys/buf.h>
                     77: #include <sys/proc.h>
                     78: #include <sys/user.h>
1.3       mycroft    79: #include <sys/queue.h>
                     80: #include <sys/malloc.h>
1.1       mycroft    81:
1.63      ad         82: #include <sys/intr.h>
1.1       mycroft    83: #include <machine/pio.h>
                     84:
1.23      bouyer     85: #include <dev/scsipi/scsi_all.h>
                     86: #include <dev/scsipi/scsipi_all.h>
                     87: #include <dev/scsipi/scsi_message.h>
                     88: #include <dev/scsipi/scsiconf.h>
1.1       mycroft    89:
1.8       cgd        90: #include <dev/isa/isareg.h>
1.33      cgd        91: #include <dev/isa/isavar.h>    /* XXX USES ISA HOLE DIRECTLY */
1.3       mycroft    92:
1.1       mycroft    93: #define        SEA_SCB_MAX     32      /* allow maximally 8 scsi control blocks */
                     94: #define SCB_TABLE_SIZE 8       /* start with 8 scb entries in table */
                     95: #define BLOCK_SIZE     512     /* size of READ/WRITE areas on SCSI card */
                     96:
                     97: /*
                     98:  * defining SEA_BLINDTRANSFER will make DATA IN and DATA OUT to be done with
                     99:  * blind transfers, i.e. no check is done for scsi phase changes. This will
                    100:  * result in data loss if the scsi device does not send its data using
                    101:  * BLOCK_SIZE bytes at a time.
                    102:  * If SEA_BLINDTRANSFER defined and SEA_ASSEMBLER also defined will result in
                    103:  * the use of blind transfers coded in assembler. SEA_ASSEMBLER is no good
                    104:  * without SEA_BLINDTRANSFER defined.
                    105:  */
                    106: #define        SEA_BLINDTRANSFER       /* do blind transfers */
                    107: #define        SEA_ASSEMBLER           /* Use assembly code for fast transfers */
                    108:
                    109: /*
                    110:  * defining SEA_NOMSGS causes messages not to be used (thereby disabling
                    111:  * disconnects)
                    112:  */
                    113: #undef SEA_NOMSGS
                    114:
                    115: /*
                    116:  * defining SEA_NODATAOUT makes dataout phase being aborted
                    117:  */
                    118: #undef SEA_NODATAOUT
                    119:
                    120: /* Debugging definitions. Should not be used unless you want a lot of
                    121:    printouts even under normal conditions */
                    122:
                    123: #undef SEA_DEBUGQUEUE          /* Display info about queue-lengths */
                    124:
                    125: /******************************* board definitions **************************/
                    126: /*
                    127:  * CONTROL defines
                    128:  */
                    129: #define CMD_RST                0x01            /* scsi reset */
                    130: #define CMD_SEL                0x02            /* scsi select */
                    131: #define CMD_BSY                0x04            /* scsi busy */
                    132: #define        CMD_ATTN        0x08            /* scsi attention */
                    133: #define CMD_START_ARB  0x10            /* start arbitration bit */
                    134: #define        CMD_EN_PARITY   0x20            /* enable scsi parity generation */
                    135: #define CMD_INTR       0x40            /* enable scsi interrupts */
                    136: #define CMD_DRVR_ENABLE        0x80            /* scsi enable */
                    137:
                    138: /*
                    139:  * STATUS
                    140:  */
                    141: #define STAT_BSY       0x01            /* scsi busy */
                    142: #define STAT_MSG       0x02            /* scsi msg */
                    143: #define STAT_IO                0x04            /* scsi I/O */
                    144: #define STAT_CD                0x08            /* scsi C/D */
                    145: #define STAT_REQ       0x10            /* scsi req */
                    146: #define STAT_SEL       0x20            /* scsi select */
                    147: #define STAT_PARITY    0x40            /* parity error bit */
                    148: #define STAT_ARB_CMPL  0x80            /* arbitration complete bit */
                    149:
                    150: /*
                    151:  * REQUESTS
                    152:  */
1.3       mycroft   153: #define PH_DATAOUT     (0)
                    154: #define PH_DATAIN      (STAT_IO)
                    155: #define PH_CMD         (STAT_CD)
                    156: #define PH_STAT                (STAT_CD | STAT_IO)
                    157: #define PH_MSGOUT      (STAT_MSG | STAT_CD)
                    158: #define PH_MSGIN       (STAT_MSG | STAT_CD | STAT_IO)
                    159:
                    160: #define PH_MASK                (STAT_MSG | STAT_CD | STAT_IO)
1.1       mycroft   161:
1.3       mycroft   162: #define PH_INVALID     0xff
1.1       mycroft   163:
                    164: #define SEA_RAMOFFSET  0x00001800
                    165:
                    166: #define BASE_CMD       (CMD_INTR | CMD_EN_PARITY)
                    167:
1.3       mycroft   168: #define        SEAGATE         1       /* Seagate ST0[12] */
                    169: #define        FDOMAIN         2       /* Future Domain TMC-{885,950} */
                    170: #define        FDOMAIN840      3       /* Future Domain TMC-{84[01],88[01]} */
1.1       mycroft   171:
                    172: /******************************************************************************/
                    173:
1.57      perry     174: /* scsi control block used to keep info about a scsi command */
1.1       mycroft   175: struct sea_scb {
                    176:         u_char *data;                  /* position in data buffer so far */
1.3       mycroft   177:        int datalen;                    /* bytes remaining to transfer */
1.1       mycroft   178:        TAILQ_ENTRY(sea_scb) chain;
1.23      bouyer    179:        struct scsipi_xfer *xs;         /* the scsipi_xfer for this cmd */
1.1       mycroft   180:        int flags;                      /* status of the instruction */
                    181: #define        SCB_FREE        0
                    182: #define        SCB_ACTIVE      1
                    183: #define SCB_ABORTED    2
                    184: #define SCB_TIMEOUT    4
                    185: #define SCB_ERROR      8
                    186: };
                    187:
                    188: /*
                    189:  * data structure describing current status of the scsi bus. One for each
                    190:  * controller card.
                    191:  */
                    192: struct sea_softc {
                    193:        struct device sc_dev;
1.8       cgd       194:        void *sc_ih;
1.1       mycroft   195:
1.3       mycroft   196:        int type;                       /* board type */
1.62      christos  197:        void *  maddr;                  /* Base address for card */
                    198:        void *  maddr_cr_sr;            /* Address of control and status reg */
                    199:        void *  maddr_dr;               /* Address of data register */
1.3       mycroft   200:
1.30      thorpej   201:        struct scsipi_adapter sc_adapter;
1.40      bouyer    202:        struct scsipi_channel sc_channel;
                    203:
1.3       mycroft   204:        TAILQ_HEAD(, sea_scb) free_list, ready_list, nexus_list;
                    205:        struct sea_scb *nexus;          /* currently connected command */
                    206:        int numscbs;                    /* number of scsi control blocks */
                    207:        struct sea_scb scb[SCB_TABLE_SIZE];
                    208:
1.1       mycroft   209:        int our_id;                     /* our scsi id */
                    210:        u_char our_id_mask;
                    211:        volatile u_char busy[8];        /* index=target, bit=lun, Keep track of
                    212:                                           busy luns at device target */
                    213: };
                    214:
                    215: /* flag showing if main routine is running. */
                    216: static volatile int main_running = 0;
                    217:
                    218: #define        STATUS  (*(volatile u_char *)sea->maddr_cr_sr)
                    219: #define CONTROL        STATUS
                    220: #define DATA   (*(volatile u_char *)sea->maddr_dr)
                    221:
                    222: /*
                    223:  * These are "special" values for the tag parameter passed to sea_select
                    224:  * Not implemented right now.
                    225:  */
                    226: #define TAG_NEXT       -1      /* Use next free tag */
                    227: #define TAG_NONE       -2      /*
                    228:                                 * Establish I_T_L nexus instead of I_T_L_Q
                    229:                                 * even on SCSI-II devices.
                    230:                                 */
                    231:
                    232: typedef struct {
1.58      christos  233:        const char *signature;
1.1       mycroft   234:        int offset, length;
                    235:        int type;
                    236: } BiosSignature;
                    237:
                    238: /*
                    239:  * Signatures for automatic recognition of board type
                    240:  */
                    241: static const BiosSignature signatures[] = {
                    242: {"ST01 v1.7  (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
                    243: {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
                    244:
                    245: /*
                    246:  * The following two lines are NOT mistakes. One detects ROM revision
                    247:  * 3.0.0, the other 3.2. Since seagate has only one type of SCSI adapter,
                    248:  * and this is not going to change, the "SEAGATE" and "SCSI" together
                    249:  * are probably "good enough"
                    250:  */
                    251: {"SEAGATE SCSI BIOS ", 16, 17, SEAGATE},
                    252: {"SEAGATE SCSI BIOS ", 17, 17, SEAGATE},
                    253:
                    254: /*
                    255:  * However, future domain makes several incompatible SCSI boards, so specific
                    256:  * signatures must be used.
                    257:  */
                    258: {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 45, FDOMAIN},
                    259: {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FDOMAIN},
                    260: {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FDOMAIN},
                    261: {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90",5, 47, FDOMAIN},
                    262: {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FDOMAIN},
                    263: {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92",   5, 44, FDOMAIN},
                    264: {"FUTURE DOMAIN TMC-950",                         5, 21, FDOMAIN},
                    265: };
                    266:
                    267: #define        nsignatures     (sizeof(signatures) / sizeof(signatures[0]))
                    268:
1.16      christos  269: #ifdef notdef
1.1       mycroft   270: static const char *bases[] = {
                    271:        (char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000,
                    272:        (char *) 0xce000, (char *) 0xdc000, (char *) 0xde000
                    273: };
                    274:
                    275: #define        nbases          (sizeof(bases) / sizeof(bases[0]))
1.16      christos  276: #endif
1.1       mycroft   277:
1.56      perry     278: int seaintr(void *);
                    279: void sea_scsipi_request(struct scsipi_channel *, scsipi_adapter_req_t, void *);
                    280: void sea_timeout(void *);
                    281: void sea_done(struct sea_softc *, struct sea_scb *);
                    282: struct sea_scb *sea_get_scb(struct sea_softc *, int);
                    283: void sea_free_scb(struct sea_softc *, struct sea_scb *, int);
                    284: static void sea_main(void);
                    285: static void sea_information_transfer(struct sea_softc *);
                    286: int sea_poll(struct sea_softc *, struct scsipi_xfer *, int);
                    287: void sea_init(struct sea_softc *);
                    288: void sea_send_scb(struct sea_softc *sea, struct sea_scb *scb);
                    289: void sea_reselect(struct sea_softc *sea);
                    290: int sea_select(struct sea_softc *sea, struct sea_scb *scb);
                    291: int sea_transfer_pio(struct sea_softc *sea, u_char *phase,
                    292:     int *count, u_char **data);
                    293: int sea_abort(struct sea_softc *, struct sea_scb *scb);
1.1       mycroft   294:
1.56      perry     295: void   sea_grow_scb(struct sea_softc *);
1.1       mycroft   296:
1.56      perry     297: int    seaprobe(struct device *, struct cfdata *, void *);
                    298: void   seaattach(struct device *, struct device *, void *);
1.1       mycroft   299:
1.51      thorpej   300: CFATTACH_DECL(sea, sizeof(struct sea_softc),
1.52      thorpej   301:     seaprobe, seaattach, NULL, NULL);
1.14      thorpej   302:
1.25      thorpej   303: extern struct cfdriver sea_cd;
1.1       mycroft   304:
                    305: #ifdef SEA_DEBUGQUEUE
                    306: void
1.65.6.1! skrll     307: sea_queue_length(struct sea_softc *sea)
1.1       mycroft   308: {
                    309:        struct sea_scb *scb;
                    310:        int connected, issued, disconnected;
                    311:
1.3       mycroft   312:        connected = sea->nexus ? 1 : 0;
                    313:        for (scb = sea->ready_list.tqh_first, issued = 0; scb;
1.1       mycroft   314:            scb = scb->chain.tqe_next, issued++);
1.3       mycroft   315:        for (scb = sea->nexus_list.tqh_first, disconnected = 0; scb;
1.1       mycroft   316:            scb = scb->chain.tqe_next, disconnected++);
1.64      cegger    317:        printf("%s: length: %d/%d/%d\n", device_xname(&sea->sc_dev), connected,
1.1       mycroft   318:            issued, disconnected);
                    319: }
                    320: #endif
                    321:
                    322: /*
                    323:  * Check if the device can be found at the port given and if so, detect the
                    324:  * type the type of board.  Set it up ready for further work. Takes the isa_dev
                    325:  * structure from autoconf as an argument.
                    326:  * Returns 1 if card recognized, 0 if errors.
                    327:  */
                    328: int
1.61      christos  329: seaprobe(struct device *parent, struct cfdata *match,
1.60      christos  330:     void *aux)
1.1       mycroft   331: {
                    332:        struct isa_attach_args *ia = aux;
1.26      drochner  333:        int i, type = 0;
1.62      christos  334:        void *maddr;
1.1       mycroft   335:
1.45      thorpej   336:        if (ia->ia_niomem < 1)
                    337:                return (0);
                    338:        if (ia->ia_nirq < 1)
                    339:                return (0);
                    340:
                    341:        if (ISA_DIRECT_CONFIG(ia))
                    342:                return (0);
                    343:
1.55      drochner  344:        if (ia->ia_iomem[0].ir_addr == ISA_UNKNOWN_IOMEM)
1.45      thorpej   345:                return (0);
1.55      drochner  346:        if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ)
1.45      thorpej   347:                return (0);
                    348:
                    349:        /* XXX XXX XXX */
                    350:        maddr = ISA_HOLE_VADDR(ia->ia_iomem[0].ir_addr);
1.1       mycroft   351:
1.26      drochner  352:        /* check board type */  /* No way to define this through config */
                    353:        for (i = 0; i < nsignatures; i++)
1.62      christos  354:                if (!memcmp((char *)maddr + signatures[i].offset,
1.26      drochner  355:                    signatures[i].signature, signatures[i].length)) {
                    356:                        type = signatures[i].type;
                    357:                        break;
                    358:                }
                    359:
                    360:        /* Find controller and data memory addresses */
                    361:        switch (type) {
                    362:        case SEAGATE:
                    363:        case FDOMAIN840:
                    364:        case FDOMAIN:
                    365:                break;
                    366:        default:
1.54      christos  367: #ifdef SEA_DEBUG
1.48      sommerfe  368:                printf("seaprobe: board type unknown at address %p\n", maddr);
1.26      drochner  369: #endif
                    370:                return 0;
                    371:        }
                    372:
1.45      thorpej   373:        ia->ia_niomem = 1;
                    374:        ia->ia_iomem[0].ir_size = 0x2000;
                    375:
                    376:        ia->ia_nirq = 1;
                    377:
                    378:        ia->ia_nio = 0;
                    379:        ia->ia_ndrq = 0;
                    380:
1.26      drochner  381:        return 1;
                    382: }
                    383:
                    384: /*
                    385:  * Attach all sub-devices we can find
                    386:  */
                    387: void
1.61      christos  388: seaattach(struct device *parent, struct device *self, void *aux)
1.26      drochner  389: {
                    390:        struct isa_attach_args *ia = aux;
                    391:        struct sea_softc *sea = (void *)self;
1.40      bouyer    392:        struct scsipi_adapter *adapt = &sea->sc_adapter;
                    393:        struct scsipi_channel *chan = &sea->sc_channel;
1.26      drochner  394:        int i;
                    395:
1.45      thorpej   396:        /* XXX XXX XXX */
                    397:        sea->maddr = ISA_HOLE_VADDR(ia->ia_iomem[0].ir_addr);
1.57      perry     398:
1.1       mycroft   399:        /* check board type */  /* No way to define this through config */
                    400:        for (i = 0; i < nsignatures; i++)
1.62      christos  401:                if (!memcmp((char *)sea->maddr + signatures[i].offset,
1.1       mycroft   402:                    signatures[i].signature, signatures[i].length)) {
                    403:                        sea->type = signatures[i].type;
                    404:                        break;
                    405:                }
                    406:
                    407:        /* Find controller and data memory addresses */
                    408:        switch (sea->type) {
                    409:        case SEAGATE:
1.3       mycroft   410:        case FDOMAIN840:
1.1       mycroft   411:                sea->maddr_cr_sr =
                    412:                    (void *) (((u_char *)sea->maddr) + 0x1a00);
                    413:                sea->maddr_dr =
                    414:                    (void *) (((u_char *)sea->maddr) + 0x1c00);
                    415:                break;
                    416:        case FDOMAIN:
                    417:                sea->maddr_cr_sr =
                    418:                    (void *) (((u_char *)sea->maddr) + 0x1c00);
                    419:                sea->maddr_dr =
                    420:                    (void *) (((u_char *)sea->maddr) + 0x1e00);
                    421:                break;
                    422:        default:
1.22      mikel     423: #ifdef DEBUG
1.48      sommerfe  424:                printf("%s: board type unknown at address %p\n",
1.64      cegger    425:                    device_xname(&sea->sc_dev), sea->maddr);
1.10      mycroft   426: #endif
1.26      drochner  427:                return;
1.1       mycroft   428:        }
                    429:
                    430:        /* Test controller RAM (works the same way on future domain cards?) */
                    431:        *((u_char *)sea->maddr + SEA_RAMOFFSET) = 0xa5;
                    432:        *((u_char *)sea->maddr + SEA_RAMOFFSET + 1) = 0x5a;
                    433:
                    434:        if ((*((u_char *)sea->maddr + SEA_RAMOFFSET) != 0xa5) ||
                    435:            (*((u_char *)sea->maddr + SEA_RAMOFFSET + 1) != 0x5a)) {
1.64      cegger    436:                aprint_error_dev(&sea->sc_dev, "board RAM failure\n");
1.26      drochner  437:                return;
1.1       mycroft   438:        }
                    439:
                    440:        sea_init(sea);
                    441:
                    442:        /*
1.40      bouyer    443:         * Fill in the scsipi_adapter.
1.30      thorpej   444:         */
1.40      bouyer    445:        memset(adapt, 0, sizeof(*adapt));
                    446:        adapt->adapt_dev = &sea->sc_dev;
                    447:        adapt->adapt_nchannels = 1;
                    448:        adapt->adapt_openings = sea->numscbs;
                    449:        adapt->adapt_max_periph = 1;
                    450:        adapt->adapt_request = sea_scsipi_request;
                    451:        adapt->adapt_minphys = minphys;
1.30      thorpej   452:
                    453:        /*
1.40      bouyer    454:         * Fill in the scsipi_channel.
1.1       mycroft   455:         */
1.40      bouyer    456:        memset(chan, 0, sizeof(*chan));
                    457:        chan->chan_adapter = adapt;
                    458:        chan->chan_bustype = &scsi_bustype;
                    459:        chan->chan_channel = 0;
                    460:        chan->chan_ntargets = 8;
                    461:        chan->chan_nluns = 8;
                    462:        chan->chan_id = sea->our_id;
                    463:        chan->chan_flags = SCSIPI_CHAN_CANGROW;
1.57      perry     464:
1.21      christos  465:        printf("\n");
1.1       mycroft   466:
1.45      thorpej   467:        sea->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
                    468:            IST_EDGE, IPL_BIO, seaintr, sea);
1.1       mycroft   469:
                    470:        /*
                    471:         * ask the adapter what subunits are present
                    472:         */
1.40      bouyer    473:        config_found(self, &sea->sc_channel, scsiprint);
1.1       mycroft   474: }
                    475:
                    476: /*
                    477:  * Catch an interrupt from the adaptor
                    478:  */
                    479: int
1.65.6.1! skrll     480: seaintr(void *arg)
1.1       mycroft   481: {
1.8       cgd       482:        struct sea_softc *sea = arg;
1.1       mycroft   483:
                    484: #ifdef DEBUG   /* extra overhead, and only needed for intr debugging */
                    485:        if ((STATUS & STAT_PARITY) == 0 &&
                    486:            (STATUS & (STAT_SEL | STAT_IO)) != (STAT_SEL | STAT_IO))
                    487:                return 0;
                    488: #endif
                    489:
                    490: loop:
                    491:        /* dispatch to appropriate routine if found and done=0 */
                    492:        /* should check to see that this card really caused the interrupt */
                    493:
                    494:        if (STATUS & STAT_PARITY) {
                    495:                /* Parity error interrupt */
1.64      cegger    496:                aprint_error_dev(&sea->sc_dev, "parity error\n");
1.1       mycroft   497:                return 1;
                    498:        }
                    499:
                    500:        if ((STATUS & (STAT_SEL | STAT_IO)) == (STAT_SEL | STAT_IO)) {
                    501:                /* Reselect interrupt */
                    502:                sea_reselect(sea);
                    503:                if (!main_running)
                    504:                        sea_main();
                    505:                goto loop;
                    506:        }
                    507:
                    508:        return 1;
                    509: }
                    510:
                    511: /*
                    512:  * Setup data structures, and reset the board and the SCSI bus.
                    513:  */
                    514: void
1.65.6.1! skrll     515: sea_init(struct sea_softc *sea)
1.1       mycroft   516: {
                    517:        int i;
1.57      perry     518:
1.1       mycroft   519:        /* Reset the scsi bus (I don't know if this is needed */
                    520:        CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_RST;
                    521:        delay(25);      /* hold reset for at least 25 microseconds */
                    522:        CONTROL = BASE_CMD;
                    523:        delay(10);      /* wait a Bus Clear Delay (800 ns + bus free delay (800 ns) */
                    524:
                    525:        /* Set our id (don't know anything about this) */
                    526:        switch (sea->type) {
                    527:        case SEAGATE:
                    528:                sea->our_id = 7;
                    529:                break;
                    530:        case FDOMAIN:
1.3       mycroft   531:        case FDOMAIN840:
1.1       mycroft   532:                sea->our_id = 6;
                    533:                break;
                    534:        }
                    535:        sea->our_id_mask = 1 << sea->our_id;
                    536:
                    537:        /* init fields used by our routines */
1.3       mycroft   538:        sea->nexus = 0;
                    539:        TAILQ_INIT(&sea->ready_list);
                    540:        TAILQ_INIT(&sea->nexus_list);
                    541:        TAILQ_INIT(&sea->free_list);
1.1       mycroft   542:        for (i = 0; i < 8; i++)
                    543:                sea->busy[i] = 0x00;
                    544:
                    545:        /* link up the free list of scbs */
                    546:        sea->numscbs = SCB_TABLE_SIZE;
                    547:        for (i = 0; i < SCB_TABLE_SIZE; i++) {
1.3       mycroft   548:                TAILQ_INSERT_TAIL(&sea->free_list, &sea->scb[i], chain);
1.1       mycroft   549:        }
                    550: }
                    551:
                    552: /*
                    553:  * start a scsi operation given the command and the data address. Also needs
                    554:  * the unit, target and lu.
                    555:  */
1.40      bouyer    556: void
1.65.6.1! skrll     557: sea_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
1.40      bouyer    558: {
1.23      bouyer    559:        struct scsipi_xfer *xs;
1.40      bouyer    560:        struct scsipi_periph *periph;
                    561:        struct sea_softc *sea = (void *)chan->chan_adapter->adapt_dev;
1.1       mycroft   562:        struct sea_scb *scb;
                    563:        int flags;
1.3       mycroft   564:        int s;
1.1       mycroft   565:
1.40      bouyer    566:        switch (req) {
                    567:        case ADAPTER_REQ_RUN_XFER:
                    568:                xs = arg;
                    569:                periph = xs->xs_periph;
                    570:                flags = xs->xs_control;
                    571:
                    572:                SC_DEBUG(periph, SCSIPI_DB2, ("sea_scsipi_requeset\n"));
                    573:
                    574:                /* XXX Reset not implemented. */
                    575:                if (flags & XS_CTL_RESET) {
1.64      cegger    576:                        printf("%s: resetting\n", device_xname(&sea->sc_dev));
1.40      bouyer    577:                        xs->error = XS_DRIVER_STUFFUP;
                    578:                        scsipi_done(xs);
                    579:                        return;
                    580:                }
1.1       mycroft   581:
1.40      bouyer    582:                /* Get an SCB to use. */
                    583:                scb = sea_get_scb(sea, flags);
                    584: #ifdef DIAGNOSTIC
                    585:                /*
                    586:                 * This should never happen as we track the resources
                    587:                 * in the mid-layer.
                    588:                 */
                    589:                if (scb == NULL) {
                    590:                        scsipi_printaddr(periph);
                    591:                        printf("unable to allocate scb\n");
                    592:                        panic("sea_scsipi_request");
                    593:                }
                    594: #endif
                    595:
                    596:                scb->flags = SCB_ACTIVE;
                    597:                scb->xs = xs;
1.1       mycroft   598:
                    599:                /*
1.40      bouyer    600:                 * Put all the arguments for the xfer in the scb
1.1       mycroft   601:                 */
1.40      bouyer    602:                scb->datalen = xs->datalen;
                    603:                scb->data = xs->data;
1.1       mycroft   604:
                    605: #ifdef SEA_DEBUGQUEUE
1.40      bouyer    606:                sea_queue_length(sea);
1.1       mycroft   607: #endif
                    608:
1.40      bouyer    609:                s = splbio();
1.3       mycroft   610:
1.40      bouyer    611:                sea_send_scb(sea, scb);
                    612:
                    613:                if ((flags & XS_CTL_POLL) == 0) {
                    614:                        callout_reset(&scb->xs->xs_callout,
1.49      bouyer    615:                            mstohz(xs->timeout), sea_timeout, scb);
1.40      bouyer    616:                        splx(s);
                    617:                        return;
                    618:                }
1.3       mycroft   619:
1.1       mycroft   620:                splx(s);
                    621:
1.40      bouyer    622:                /*
                    623:                 * If we can't use interrupts, poll on completion
                    624:                 */
                    625:                if (sea_poll(sea, xs, xs->timeout)) {
                    626:                        sea_timeout(scb);
                    627:                        if (sea_poll(sea, xs, 2000))
                    628:                                sea_timeout(scb);
                    629:                }
                    630:                return;
                    631:
                    632:        case ADAPTER_REQ_GROW_RESOURCES:
                    633:                sea_grow_scb(sea);
                    634:                return;
                    635:
                    636:        case ADAPTER_REQ_SET_XFER_MODE:
                    637:            {
                    638:                struct scsipi_xfer_mode *xm = arg;
1.3       mycroft   639:
1.40      bouyer    640:                /*
                    641:                 * We don't support sync or wide or tagged queueing,
                    642:                 * so announce that now.
                    643:                 */
                    644:                xm->xm_mode = 0;
                    645:                xm->xm_period = 0;
                    646:                xm->xm_offset = 0;
                    647:                scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm);
                    648:                return;
                    649:            }
1.3       mycroft   650:        }
1.1       mycroft   651: }
                    652:
                    653: /*
                    654:  * Get a free scb. If there are none, see if we can allocate a new one.  If so,
                    655:  * put it in the hash table too; otherwise return an error or sleep.
                    656:  */
                    657: struct sea_scb *
1.61      christos  658: sea_get_scb(struct sea_softc *sea, int flags)
1.1       mycroft   659: {
                    660:        int s;
                    661:        struct sea_scb *scb;
                    662:
1.3       mycroft   663:        s = splbio();
1.40      bouyer    664:        if ((scb = TAILQ_FIRST(&sea->free_list)) != NULL)
                    665:                TAILQ_REMOVE(&sea->free_list, scb, chain);
                    666:        splx(s);
1.1       mycroft   667:
1.40      bouyer    668:        return (scb);
1.1       mycroft   669: }
                    670:
                    671: /*
                    672:  * Try to send this command to the board. Because this board does not use any
                    673:  * mailboxes, this routine simply adds the command to the queue held by the
                    674:  * sea_softc structure.
                    675:  * A check is done to see if the command contains a REQUEST_SENSE command, and
                    676:  * if so the command is put first in the queue, otherwise the command is added
                    677:  * to the end of the queue. ?? Not correct ??
                    678:  */
                    679: void
1.65.6.1! skrll     680: sea_send_scb(struct sea_softc *sea, struct sea_scb *scb)
1.1       mycroft   681: {
                    682:
1.3       mycroft   683:        TAILQ_INSERT_TAIL(&sea->ready_list, scb, chain);
                    684:        /* Try to do some work on the card. */
1.1       mycroft   685:        if (!main_running)
                    686:                sea_main();
                    687: }
                    688:
                    689: /*
                    690:  * Coroutine that runs as long as more work can be done on the seagate host
                    691:  * adapter in a system.  Both sea_scsi_cmd and sea_intr will try to start it in
                    692:  * case it is not running.
                    693:  */
1.40      bouyer    694:
1.1       mycroft   695: void
1.65.6.1! skrll     696: sea_main(void)
1.1       mycroft   697: {
                    698:        struct sea_softc *sea;
                    699:        struct sea_scb *scb;
                    700:        int done;
                    701:        int unit;
                    702:        int s;
                    703:
                    704:        main_running = 1;
                    705:
                    706:        /*
                    707:         * This should not be run with interrupts disabled, but use the splx
                    708:         * code instead.
                    709:         */
                    710: loop:
                    711:        done = 1;
1.14      thorpej   712:        for (unit = 0; unit < sea_cd.cd_ndevs; unit++) {
1.65      tsutsui   713:                sea = device_lookup_private(&sea_cd, unit);
1.1       mycroft   714:                if (!sea)
                    715:                        continue;
                    716:                s = splbio();
1.3       mycroft   717:                if (!sea->nexus) {
1.1       mycroft   718:                        /*
1.3       mycroft   719:                         * Search through the ready_list for a command
1.1       mycroft   720:                         * destined for a target that's not busy.
                    721:                         */
1.3       mycroft   722:                        for (scb = sea->ready_list.tqh_first; scb;
1.1       mycroft   723:                            scb = scb->chain.tqe_next) {
1.40      bouyer    724:                                if (!(sea->busy[scb->xs->xs_periph->periph_target] &
                    725:                                    (1 << scb->xs->xs_periph->periph_lun))) {
1.3       mycroft   726:                                        TAILQ_REMOVE(&sea->ready_list, scb,
1.1       mycroft   727:                                            chain);
1.57      perry     728:
1.1       mycroft   729:                                        /* Re-enable interrupts. */
                    730:                                        splx(s);
                    731:
                    732:                                        /*
                    733:                                         * Attempt to establish an I_T_L nexus.
1.3       mycroft   734:                                         * On success, sea->nexus is set.
1.1       mycroft   735:                                         * On failure, we must add the command
                    736:                                         * back to the issue queue so we can
                    737:                                         * keep trying.
                    738:                                         */
                    739:
                    740:                                        /*
                    741:                                         * REQUEST_SENSE commands are issued
                    742:                                         * without tagged queueing, even on
                    743:                                         * SCSI-II devices because the
                    744:                                         * contingent alligence condition
                    745:                                         * exists for the entire unit.
                    746:                                         */
                    747:
                    748:                                        /*
                    749:                                         * First check that if any device has
                    750:                                         * tried a reconnect while we have done
                    751:                                         * other things with interrupts
                    752:                                         * disabled.
                    753:                                         */
                    754:
                    755:                                        if ((STATUS & (STAT_SEL | STAT_IO)) ==
                    756:                                            (STAT_SEL | STAT_IO)) {
                    757:                                                sea_reselect(sea);
                    758:                                                break;
                    759:                                        }
                    760:                                        if (sea_select(sea, scb)) {
                    761:                                                s = splbio();
1.3       mycroft   762:                                                TAILQ_INSERT_HEAD(&sea->ready_list,
1.1       mycroft   763:                                                    scb, chain);
                    764:                                                splx(s);
                    765:                                        } else
                    766:                                                break;
                    767:                                } /* if target/lun is not busy */
                    768:                        } /* for scb */
1.3       mycroft   769:                        if (!sea->nexus) {
                    770:                                /* check for reselection phase */
                    771:                                if ((STATUS & (STAT_SEL | STAT_IO)) ==
                    772:                                    (STAT_SEL | STAT_IO)) {
                    773:                                        sea_reselect(sea);
                    774:                                }
                    775:                        }
                    776:                } /* if (!sea->nexus) */
1.57      perry     777:
1.1       mycroft   778:                splx(s);
1.3       mycroft   779:                if (sea->nexus) {       /* we are connected. Do the task */
1.1       mycroft   780:                        sea_information_transfer(sea);
                    781:                        done = 0;
                    782:                } else
                    783:                        break;
                    784:        } /* for instance */
                    785:
                    786:        if (!done)
                    787:                goto loop;
                    788:
                    789:        main_running = 0;
                    790: }
                    791:
1.40      bouyer    792: /*
                    793:  * Allocate an scb and add it to the free list.
                    794:  * We are called at splbio.
                    795:  */
                    796: void
1.65.6.1! skrll     797: sea_grow_scb(struct sea_softc *sea)
1.40      bouyer    798: {
                    799:        struct sea_scb *scb;
                    800:
                    801:        if (sea->numscbs == SEA_SCB_MAX) {
                    802:                sea->sc_channel.chan_flags &= ~SCSIPI_CHAN_CANGROW;
                    803:                return;
                    804:        }
                    805:
1.46      tsutsui   806:        scb = malloc(sizeof(struct sea_scb), M_DEVBUF, M_NOWAIT|M_ZERO);
1.40      bouyer    807:        if (scb == NULL)
                    808:                return;
                    809:
                    810:        TAILQ_INSERT_TAIL(&sea->free_list, scb, chain);
                    811:        sea->numscbs++;
                    812:        sea->sc_adapter.adapt_openings++;
                    813: }
1.1       mycroft   814: void
1.61      christos  815: sea_free_scb(struct sea_softc *sea, struct sea_scb *scb, int flags)
1.1       mycroft   816: {
                    817:        int s;
                    818:
1.3       mycroft   819:        s = splbio();
1.1       mycroft   820:        scb->flags = SCB_FREE;
1.3       mycroft   821:        TAILQ_INSERT_HEAD(&sea->free_list, scb, chain);
                    822:        splx(s);
1.1       mycroft   823: }
                    824:
                    825: void
1.65.6.1! skrll     826: sea_timeout(void *arg)
1.1       mycroft   827: {
                    828:        struct sea_scb *scb = arg;
1.23      bouyer    829:        struct scsipi_xfer *xs = scb->xs;
1.40      bouyer    830:        struct scsipi_periph *periph = xs->xs_periph;
                    831:        struct sea_softc *sea =
                    832:            (void *)periph->periph_channel->chan_adapter->adapt_dev;
1.3       mycroft   833:        int s;
1.1       mycroft   834:
1.40      bouyer    835:        scsipi_printaddr(periph);
1.21      christos  836:        printf("timed out");
1.1       mycroft   837:
1.3       mycroft   838:        s = splbio();
                    839:
1.1       mycroft   840:        /*
                    841:         * If it has been through before, then
                    842:         * a previous abort has failed, don't
                    843:         * try abort again
                    844:         */
                    845:        if (scb->flags & SCB_ABORTED) {
1.3       mycroft   846:                /* abort timed out */
1.21      christos  847:                printf(" AGAIN\n");
1.40      bouyer    848:                scb->xs->xs_retries = 0;
1.1       mycroft   849:                scb->flags |= SCB_ABORTED;
                    850:                sea_done(sea, scb);
                    851:        } else {
1.3       mycroft   852:                /* abort the operation that has timed out */
1.21      christos  853:                printf("\n");
1.3       mycroft   854:                scb->flags |= SCB_ABORTED;
1.1       mycroft   855:                sea_abort(sea, scb);
1.3       mycroft   856:                /* 2 secs for the abort */
1.34      thorpej   857:                if ((xs->xs_control & XS_CTL_POLL) == 0)
1.35      thorpej   858:                        callout_reset(&scb->xs->xs_callout, 2 * hz,
                    859:                            sea_timeout, scb);
1.1       mycroft   860:        }
1.3       mycroft   861:
1.1       mycroft   862:        splx(s);
                    863: }
1.57      perry     864:
1.1       mycroft   865: void
1.65.6.1! skrll     866: sea_reselect(struct sea_softc *sea)
1.1       mycroft   867: {
                    868:        u_char target_mask;
                    869:        int i;
                    870:        u_char lun, phase;
                    871:        u_char msg[3];
1.3       mycroft   872:        int len;
1.1       mycroft   873:        u_char *data;
                    874:        struct sea_scb *scb;
                    875:        int abort = 0;
1.57      perry     876:
1.1       mycroft   877:        if (!((target_mask = STATUS) & STAT_SEL)) {
1.64      cegger    878:                printf("%s: wrong state 0x%x\n", device_xname(&sea->sc_dev),
1.1       mycroft   879:                    target_mask);
                    880:                return;
                    881:        }
                    882:
                    883:        /* wait for a device to win the reselection phase */
                    884:        /* signals this by asserting the I/O signal */
                    885:        for (i = 10; i && (STATUS & (STAT_SEL | STAT_IO | STAT_BSY)) !=
                    886:            (STAT_SEL | STAT_IO | 0); i--);
                    887:        /* !! Check for timeout here */
                    888:        /* the data bus contains original initiator id ORed with target id */
                    889:        target_mask = DATA;
                    890:        /* see that we really are the initiator */
                    891:        if (!(target_mask & sea->our_id_mask)) {
1.21      christos  892:                printf("%s: polled reselection was not for me: 0x%x\n",
1.64      cegger    893:                    device_xname(&sea->sc_dev), target_mask);
1.1       mycroft   894:                return;
                    895:        }
                    896:        /* find target who won */
                    897:        target_mask &= ~sea->our_id_mask;
                    898:        /* host responds by asserting the BSY signal */
                    899:        CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY;
                    900:        /* target should respond by deasserting the SEL signal */
                    901:        for (i = 50000; i && (STATUS & STAT_SEL); i++);
                    902:        /* remove the busy status */
                    903:        CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
                    904:        /* we are connected. Now we wait for the MSGIN condition */
                    905:        for (i = 50000; i && !(STATUS & STAT_REQ); i--);
                    906:        /* !! Add timeout check here */
                    907:        /* hope we get an IDENTIFY message */
                    908:        len = 3;
                    909:        data = msg;
1.3       mycroft   910:        phase = PH_MSGIN;
1.57      perry     911:        sea_transfer_pio(sea, &phase, &len, &data);
1.1       mycroft   912:
1.39      bouyer    913:        if (!MSG_ISIDENTIFY(msg[0])) {
1.21      christos  914:                printf("%s: expecting IDENTIFY message, got 0x%x\n",
1.64      cegger    915:                    device_xname(&sea->sc_dev), msg[0]);
1.1       mycroft   916:                abort = 1;
1.16      christos  917:                scb = NULL;
1.1       mycroft   918:        } else {
                    919:                lun = msg[0] & 0x07;
                    920:
                    921:                /*
                    922:                 * Find the command corresponding to the I_T_L or I_T_L_Q nexus
                    923:                 * we just reestablished, and remove it from the disconnected
                    924:                 * queue.
                    925:                 */
1.3       mycroft   926:                for (scb = sea->nexus_list.tqh_first; scb;
1.1       mycroft   927:                    scb = scb->chain.tqe_next)
1.40      bouyer    928:                        if (target_mask == (1 << scb->xs->xs_periph->periph_target) &&
                    929:                            lun == scb->xs->xs_periph->periph_lun) {
1.3       mycroft   930:                                TAILQ_REMOVE(&sea->nexus_list, scb,
1.1       mycroft   931:                                    chain);
                    932:                                break;
                    933:                        }
                    934:                if (!scb) {
1.21      christos  935:                        printf("%s: target %02x lun %d not disconnected\n",
1.64      cegger    936:                            device_xname(&sea->sc_dev), target_mask, lun);
1.1       mycroft   937:                        /*
                    938:                         * Since we have an established nexus that we can't do
                    939:                         * anything with, we must abort it.
                    940:                         */
                    941:                        abort = 1;
                    942:                }
                    943:        }
                    944:
                    945:        if (abort) {
                    946:                msg[0] = MSG_ABORT;
                    947:                len = 1;
                    948:                data = msg;
1.3       mycroft   949:                phase = PH_MSGOUT;
1.1       mycroft   950:                CONTROL = BASE_CMD | CMD_ATTN;
                    951:                sea_transfer_pio(sea, &phase, &len, &data);
                    952:        } else
1.3       mycroft   953:                sea->nexus = scb;
1.1       mycroft   954:
                    955:        return;
                    956: }
                    957:
                    958: /*
                    959:  * Transfer data in given phase using polled I/O.
                    960:  */
                    961: int
1.65.6.1! skrll     962: sea_transfer_pio(struct sea_softc *sea, u_char *phase, int *count, u_char **data)
1.1       mycroft   963: {
1.36      augustss  964:        u_char p = *phase, tmp;
                    965:        int c = *count;
                    966:        u_char *d = *data;
1.1       mycroft   967:        int timeout;
                    968:
                    969:        do {
                    970:                /*
                    971:                 * Wait for assertion of REQ, after which the phase bits will
                    972:                 * be valid.
                    973:                 */
1.3       mycroft   974:                for (timeout = 0; timeout < 50000; timeout++)
1.1       mycroft   975:                        if ((tmp = STATUS) & STAT_REQ)
                    976:                                break;
                    977:                if (!(tmp & STAT_REQ)) {
1.21      christos  978:                        printf("%s: timeout waiting for STAT_REQ\n",
1.64      cegger    979:                            device_xname(&sea->sc_dev));
1.1       mycroft   980:                        break;
                    981:                }
                    982:
                    983:                /*
                    984:                 * Check for phase mismatch.  Reached if the target decides
                    985:                 * that it has finished the transfer.
                    986:                 */
1.3       mycroft   987:                if (sea->type == FDOMAIN840)
                    988:                        tmp = ((tmp & 0x08) >> 2) |
                    989:                              ((tmp & 0x02) << 2) |
                    990:                               (tmp & 0xf5);
                    991:                if ((tmp & PH_MASK) != p)
1.1       mycroft   992:                        break;
                    993:
                    994:                /* Do actual transfer from SCSI bus to/from memory. */
                    995:                if (!(p & STAT_IO))
                    996:                        DATA = *d;
                    997:                else
                    998:                        *d = DATA;
                    999:                ++d;
                   1000:
                   1001:                /*
                   1002:                 * The SCSI standard suggests that in MSGOUT phase, the
                   1003:                 * initiator should drop ATN on the last byte of the message
                   1004:                 * phase after REQ has been asserted for the handshake but
                   1005:                 * before the initiator raises ACK.
                   1006:                 * Don't know how to accomplish this on the ST01/02.
                   1007:                 */
                   1008:
                   1009: #if 0
                   1010:                /*
                   1011:                 * XXX
                   1012:                 * The st01 code doesn't wait for STAT_REQ to be deasserted.
                   1013:                 * Is this ok?
                   1014:                 */
                   1015:                for (timeout = 0; timeout < 200000L; timeout++)
                   1016:                        if (!(STATUS & STAT_REQ))
                   1017:                                break;
                   1018:                if (STATUS & STAT_REQ)
1.21      christos 1019:                        printf("%s: timeout on wait for !STAT_REQ",
1.64      cegger   1020:                            device_xname(&sea->sc_dev));
1.1       mycroft  1021: #endif
                   1022:        } while (--c);
                   1023:
                   1024:        *count = c;
                   1025:        *data = d;
                   1026:        tmp = STATUS;
                   1027:        if (tmp & STAT_REQ)
1.3       mycroft  1028:                *phase = tmp & PH_MASK;
1.1       mycroft  1029:        else
1.3       mycroft  1030:                *phase = PH_INVALID;
1.1       mycroft  1031:
                   1032:        if (c && (*phase != p))
                   1033:                return -1;
                   1034:        return 0;
                   1035: }
                   1036:
                   1037: /*
                   1038:  * Establish I_T_L or I_T_L_Q nexus for new or existing command including
                   1039:  * ARBITRATION, SELECTION, and initial message out for IDENTIFY and queue
                   1040:  * messages.  Return -1 if selection could not execute for some reason, 0 if
                   1041:  * selection succeded or failed because the target did not respond.
                   1042:  */
                   1043: int
1.65.6.1! skrll    1044: sea_select(struct sea_softc *sea, struct sea_scb *scb)
1.1       mycroft  1045: {
                   1046:        u_char msg[3], phase;
                   1047:        u_char *data;
1.3       mycroft  1048:        int len;
1.1       mycroft  1049:        int timeout;
                   1050:
                   1051:        CONTROL = BASE_CMD;
                   1052:        DATA = sea->our_id_mask;
                   1053:        CONTROL = (BASE_CMD & ~CMD_INTR) | CMD_START_ARB;
                   1054:
                   1055:        /* wait for arbitration to complete */
                   1056:        for (timeout = 0; timeout < 3000000L; timeout++)
                   1057:                if (STATUS & STAT_ARB_CMPL)
                   1058:                        break;
                   1059:        if (!(STATUS & STAT_ARB_CMPL)) {
                   1060:                if (STATUS & STAT_SEL) {
1.64      cegger   1061:                        printf("%s: arbitration lost\n", device_xname(&sea->sc_dev));
1.1       mycroft  1062:                        scb->flags |= SCB_ERROR;
                   1063:                } else {
1.21      christos 1064:                        printf("%s: arbitration timeout\n",
1.64      cegger   1065:                            device_xname(&sea->sc_dev));
1.1       mycroft  1066:                        scb->flags |= SCB_TIMEOUT;
                   1067:                }
                   1068:                CONTROL = BASE_CMD;
                   1069:                return -1;
                   1070:        }
                   1071:
                   1072:        delay(2);
1.40      bouyer   1073:        DATA = (u_char)((1 << scb->xs->xs_periph->periph_target) |
1.23      bouyer   1074:                sea->our_id_mask);
1.1       mycroft  1075:        CONTROL =
                   1076: #ifdef SEA_NOMSGS
                   1077:            (BASE_CMD & ~CMD_INTR) | CMD_DRVR_ENABLE | CMD_SEL;
                   1078: #else
                   1079:            (BASE_CMD & ~CMD_INTR) | CMD_DRVR_ENABLE | CMD_SEL | CMD_ATTN;
                   1080: #endif
1.57      perry    1081:        delay(1);
1.1       mycroft  1082:
                   1083:        /* wait for a bsy from target */
                   1084:        for (timeout = 0; timeout < 2000000L; timeout++)
                   1085:                if (STATUS & STAT_BSY)
                   1086:                        break;
                   1087:        if (!(STATUS & STAT_BSY)) {
                   1088:                /* should return some error to the higher level driver */
                   1089:                CONTROL = BASE_CMD;
                   1090:                scb->flags |= SCB_TIMEOUT;
                   1091:                return 0;
                   1092:        }
                   1093:
                   1094:        /* Try to make the target to take a message from us */
                   1095: #ifdef SEA_NOMSGS
                   1096:        CONTROL = (BASE_CMD & ~CMD_INTR) | CMD_DRVR_ENABLE;
                   1097: #else
                   1098:        CONTROL = (BASE_CMD & ~CMD_INTR) | CMD_DRVR_ENABLE | CMD_ATTN;
                   1099: #endif
                   1100:        delay(1);
1.57      perry    1101:
1.1       mycroft  1102:        /* should start a msg_out phase */
                   1103:        for (timeout = 0; timeout < 2000000L; timeout++)
                   1104:                if (STATUS & STAT_REQ)
                   1105:                        break;
1.3       mycroft  1106:        /* Remove ATN. */
1.1       mycroft  1107:        CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
                   1108:        if (!(STATUS & STAT_REQ)) {
                   1109:                /*
                   1110:                 * This should not be taken as an error, but more like an
                   1111:                 * unsupported feature!  Should set a flag indicating that the
                   1112:                 * target don't support messages, and continue without failure.
                   1113:                 * (THIS IS NOT AN ERROR!)
                   1114:                 */
                   1115:        } else {
1.40      bouyer   1116:                msg[0] = MSG_IDENTIFY(scb->xs->xs_periph->periph_lun, 1);
1.1       mycroft  1117:                len = 1;
                   1118:                data = msg;
1.3       mycroft  1119:                phase = PH_MSGOUT;
1.1       mycroft  1120:                /* Should do test on result of sea_transfer_pio(). */
                   1121:                sea_transfer_pio(sea, &phase, &len, &data);
                   1122:        }
                   1123:        if (!(STATUS & STAT_BSY))
1.21      christos 1124:                printf("%s: after successful arbitrate: no STAT_BSY!\n",
1.64      cegger   1125:                    device_xname(&sea->sc_dev));
1.57      perry    1126:
1.3       mycroft  1127:        sea->nexus = scb;
1.40      bouyer   1128:        sea->busy[scb->xs->xs_periph->periph_target] |=
                   1129:            1 << scb->xs->xs_periph->periph_lun;
1.1       mycroft  1130:        /* This assignment should depend on possibility to send a message to target. */
                   1131:        CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
                   1132:        /* XXX Reset pointer in command? */
                   1133:        return 0;
                   1134: }
                   1135:
                   1136: /*
                   1137:  * Send an abort to the target.  Return 1 success, 0 on failure.
                   1138:  */
                   1139: int
1.65.6.1! skrll    1140: sea_abort(struct sea_softc *sea, struct sea_scb *scb)
1.1       mycroft  1141: {
                   1142:        struct sea_scb *tmp;
                   1143:        u_char msg, phase, *msgptr;
1.3       mycroft  1144:        int len;
1.1       mycroft  1145:
                   1146:        /*
                   1147:         * If the command hasn't been issued yet, we simply remove it from the
                   1148:         * issue queue
                   1149:         * XXX Could avoid this loop.
                   1150:         */
1.3       mycroft  1151:        for (tmp = sea->ready_list.tqh_first; tmp; tmp = tmp->chain.tqe_next)
1.1       mycroft  1152:                if (scb == tmp) {
1.3       mycroft  1153:                        TAILQ_REMOVE(&sea->ready_list, scb, chain);
1.1       mycroft  1154:                        /* XXX Set some type of error result for operation. */
                   1155:                        return 1;
                   1156:                }
                   1157:
                   1158:        /*
                   1159:         * If any commands are connected, we're going to fail the abort and let
                   1160:         * the high level SCSI driver retry at a later time or issue a reset.
                   1161:         */
1.3       mycroft  1162:        if (sea->nexus)
1.1       mycroft  1163:                return 0;
                   1164:
                   1165:        /*
                   1166:         * If the command is currently disconnected from the bus, and there are
                   1167:         * no connected commands, we reconnect the I_T_L or I_T_L_Q nexus
                   1168:         * associated with it, go into message out, and send an abort message.
                   1169:         */
1.3       mycroft  1170:        for (tmp = sea->nexus_list.tqh_first; tmp;
1.1       mycroft  1171:            tmp = tmp->chain.tqe_next)
                   1172:                if (scb == tmp) {
                   1173:                        if (sea_select(sea, scb))
                   1174:                                return 0;
                   1175:
                   1176:                        msg = MSG_ABORT;
                   1177:                        msgptr = &msg;
                   1178:                        len = 1;
1.3       mycroft  1179:                        phase = PH_MSGOUT;
1.1       mycroft  1180:                        CONTROL = BASE_CMD | CMD_ATTN;
                   1181:                        sea_transfer_pio(sea, &phase, &len, &msgptr);
                   1182:
1.3       mycroft  1183:                        for (tmp = sea->nexus_list.tqh_first; tmp;
1.1       mycroft  1184:                            tmp = tmp->chain.tqe_next)
                   1185:                                if (scb == tmp) {
1.3       mycroft  1186:                                        TAILQ_REMOVE(&sea->nexus_list,
1.1       mycroft  1187:                                            scb, chain);
                   1188:                                        /* XXX Set some type of error result
                   1189:                                           for the operation. */
                   1190:                                        return 1;
                   1191:                                }
                   1192:                }
                   1193:
                   1194:        /* Command not found in any queue; race condition? */
                   1195:        return 1;
                   1196: }
                   1197:
                   1198: void
1.65.6.1! skrll    1199: sea_done(struct sea_softc *sea, struct sea_scb *scb)
1.1       mycroft  1200: {
1.23      bouyer   1201:        struct scsipi_xfer *xs = scb->xs;
1.1       mycroft  1202:
1.35      thorpej  1203:        callout_stop(&scb->xs->xs_callout);
1.1       mycroft  1204:
                   1205:        xs->resid = scb->datalen;
                   1206:
1.3       mycroft  1207:        /* XXXX need to get status */
                   1208:        if (scb->flags == SCB_ACTIVE) {
1.1       mycroft  1209:                xs->resid = 0;
                   1210:        } else {
1.3       mycroft  1211:                if (scb->flags & (SCB_TIMEOUT | SCB_ABORTED))
                   1212:                        xs->error = XS_TIMEOUT;
                   1213:                if (scb->flags & SCB_ERROR)
1.1       mycroft  1214:                        xs->error = XS_DRIVER_STUFFUP;
                   1215:        }
1.34      thorpej  1216:        sea_free_scb(sea, scb, xs->xs_control);
1.23      bouyer   1217:        scsipi_done(xs);
1.1       mycroft  1218: }
                   1219:
                   1220: /*
                   1221:  * Wait for completion of command in polled mode.
                   1222:  */
                   1223: int
1.61      christos 1224: sea_poll(struct sea_softc *sea, struct scsipi_xfer *xs, int count)
1.1       mycroft  1225: {
                   1226:        int s;
                   1227:
                   1228:        while (count) {
                   1229:                /* try to do something */
                   1230:                s = splbio();
                   1231:                if (!main_running)
                   1232:                        sea_main();
                   1233:                splx(s);
1.34      thorpej  1234:                if (xs->xs_status & XS_STS_DONE)
1.3       mycroft  1235:                        return 0;
                   1236:                delay(1000);
1.1       mycroft  1237:                count--;
                   1238:        }
1.3       mycroft  1239:        return 1;
1.1       mycroft  1240: }
                   1241:
                   1242: /*
                   1243:  * Do the transfer.  We know we are connected.  Update the flags, and call
                   1244:  * sea_done() when task accomplished.  Dialog controlled by the target.
                   1245:  */
                   1246: void
1.65.6.1! skrll    1247: sea_information_transfer(struct sea_softc *sea)
1.1       mycroft  1248: {
                   1249:        int timeout;
1.3       mycroft  1250:        u_char msgout = MSG_NOOP;
                   1251:        int len;
1.1       mycroft  1252:        int s;
                   1253:        u_char *data;
1.3       mycroft  1254:        u_char phase, tmp, old_phase = PH_INVALID;
                   1255:        struct sea_scb *scb = sea->nexus;
1.1       mycroft  1256:        int loop;
                   1257:
                   1258:        for (timeout = 0; timeout < 10000000L; timeout++) {
                   1259:                tmp = STATUS;
1.3       mycroft  1260:                if (tmp & STAT_PARITY)
1.21      christos 1261:                        printf("%s: parity error detected\n",
1.64      cegger   1262:                            device_xname(&sea->sc_dev));
1.1       mycroft  1263:                if (!(tmp & STAT_BSY)) {
                   1264:                        for (loop = 0; loop < 20; loop++)
                   1265:                                if ((tmp = STATUS) & STAT_BSY)
                   1266:                                        break;
                   1267:                        if (!(tmp & STAT_BSY)) {
1.21      christos 1268:                                printf("%s: !STAT_BSY unit in data transfer!\n",
1.64      cegger   1269:                                    device_xname(&sea->sc_dev));
1.1       mycroft  1270:                                s = splbio();
1.3       mycroft  1271:                                sea->nexus = NULL;
1.1       mycroft  1272:                                scb->flags = SCB_ERROR;
                   1273:                                splx(s);
                   1274:                                sea_done(sea, scb);
                   1275:                                return;
                   1276:                        }
                   1277:                }
                   1278:
                   1279:                /* we only have a valid SCSI phase when REQ is asserted */
                   1280:                if (!(tmp & STAT_REQ))
                   1281:                        continue;
                   1282:
1.3       mycroft  1283:                if (sea->type == FDOMAIN840)
                   1284:                        tmp = ((tmp & 0x08) >> 2) |
                   1285:                              ((tmp & 0x02) << 2) |
                   1286:                               (tmp & 0xf5);
                   1287:                phase = tmp & PH_MASK;
1.1       mycroft  1288:                if (phase != old_phase)
                   1289:                        old_phase = phase;
                   1290:
                   1291:                switch (phase) {
1.3       mycroft  1292:                case PH_DATAOUT:
1.1       mycroft  1293: #ifdef SEA_NODATAOUT
1.21      christos 1294:                        printf("%s: SEA_NODATAOUT set, attempted DATAOUT aborted\n",
1.64      cegger   1295:                            device_xname(&sea->sc_dev));
1.1       mycroft  1296:                        msgout = MSG_ABORT;
                   1297:                        CONTROL = BASE_CMD | CMD_ATTN;
                   1298:                        break;
                   1299: #endif
1.3       mycroft  1300:                case PH_DATAIN:
1.1       mycroft  1301:                        if (!scb->data)
1.21      christos 1302:                                printf("no data address!\n");
1.1       mycroft  1303: #ifdef SEA_BLINDTRANSFER
                   1304:                        if (scb->datalen && !(scb->datalen % BLOCK_SIZE)) {
                   1305:                                while (scb->datalen) {
1.3       mycroft  1306:                                        for (loop = 0; loop < 50000; loop++)
1.1       mycroft  1307:                                                if ((tmp = STATUS) & STAT_REQ)
                   1308:                                                        break;
                   1309:                                        if (!(tmp & STAT_REQ)) {
1.21      christos 1310:                                                printf("%s: timeout waiting for STAT_REQ\n",
1.64      cegger   1311:                                                    device_xname(&sea->sc_dev));
1.1       mycroft  1312:                                                /* XXX Do something? */
                   1313:                                        }
1.3       mycroft  1314:                                        if (sea->type == FDOMAIN840)
                   1315:                                                tmp = ((tmp & 0x08) >> 2) |
                   1316:                                                      ((tmp & 0x02) << 2) |
                   1317:                                                       (tmp & 0xf5);
                   1318:                                        if ((tmp & PH_MASK) != phase)
1.1       mycroft  1319:                                                break;
                   1320:                                        if (!(phase & STAT_IO)) {
                   1321: #ifdef SEA_ASSEMBLER
1.62      christos 1322:                                                void *junk;
1.53      perry    1323:                                                __asm("cld\n\t\
1.1       mycroft  1324:                                                    rep\n\t\
                   1325:                                                    movsl" :
1.37      mycroft  1326:                                                    "=S" (scb->data),
                   1327:                                                    "=c" (len),
                   1328:                                                    "=D" (junk) :
1.1       mycroft  1329:                                                    "0" (scb->data),
1.37      mycroft  1330:                                                    "1" (BLOCK_SIZE >> 2),
                   1331:                                                    "2" (sea->maddr_dr));
1.1       mycroft  1332: #else
1.37      mycroft  1333:                                                for (len = BLOCK_SIZE;
                   1334:                                                    len; len--)
1.1       mycroft  1335:                                                        DATA = *(scb->data++);
                   1336: #endif
                   1337:                                        } else {
                   1338: #ifdef SEA_ASSEMBLER
1.62      christos 1339:                                                void *junk;
1.53      perry    1340:                                                __asm("cld\n\t\
1.1       mycroft  1341:                                                    rep\n\t\
                   1342:                                                    movsl" :
1.37      mycroft  1343:                                                    "=D" (scb->data),
                   1344:                                                    "=c" (len),
                   1345:                                                    "=S" (junk) :
1.1       mycroft  1346:                                                    "0" (scb->data),
1.37      mycroft  1347:                                                    "1" (BLOCK_SIZE >> 2),
                   1348:                                                    "2" (sea->maddr_dr));
1.1       mycroft  1349: #else
1.37      mycroft  1350:                                                for (len = BLOCK_SIZE;
                   1351:                                                    len; len--)
1.1       mycroft  1352:                                                        *(scb->data++) = DATA;
                   1353: #endif
                   1354:                                        }
                   1355:                                        scb->datalen -= BLOCK_SIZE;
                   1356:                                }
                   1357:                        }
1.57      perry    1358: #endif
1.1       mycroft  1359:                        if (scb->datalen)
                   1360:                                sea_transfer_pio(sea, &phase, &scb->datalen,
                   1361:                                    &scb->data);
                   1362:                        break;
1.3       mycroft  1363:                case PH_MSGIN:
1.1       mycroft  1364:                        /* Multibyte messages should not be present here. */
                   1365:                        len = 1;
                   1366:                        data = &tmp;
                   1367:                        sea_transfer_pio(sea, &phase, &len, &data);
                   1368:                        /* scb->MessageIn = tmp; */
                   1369:
                   1370:                        switch (tmp) {
                   1371:                        case MSG_ABORT:
                   1372:                                scb->flags = SCB_ABORTED;
1.21      christos 1373:                                printf("sea: command aborted by target\n");
1.1       mycroft  1374:                                CONTROL = BASE_CMD;
                   1375:                                sea_done(sea, scb);
                   1376:                                return;
1.3       mycroft  1377:                        case MSG_CMDCOMPLETE:
1.1       mycroft  1378:                                s = splbio();
1.3       mycroft  1379:                                sea->nexus = NULL;
1.1       mycroft  1380:                                splx(s);
1.57      perry    1381:                                sea->busy[scb->xs->xs_periph->periph_target] &=
1.40      bouyer   1382:                                    ~(1 << scb->xs->xs_periph->periph_lun);
1.1       mycroft  1383:                                CONTROL = BASE_CMD;
                   1384:                                sea_done(sea, scb);
                   1385:                                return;
                   1386:                        case MSG_MESSAGE_REJECT:
1.41      wiz      1387:                                printf("%s: message_reject received\n",
1.64      cegger   1388:                                    device_xname(&sea->sc_dev));
1.1       mycroft  1389:                                break;
                   1390:                        case MSG_DISCONNECT:
                   1391:                                s = splbio();
1.3       mycroft  1392:                                TAILQ_INSERT_TAIL(&sea->nexus_list,
1.1       mycroft  1393:                                    scb, chain);
1.3       mycroft  1394:                                sea->nexus = NULL;
1.1       mycroft  1395:                                CONTROL = BASE_CMD;
                   1396:                                splx(s);
                   1397:                                return;
1.3       mycroft  1398:                        case MSG_SAVEDATAPOINTER:
                   1399:                        case MSG_RESTOREPOINTERS:
1.1       mycroft  1400:                                /* save/restore of pointers are ignored */
                   1401:                                break;
                   1402:                        default:
                   1403:                                /*
                   1404:                                 * This should be handled in the pio data
                   1405:                                 * transfer phase, as the ATN should be raised
                   1406:                                 * before ACK goes false when rejecting a
                   1407:                                 * message.
                   1408:                                 */
1.21      christos 1409:                                printf("%s: unknown message in: %x\n",
1.64      cegger   1410:                                    device_xname(&sea->sc_dev), tmp);
1.1       mycroft  1411:                                break;
                   1412:                        } /* switch (tmp) */
                   1413:                        break;
1.3       mycroft  1414:                case PH_MSGOUT:
1.1       mycroft  1415:                        len = 1;
                   1416:                        data = &msgout;
                   1417:                        /* sea->last_message = msgout; */
                   1418:                        sea_transfer_pio(sea, &phase, &len, &data);
                   1419:                        if (msgout == MSG_ABORT) {
1.21      christos 1420:                                printf("%s: sent message abort to target\n",
1.64      cegger   1421:                                    device_xname(&sea->sc_dev));
1.1       mycroft  1422:                                s = splbio();
1.57      perry    1423:                                sea->busy[scb->xs->xs_periph->periph_target] &=
1.40      bouyer   1424:                                    ~(1 << scb->xs->xs_periph->periph_lun);
1.3       mycroft  1425:                                sea->nexus = NULL;
1.1       mycroft  1426:                                scb->flags = SCB_ABORTED;
1.57      perry    1427:                                splx(s);
1.1       mycroft  1428:                                /* enable interrupt from scsi */
                   1429:                                sea_done(sea, scb);
                   1430:                                return;
                   1431:                        }
1.3       mycroft  1432:                        msgout = MSG_NOOP;
1.1       mycroft  1433:                        break;
1.3       mycroft  1434:                case PH_CMD:
                   1435:                        len = scb->xs->cmdlen;
                   1436:                        data = (char *) scb->xs->cmd;
1.1       mycroft  1437:                        sea_transfer_pio(sea, &phase, &len, &data);
                   1438:                        break;
1.3       mycroft  1439:                case PH_STAT:
1.1       mycroft  1440:                        len = 1;
                   1441:                        data = &tmp;
                   1442:                        sea_transfer_pio(sea, &phase, &len, &data);
1.3       mycroft  1443:                        scb->xs->status = tmp;
1.1       mycroft  1444:                        break;
                   1445:                default:
1.21      christos 1446:                        printf("sea: unknown phase\n");
1.1       mycroft  1447:                } /* switch (phase) */
                   1448:        } /* for (...) */
                   1449:
                   1450:        /* If we get here we have got a timeout! */
1.64      cegger   1451:        printf("%s: timeout in data transfer\n", device_xname(&sea->sc_dev));
1.1       mycroft  1452:        scb->flags = SCB_TIMEOUT;
                   1453:        /* XXX Should I clear scsi-bus state? */
                   1454:        sea_done(sea, scb);
                   1455: }

CVSweb <webmaster@jp.NetBSD.org>