[BACK]Return to aha1742.c CVS log [TXT][DIR] Up to [local] / sys / dev / eisa

Annotation of sys/dev/eisa/aha1742.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: aha1742.c,v 1.25 2007/05/08 16:03:20 deraadt Exp $    */
                      2: /*     $NetBSD: aha1742.c,v 1.61 1996/05/12 23:40:01 mycroft Exp $     */
                      3:
                      4: /*
                      5:  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed by Charles Hannum.
                     18:  * 4. The name of the author may not be used to endorse or promote products
                     19:  *    derived from this software without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     31:  */
                     32:
                     33: /*
                     34:  * Originally written by Julian Elischer (julian@tfs.com)
                     35:  * for TRW Financial Systems for use under the MACH(2.5) operating system.
                     36:  *
                     37:  * TRW Financial Systems, in accordance with their agreement with Carnegie
                     38:  * Mellon University, makes this software available to CMU to distribute
                     39:  * or use in any manner that they see fit as long as this message is kept with
                     40:  * the software. For this reason TFS also grants any other persons or
                     41:  * organisations permission to use or modify this software.
                     42:  *
                     43:  * TFS supplies this software to be publicly redistributed
                     44:  * on the understanding that TFS is not responsible for the correct
                     45:  * functioning of this software in any circumstances.
                     46:  *
                     47:  * commenced: Sun Sep 27 18:14:01 PDT 1992
                     48:  */
                     49:
                     50: #include <sys/types.h>
                     51: #include <sys/param.h>
                     52: #include <sys/systm.h>
                     53: #include <sys/kernel.h>
                     54: #include <sys/errno.h>
                     55: #include <sys/ioctl.h>
                     56: #include <sys/device.h>
                     57: #include <sys/malloc.h>
                     58: #include <sys/buf.h>
                     59: #include <sys/proc.h>
                     60: #include <sys/user.h>
                     61:
                     62: #include <machine/bus.h>
                     63: #include <machine/intr.h>
                     64:
                     65: #include <dev/eisa/eisareg.h>
                     66: #include <dev/eisa/eisavar.h>
                     67: #include <dev/eisa/eisadevs.h>
                     68:
                     69: #include <scsi/scsi_all.h>
                     70: #include <scsi/scsiconf.h>
                     71:
                     72: #ifndef DDB
                     73: #define Debugger() panic("should call debugger here (aha1742.c)")
                     74: #endif /* ! DDB */
                     75:
                     76: typedef u_long physaddr;
                     77: typedef u_long physlen;
                     78:
                     79: #define KVTOPHYS(x)    kvtop((caddr_t)x)
                     80:
                     81: #define AHB_ECB_MAX    32      /* store up to 32 ECBs at one time */
                     82: #define        ECB_HASH_SIZE   32      /* hash table size for phystokv */
                     83: #define        ECB_HASH_SHIFT  9
                     84: #define ECB_HASH(x)    ((((long)(x))>>ECB_HASH_SHIFT) & (ECB_HASH_SIZE - 1))
                     85:
                     86: #define        AHB_NSEG        33      /* number of dma segments supported */
                     87:
                     88: /*
                     89:  * EISA registers (offset from slot base)
                     90:  */
                     91: #define        EISA_VENDOR             0x0c80  /* vendor ID (2 ports) */
                     92: #define        EISA_MODEL              0x0c82  /* model number (2 ports) */
                     93: #define        EISA_CONTROL            0x0c84
                     94: #define         EISA_RESET             0x04
                     95: #define         EISA_ERROR             0x02
                     96: #define         EISA_ENABLE            0x01
                     97:
                     98: /*
                     99:  * AHA1740 EISA board mode registers (Offset from slot base)
                    100:  */
                    101: #define PORTADDR       0xCC0
                    102: #define         PORTADDR_ENHANCED      0x80
                    103: #define BIOSADDR       0xCC1
                    104: #define        INTDEF          0xCC2
                    105: #define        SCSIDEF         0xCC3
                    106: #define        BUSDEF          0xCC4
                    107: #define        RESV0           0xCC5
                    108: #define        RESV1           0xCC6
                    109: #define        RESV2           0xCC7
                    110: /**** bit definitions for INTDEF ****/
                    111: #define        INT9    0x00
                    112: #define        INT10   0x01
                    113: #define        INT11   0x02
                    114: #define        INT12   0x03
                    115: #define        INT14   0x05
                    116: #define        INT15   0x06
                    117: #define INTHIGH 0x08           /* int high=ACTIVE (else edge) */
                    118: #define        INTEN   0x10
                    119: /**** bit definitions for SCSIDEF ****/
                    120: #define        HSCSIID 0x0F            /* our SCSI ID */
                    121: #define        RSTPWR  0x10            /* reset scsi bus on power up or reset */
                    122: /**** bit definitions for BUSDEF ****/
                    123: #define        B0uS    0x00            /* give up bus immediately */
                    124: #define        B4uS    0x01            /* delay 4uSec. */
                    125: #define        B8uS    0x02
                    126:
                    127: /*
                    128:  * AHA1740 ENHANCED mode mailbox control regs (Offset from slot base)
                    129:  */
                    130: #define MBOXOUT0       0xCD0
                    131: #define MBOXOUT1       0xCD1
                    132: #define MBOXOUT2       0xCD2
                    133: #define MBOXOUT3       0xCD3
                    134:
                    135: #define        ATTN            0xCD4
                    136: #define        G2CNTRL         0xCD5
                    137: #define        G2INTST         0xCD6
                    138: #define G2STAT         0xCD7
                    139:
                    140: #define        MBOXIN0         0xCD8
                    141: #define        MBOXIN1         0xCD9
                    142: #define        MBOXIN2         0xCDA
                    143: #define        MBOXIN3         0xCDB
                    144:
                    145: #define G2STAT2                0xCDC
                    146:
                    147: /*
                    148:  * Bit definitions for the 5 control/status registers
                    149:  */
                    150: #define        ATTN_TARGET             0x0F
                    151: #define        ATTN_OPCODE             0xF0
                    152: #define  OP_IMMED              0x10
                    153: #define          AHB_TARG_RESET        0x80
                    154: #define  OP_START_ECB          0x40
                    155: #define  OP_ABORT_ECB          0x50
                    156:
                    157: #define        G2CNTRL_SET_HOST_READY  0x20
                    158: #define        G2CNTRL_CLEAR_EISA_INT  0x40
                    159: #define        G2CNTRL_HARD_RESET      0x80
                    160:
                    161: #define        G2INTST_TARGET          0x0F
                    162: #define        G2INTST_INT_STAT        0xF0
                    163: #define         AHB_ECB_OK             0x10
                    164: #define         AHB_ECB_RECOVERED      0x50
                    165: #define         AHB_HW_ERR             0x70
                    166: #define         AHB_IMMED_OK           0xA0
                    167: #define         AHB_ECB_ERR            0xC0
                    168: #define         AHB_ASN                0xD0    /* for target mode */
                    169: #define         AHB_IMMED_ERR          0xE0
                    170:
                    171: #define        G2STAT_BUSY             0x01
                    172: #define        G2STAT_INT_PEND         0x02
                    173: #define        G2STAT_MBOX_EMPTY       0x04
                    174:
                    175: #define        G2STAT2_HOST_READY      0x01
                    176:
                    177: struct ahb_dma_seg {
                    178:        physaddr seg_addr;
                    179:        physlen seg_len;
                    180: };
                    181:
                    182: struct ahb_ecb_status {
                    183:        u_short status;
                    184: #define        ST_DON  0x0001
                    185: #define        ST_DU   0x0002
                    186: #define        ST_QF   0x0008
                    187: #define        ST_SC   0x0010
                    188: #define        ST_DO   0x0020
                    189: #define        ST_CH   0x0040
                    190: #define        ST_INT  0x0080
                    191: #define        ST_ASA  0x0100
                    192: #define        ST_SNS  0x0200
                    193: #define        ST_INI  0x0800
                    194: #define        ST_ME   0x1000
                    195: #define        ST_ECA  0x4000
                    196:        u_char  host_stat;
                    197: #define        HS_OK                   0x00
                    198: #define        HS_CMD_ABORTED_HOST     0x04
                    199: #define        HS_CMD_ABORTED_ADAPTER  0x05
                    200: #define        HS_TIMED_OUT            0x11
                    201: #define        HS_HARDWARE_ERR         0x20
                    202: #define        HS_SCSI_RESET_ADAPTER   0x22
                    203: #define        HS_SCSI_RESET_INCOMING  0x23
                    204:        u_char  target_stat;
                    205:        u_long  resid_count;
                    206:        u_long  resid_addr;
                    207:        u_short addit_status;
                    208:        u_char  sense_len;
                    209:        u_char  unused[9];
                    210:        u_char  cdb[6];
                    211: };
                    212:
                    213: struct ahb_ecb {
                    214:        u_char  opcode;
                    215: #define        ECB_SCSI_OP     0x01
                    216:                u_char:4;
                    217:        u_char  options:3;
                    218:                u_char:1;
                    219:        short   opt1;
                    220: #define        ECB_CNE 0x0001
                    221: #define        ECB_DI  0x0080
                    222: #define        ECB_SES 0x0400
                    223: #define        ECB_S_G 0x1000
                    224: #define        ECB_DSB 0x4000
                    225: #define        ECB_ARS 0x8000
                    226:        short   opt2;
                    227: #define        ECB_LUN 0x0007
                    228: #define        ECB_TAG 0x0008
                    229: #define        ECB_TT  0x0030
                    230: #define        ECB_ND  0x0040
                    231: #define        ECB_DAT 0x0100
                    232: #define        ECB_DIR 0x0200
                    233: #define        ECB_ST  0x0400
                    234: #define        ECB_CHK 0x0800
                    235: #define        ECB_REC 0x4000
                    236: #define        ECB_NRB 0x8000
                    237:        u_short unused1;
                    238:        physaddr data_addr;
                    239:        physlen  data_length;
                    240:        physaddr status;
                    241:        physaddr link_addr;
                    242:        short   unused2;
                    243:        short   unused3;
                    244:        physaddr sense_ptr;
                    245:        u_char  req_sense_length;
                    246:        u_char  scsi_cmd_length;
                    247:        short   cksum;
                    248:        struct scsi_generic scsi_cmd;
                    249:        /*-----------------end of hardware supported fields----------------*/
                    250:        TAILQ_ENTRY(ahb_ecb) chain;
                    251:        struct ahb_ecb *nexthash;
                    252:        long hashkey;
                    253:        struct scsi_xfer *xs;   /* the scsi_xfer for this cmd */
                    254:        int flags;
                    255: #define ECB_FREE       0
                    256: #define ECB_ACTIVE     1
                    257: #define ECB_ABORTED    2
                    258: #define ECB_IMMED      4
                    259: #define ECB_IMMED_FAIL 8
                    260:        struct ahb_dma_seg ahb_dma[AHB_NSEG];
                    261:        struct ahb_ecb_status ecb_status;
                    262:        struct scsi_sense_data ecb_sense;
                    263: };
                    264:
                    265: struct ahb_softc {
                    266:        struct device sc_dev;
                    267:        bus_space_tag_t sc_iot;
                    268:        eisa_chipset_tag_t sc_ec;
                    269:
                    270:        bus_space_handle_t sc_ioh;
                    271:        int sc_irq;
                    272:        void *sc_ih;
                    273:
                    274:        struct ahb_ecb *immed_ecb;      /* an outstanding immediete command */
                    275:        struct ahb_ecb *ecbhash[ECB_HASH_SIZE];
                    276:        TAILQ_HEAD(, ahb_ecb) free_ecb;
                    277:        int numecbs;
                    278:        int ahb_scsi_dev;               /* our scsi id */
                    279:        struct scsi_link sc_link;
                    280: };
                    281:
                    282: void ahb_send_mbox(struct ahb_softc *, int, struct ahb_ecb *);
                    283: int ahb_poll(struct ahb_softc *, struct scsi_xfer *, int);
                    284: void ahb_send_immed(struct ahb_softc *, int, u_long);
                    285: int ahbintr(void *);
                    286: void ahb_done(struct ahb_softc *, struct ahb_ecb *);
                    287: void ahb_free_ecb(struct ahb_softc *, struct ahb_ecb *, int);
                    288: struct ahb_ecb *ahb_get_ecb(struct ahb_softc *, int);
                    289: struct ahb_ecb *ahb_ecb_phys_kv(struct ahb_softc *, physaddr);
                    290: int ahb_find(bus_space_tag_t, bus_space_handle_t, struct ahb_softc *);
                    291: void ahb_init(struct ahb_softc *);
                    292: void ahbminphys(struct buf *);
                    293: int ahb_scsi_cmd(struct scsi_xfer *);
                    294: void ahb_timeout(void *);
                    295: void ahb_print_ecb(struct ahb_ecb *);
                    296: void ahb_print_active_ecb(struct ahb_softc *);
                    297: int ahbprint(void *, const char *);
                    298:
                    299: #define        MAX_SLOTS       15
                    300:
                    301: #ifdef AHBDEBUG
                    302: int     ahb_debug = 0;
                    303: #endif /* AHBDEBUG */
                    304: #define AHB_SHOWECBS 0x01
                    305: #define AHB_SHOWINTS 0x02
                    306: #define AHB_SHOWCMDS 0x04
                    307: #define AHB_SHOWMISC 0x08
                    308:
                    309: struct scsi_adapter ahb_switch = {
                    310:        ahb_scsi_cmd,
                    311:        ahbminphys,
                    312:        0,
                    313:        0,
                    314: };
                    315:
                    316: /* the below structure is so we have a default dev struct for our link struct */
                    317: struct scsi_device ahb_dev = {
                    318:        NULL,                   /* Use default error handler */
                    319:        NULL,                   /* have a queue, served by this */
                    320:        NULL,                   /* have no async handler */
                    321:        NULL,                   /* Use default 'done' routine */
                    322: };
                    323:
                    324: int    ahbmatch(struct device *, void *, void *);
                    325: void   ahbattach(struct device *, struct device *, void *);
                    326:
                    327: struct cfattach ahb_ca = {
                    328:        sizeof(struct ahb_softc), ahbmatch, ahbattach
                    329: };
                    330:
                    331: struct cfdriver ahb_cd = {
                    332:        NULL, "ahb", DV_DULL
                    333: };
                    334:
                    335: /*
                    336:  * Function to send a command out through a mailbox
                    337:  */
                    338: void
                    339: ahb_send_mbox(sc, opcode, ecb)
                    340:        struct ahb_softc *sc;
                    341:        int opcode;
                    342:        struct ahb_ecb *ecb;
                    343: {
                    344:        bus_space_tag_t iot = sc->sc_iot;
                    345:        bus_space_handle_t ioh = sc->sc_ioh;
                    346:        int wait = 300; /* 1ms should be enough */
                    347:
                    348:        while (--wait) {
                    349:                if ((bus_space_read_1(iot, ioh, G2STAT) &
                    350:                    (G2STAT_BUSY | G2STAT_MBOX_EMPTY)) == (G2STAT_MBOX_EMPTY))
                    351:                        break;
                    352:                delay(10);
                    353:        }
                    354:        if (!wait) {
                    355:                printf("%s: board not responding\n", sc->sc_dev.dv_xname);
                    356:                Debugger();
                    357:        }
                    358:
                    359:        /* don't know this will work */
                    360:        bus_space_write_4(iot, ioh, MBOXOUT0, KVTOPHYS(ecb));
                    361:        bus_space_write_1(iot, ioh, ATTN, opcode | ecb->xs->sc_link->target);
                    362: }
                    363:
                    364: /*
                    365:  * Function to poll for command completion when in poll mode
                    366:  */
                    367: int
                    368: ahb_poll(sc, xs, count)
                    369:        struct ahb_softc *sc;
                    370:        struct scsi_xfer *xs;
                    371:        int count;
                    372: {                              /* in msec  */
                    373:        bus_space_tag_t iot = sc->sc_iot;
                    374:        bus_space_handle_t ioh = sc->sc_ioh;
                    375:
                    376:        while (count) {
                    377:                /*
                    378:                 * If we had interrupts enabled, would we
                    379:                 * have got an interrupt?
                    380:                 */
                    381:                if (bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND)
                    382:                        ahbintr(sc);
                    383:                if (xs->flags & ITSDONE)
                    384:                        return 0;
                    385:                delay(1000);
                    386:                count--;
                    387:        }
                    388:        return 1;
                    389: }
                    390:
                    391: /*
                    392:  * Function to  send an immediate type command to the adapter
                    393:  */
                    394: void
                    395: ahb_send_immed(sc, target, cmd)
                    396:        struct ahb_softc *sc;
                    397:        int target;
                    398:        u_long cmd;
                    399: {
                    400:        bus_space_tag_t iot = sc->sc_iot;
                    401:        bus_space_handle_t ioh = sc->sc_ioh;
                    402:        int wait = 100; /* 1 ms enough? */
                    403:
                    404:        while (--wait) {
                    405:                if ((bus_space_read_1(iot, ioh, G2STAT) &
                    406:                    (G2STAT_BUSY | G2STAT_MBOX_EMPTY)) == (G2STAT_MBOX_EMPTY))
                    407:                        break;
                    408:                delay(10);
                    409:        }
                    410:        if (!wait) {
                    411:                printf("%s: board not responding\n", sc->sc_dev.dv_xname);
                    412:                Debugger();
                    413:        }
                    414:
                    415:        /* don't know this will work */
                    416:        bus_space_write_4(iot, ioh, MBOXOUT0, cmd);
                    417:        bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_SET_HOST_READY);
                    418:        bus_space_write_1(iot, ioh, ATTN, OP_IMMED | target);
                    419: }
                    420:
                    421: /*
                    422:  * Check the slots looking for a board we recognise
                    423:  * If we find one, note its address (slot) and call
                    424:  * the actual probe routine to check it out.
                    425:  */
                    426: int
                    427: ahbmatch(parent, match, aux)
                    428:        struct device *parent;
                    429:        void *match, *aux;
                    430: {
                    431:        struct eisa_attach_args *ea = aux;
                    432:        bus_space_tag_t iot = ea->ea_iot;
                    433:        bus_space_handle_t ioh;
                    434:        int rv;
                    435:
                    436:        /* must match one of our known ID strings */
                    437:        if (strcmp(ea->ea_idstring, "ADP0000") &&
                    438:            strcmp(ea->ea_idstring, "ADP0001") &&
                    439:            strcmp(ea->ea_idstring, "ADP0002") &&
                    440:            strcmp(ea->ea_idstring, "ADP0400"))
                    441:                return (0);
                    442:
                    443:        if (bus_space_map(iot, EISA_SLOT_ADDR(ea->ea_slot), EISA_SLOT_SIZE, 0,
                    444:            &ioh))
                    445:                return (0);
                    446:
                    447: #ifdef notyet
                    448:        /* This won't compile as-is, anyway. */
                    449:        bus_space_write_1(iot, ioh, EISA_CONTROL, EISA_ENABLE | EISA_RESET);
                    450:        delay(10);
                    451:        bus_space_write_1(iot, ioh, EISA_CONTROL, EISA_ENABLE);
                    452:        /* Wait for reset? */
                    453:        delay(1000);
                    454: #endif
                    455:
                    456:        rv = !ahb_find(iot, ioh, NULL);
                    457:
                    458:        bus_space_unmap(ea->ea_iot, ioh, EISA_SLOT_SIZE);
                    459:
                    460:        return (rv);
                    461: }
                    462:
                    463: int
                    464: ahbprint(aux, name)
                    465:        void *aux;
                    466:        const char *name;
                    467: {
                    468:        return UNCONF;
                    469: }
                    470:
                    471: /*
                    472:  * Attach all the sub-devices we can find
                    473:  */
                    474: void
                    475: ahbattach(parent, self, aux)
                    476:        struct device *parent, *self;
                    477:        void *aux;
                    478: {
                    479:        struct eisa_attach_args *ea = aux;
                    480:        struct ahb_softc *sc = (void *)self;
                    481:        struct scsibus_attach_args saa;
                    482:        bus_space_tag_t iot = ea->ea_iot;
                    483:        bus_space_handle_t ioh;
                    484:        eisa_chipset_tag_t ec = ea->ea_ec;
                    485:        eisa_intr_handle_t ih;
                    486:        const char *model, *intrstr;
                    487:
                    488:        sc->sc_iot = iot;
                    489:        sc->sc_ec = ec;
                    490:
                    491:        if (bus_space_map(iot, EISA_SLOT_ADDR(ea->ea_slot), EISA_SLOT_SIZE, 0,
                    492:            &ioh))
                    493:                panic("ahbattach: could not map I/O addresses");
                    494:        sc->sc_ioh = ioh;
                    495:        if (ahb_find(iot, ioh, sc))
                    496:                panic("ahbattach: ahb_find failed!");
                    497:
                    498:        ahb_init(sc);
                    499:        TAILQ_INIT(&sc->free_ecb);
                    500:
                    501:        /*
                    502:         * fill in the prototype scsi_link.
                    503:         */
                    504:        sc->sc_link.adapter_softc = sc;
                    505:        sc->sc_link.adapter_target = sc->ahb_scsi_dev;
                    506:        sc->sc_link.adapter = &ahb_switch;
                    507:        sc->sc_link.device = &ahb_dev;
                    508:        sc->sc_link.openings = 2;
                    509:
                    510:        if (!strcmp(ea->ea_idstring, "ADP0000"))
                    511:                model = EISA_PRODUCT_ADP0000;
                    512:        else if (!strcmp(ea->ea_idstring, "ADP0001"))
                    513:                model = EISA_PRODUCT_ADP0001;
                    514:        else if (!strcmp(ea->ea_idstring, "ADP0002"))
                    515:                model = EISA_PRODUCT_ADP0002;
                    516:        else if (!strcmp(ea->ea_idstring, "ADP0400"))
                    517:                model = EISA_PRODUCT_ADP0400;
                    518:        else
                    519:                model = "unknown model!";
                    520:        printf(": <%s> ", model);
                    521:
                    522:        if (eisa_intr_map(ec, sc->sc_irq, &ih)) {
                    523:                printf("%s: couldn't map interrupt (%d)\n",
                    524:                    sc->sc_dev.dv_xname, sc->sc_irq);
                    525:                return;
                    526:        }
                    527:        intrstr = eisa_intr_string(ec, ih);
                    528:        sc->sc_ih = eisa_intr_establish(ec, ih, IST_LEVEL, IPL_BIO,
                    529:            ahbintr, sc, sc->sc_dev.dv_xname);
                    530:        if (sc->sc_ih == NULL) {
                    531:                printf("%s: couldn't establish interrupt",
                    532:                    sc->sc_dev.dv_xname);
                    533:                if (intrstr != NULL)
                    534:                        printf(" at %s", intrstr);
                    535:                printf("\n");
                    536:                return;
                    537:        }
                    538:        if (intrstr != NULL)
                    539:                printf("%s\n", intrstr);
                    540:
                    541:        bzero(&saa, sizeof(saa));
                    542:        saa.saa_sc_link = &sc->sc_link;
                    543:
                    544:        /*
                    545:         * ask the adapter what subunits are present
                    546:         */
                    547:        config_found(self, &saa, ahbprint);
                    548: }
                    549:
                    550: /*
                    551:  * Catch an interrupt from the adaptor
                    552:  */
                    553: int
                    554: ahbintr(arg)
                    555:        void *arg;
                    556: {
                    557:        struct ahb_softc *sc = arg;
                    558:        bus_space_tag_t iot = sc->sc_iot;
                    559:        bus_space_handle_t ioh = sc->sc_ioh;
                    560:        struct ahb_ecb *ecb;
                    561:        u_char ahbstat;
                    562:        u_long mboxval;
                    563:
                    564: #ifdef AHBDEBUG
                    565:        printf("%s: ahbintr ", sc->sc_dev.dv_xname);
                    566: #endif /* AHBDEBUG */
                    567:
                    568:        if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) == 0)
                    569:                return 0;
                    570:
                    571:        for (;;) {
                    572:                /*
                    573:                 * First get all the information and then
                    574:                 * acknowledge the interrupt
                    575:                 */
                    576:                ahbstat = bus_space_read_1(iot, ioh, G2INTST);
                    577:                mboxval = bus_space_read_4(iot, ioh, MBOXIN0);
                    578:                bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_CLEAR_EISA_INT);
                    579:
                    580: #ifdef AHBDEBUG
                    581:                printf("status = 0x%x ", ahbstat);
                    582: #endif /*AHBDEBUG */
                    583:
                    584:                /*
                    585:                 * Process the completed operation
                    586:                 */
                    587:                switch (ahbstat & G2INTST_INT_STAT) {
                    588:                case AHB_ECB_OK:
                    589:                case AHB_ECB_RECOVERED:
                    590:                case AHB_ECB_ERR:
                    591:                        ecb = ahb_ecb_phys_kv(sc, mboxval);
                    592:                        if (!ecb) {
                    593:                                printf("%s: BAD ECB RETURNED!\n",
                    594:                                    sc->sc_dev.dv_xname);
                    595:                                continue;       /* whatever it was, it'll timeout */
                    596:                        }
                    597:                        break;
                    598:
                    599:                case AHB_IMMED_ERR:
                    600:                        ecb->flags |= ECB_IMMED_FAIL;
                    601:                case AHB_IMMED_OK:
                    602:                        ecb = sc->immed_ecb;
                    603:                        sc->immed_ecb = 0;
                    604:                        break;
                    605:
                    606:                default:
                    607:                        printf("%s: unexpected interrupt %x\n",
                    608:                            sc->sc_dev.dv_xname, ahbstat);
                    609:                        ecb = 0;
                    610:                        break;
                    611:                }
                    612:                if (ecb) {
                    613: #ifdef AHBDEBUG
                    614:                        if (ahb_debug & AHB_SHOWCMDS)
                    615:                                show_scsi_cmd(ecb->xs);
                    616:                        if ((ahb_debug & AHB_SHOWECBS) && ecb)
                    617:                                printf("<int ecb(%x)>", ecb);
                    618: #endif /*AHBDEBUG */
                    619:                        timeout_del(&ecb->xs->stimeout);
                    620:                        ahb_done(sc, ecb);
                    621:                }
                    622:
                    623:                if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) ==
                    624:                    0)
                    625:                        return 1;
                    626:        }
                    627: }
                    628:
                    629: /*
                    630:  * We have a ecb which has been processed by the adaptor, now we look to see
                    631:  * how the operation went.
                    632:  */
                    633: void
                    634: ahb_done(sc, ecb)
                    635:        struct ahb_softc *sc;
                    636:        struct ahb_ecb *ecb;
                    637: {
                    638:        struct ahb_ecb_status *stat = &ecb->ecb_status;
                    639:        struct scsi_sense_data *s1, *s2;
                    640:        struct scsi_xfer *xs = ecb->xs;
                    641:
                    642:        SC_DEBUG(xs->sc_link, SDEV_DB2, ("ahb_done\n"));
                    643:        /*
                    644:         * Otherwise, put the results of the operation
                    645:         * into the xfer and call whoever started it
                    646:         */
                    647:        if (ecb->flags & ECB_IMMED) {
                    648:                if (ecb->flags & ECB_IMMED_FAIL)
                    649:                        xs->error = XS_DRIVER_STUFFUP;
                    650:                goto done;
                    651:        }
                    652:        if (xs->error == XS_NOERROR) {
                    653:                if (stat->host_stat != HS_OK) {
                    654:                        switch (stat->host_stat) {
                    655:                        case HS_SCSI_RESET_ADAPTER:
                    656:                                break;
                    657:                        case HS_SCSI_RESET_INCOMING:
                    658:                                break;
                    659:                        case HS_CMD_ABORTED_HOST:
                    660:                        case HS_CMD_ABORTED_ADAPTER:
                    661:                                xs->error = XS_DRIVER_STUFFUP;
                    662:                                break;
                    663:                        case HS_TIMED_OUT:      /* No response */
                    664:                                xs->error = XS_SELTIMEOUT;
                    665:                                break;
                    666:                        default:        /* Other scsi protocol messes */
                    667:                                printf("%s: host_stat %x\n",
                    668:                                    sc->sc_dev.dv_xname, stat->host_stat);
                    669:                                xs->error = XS_DRIVER_STUFFUP;
                    670:                        }
                    671:                } else if (stat->target_stat != SCSI_OK) {
                    672:                        switch (stat->target_stat) {
                    673:                        case SCSI_CHECK:
                    674:                                s1 = &ecb->ecb_sense;
                    675:                                s2 = &xs->sense;
                    676:                                *s2 = *s1;
                    677:                                xs->error = XS_SENSE;
                    678:                                break;
                    679:                        case SCSI_BUSY:
                    680:                                xs->error = XS_BUSY;
                    681:                                break;
                    682:                        default:
                    683:                                printf("%s: target_stat %x\n",
                    684:                                    sc->sc_dev.dv_xname, stat->target_stat);
                    685:                                xs->error = XS_DRIVER_STUFFUP;
                    686:                        }
                    687:                } else
                    688:                        xs->resid = 0;
                    689:        }
                    690: done:
                    691:        xs->flags |= ITSDONE;
                    692:        ahb_free_ecb(sc, ecb, xs->flags);
                    693:        scsi_done(xs);
                    694: }
                    695:
                    696: /*
                    697:  * A ecb (and hence a mbx-out is put onto the
                    698:  * free list.
                    699:  */
                    700: void
                    701: ahb_free_ecb(sc, ecb, flags)
                    702:        struct ahb_softc *sc;
                    703:        struct ahb_ecb *ecb;
                    704:        int flags;
                    705: {
                    706:        int s;
                    707:
                    708:        s = splbio();
                    709:
                    710:        ecb->flags = ECB_FREE;
                    711:        TAILQ_INSERT_HEAD(&sc->free_ecb, ecb, chain);
                    712:
                    713:        /*
                    714:         * If there were none, wake anybody waiting for one to come free,
                    715:         * starting with queued entries.
                    716:         */
                    717:        if (TAILQ_NEXT(ecb, chain) == NULL)
                    718:                wakeup(&sc->free_ecb);
                    719:
                    720:        splx(s);
                    721: }
                    722:
                    723: static inline void ahb_init_ecb(struct ahb_softc *, struct ahb_ecb *);
                    724:
                    725: static inline void
                    726: ahb_init_ecb(sc, ecb)
                    727:        struct ahb_softc *sc;
                    728:        struct ahb_ecb *ecb;
                    729: {
                    730:        int hashnum;
                    731:
                    732:        bzero(ecb, sizeof(struct ahb_ecb));
                    733:        /*
                    734:         * put in the phystokv hash table
                    735:         * Never gets taken out.
                    736:         */
                    737:        ecb->hashkey = KVTOPHYS(ecb);
                    738:        hashnum = ECB_HASH(ecb->hashkey);
                    739:        ecb->nexthash = sc->ecbhash[hashnum];
                    740:        sc->ecbhash[hashnum] = ecb;
                    741: }
                    742:
                    743: static inline void ahb_reset_ecb(struct ahb_softc *, struct ahb_ecb *);
                    744:
                    745: static inline void
                    746: ahb_reset_ecb(sc, ecb)
                    747:        struct ahb_softc *sc;
                    748:        struct ahb_ecb *ecb;
                    749: {
                    750:
                    751: }
                    752:
                    753: /*
                    754:  * Get a free ecb
                    755:  *
                    756:  * If there are none, see if we can allocate a new one. If so, put it in the
                    757:  * hash table too otherwise either return an error or sleep.
                    758:  */
                    759: struct ahb_ecb *
                    760: ahb_get_ecb(sc, flags)
                    761:        struct ahb_softc *sc;
                    762:        int flags;
                    763: {
                    764:        struct ahb_ecb *ecb;
                    765:        int s;
                    766:
                    767:        s = splbio();
                    768:
                    769:        /*
                    770:         * If we can and have to, sleep waiting for one to come free
                    771:         * but only if we can't allocate a new one.
                    772:         */
                    773:        for (;;) {
                    774:                ecb = TAILQ_FIRST(&sc->free_ecb);
                    775:                if (ecb) {
                    776:                        TAILQ_REMOVE(&sc->free_ecb, ecb, chain);
                    777:                        break;
                    778:                }
                    779:                if (sc->numecbs < AHB_ECB_MAX) {
                    780:                        ecb = (struct ahb_ecb *) malloc(sizeof(struct ahb_ecb),
                    781:                            M_TEMP, M_NOWAIT);
                    782:                        if (ecb) {
                    783:                                ahb_init_ecb(sc, ecb);
                    784:                                sc->numecbs++;
                    785:                        } else {
                    786:                                printf("%s: can't malloc ecb\n",
                    787:                                    sc->sc_dev.dv_xname);
                    788:                                goto out;
                    789:                        }
                    790:                        break;
                    791:                }
                    792:                if ((flags & SCSI_NOSLEEP) != 0)
                    793:                        goto out;
                    794:                tsleep(&sc->free_ecb, PRIBIO, "ahbecb", 0);
                    795:        }
                    796:
                    797:        ahb_reset_ecb(sc, ecb);
                    798:        ecb->flags = ECB_ACTIVE;
                    799:
                    800: out:
                    801:        splx(s);
                    802:        return ecb;
                    803: }
                    804:
                    805: /*
                    806:  * given a physical address, find the ecb that it corresponds to.
                    807:  */
                    808: struct ahb_ecb *
                    809: ahb_ecb_phys_kv(sc, ecb_phys)
                    810:        struct ahb_softc *sc;
                    811:        physaddr ecb_phys;
                    812: {
                    813:        int hashnum = ECB_HASH(ecb_phys);
                    814:        struct ahb_ecb *ecb = sc->ecbhash[hashnum];
                    815:
                    816:        while (ecb) {
                    817:                if (ecb->hashkey == ecb_phys)
                    818:                        break;
                    819:                ecb = ecb->nexthash;
                    820:        }
                    821:        return ecb;
                    822: }
                    823:
                    824: /*
                    825:  * Start the board, ready for normal operation
                    826:  */
                    827: int
                    828: ahb_find(iot, ioh, sc)
                    829:        bus_space_tag_t iot;
                    830:        bus_space_handle_t ioh;
                    831:        struct ahb_softc *sc;
                    832: {
                    833:        u_char intdef;
                    834:        int i, irq, busid;
                    835:        int wait = 1000;        /* 1 sec enough? */
                    836:
                    837:        bus_space_write_1(iot, ioh, PORTADDR, PORTADDR_ENHANCED);
                    838:
                    839: #define        NO_NO 1
                    840: #ifdef NO_NO
                    841:        /*
                    842:         * reset board, If it doesn't respond, assume
                    843:         * that it's not there.. good for the probe
                    844:         */
                    845:        bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_HARD_RESET);
                    846:        delay(1000);
                    847:        bus_space_write_1(iot, ioh, G2CNTRL, 0);
                    848:        delay(10000);
                    849:        while (--wait) {
                    850:                if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_BUSY) == 0)
                    851:                        break;
                    852:                delay(1000);
                    853:        }
                    854:        if (!wait) {
                    855: #ifdef AHBDEBUG
                    856:                if (ahb_debug & AHB_SHOWMISC)
                    857:                        printf("ahb_find: No answer from aha1742 board\n");
                    858: #endif /*AHBDEBUG */
                    859:                return ENXIO;
                    860:        }
                    861:        i = bus_space_read_1(iot, ioh, MBOXIN0);
                    862:        if (i) {
                    863:                printf("self test failed, val = 0x%x\n", i);
                    864:                return EIO;
                    865:        }
                    866:
                    867:        /* Set it again, just to be sure. */
                    868:        bus_space_write_1(iot, ioh, PORTADDR, PORTADDR_ENHANCED);
                    869: #endif
                    870:
                    871:        while (bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) {
                    872:                printf(".");
                    873:                bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_CLEAR_EISA_INT);
                    874:                delay(10000);
                    875:        }
                    876:
                    877:        intdef = bus_space_read_1(iot, ioh, INTDEF);
                    878:        switch (intdef & 0x07) {
                    879:        case INT9:
                    880:                irq = 9;
                    881:                break;
                    882:        case INT10:
                    883:                irq = 10;
                    884:                break;
                    885:        case INT11:
                    886:                irq = 11;
                    887:                break;
                    888:        case INT12:
                    889:                irq = 12;
                    890:                break;
                    891:        case INT14:
                    892:                irq = 14;
                    893:                break;
                    894:        case INT15:
                    895:                irq = 15;
                    896:                break;
                    897:        default:
                    898:                printf("illegal int setting %x\n", intdef);
                    899:                return EIO;
                    900:        }
                    901:
                    902:        /* make sure we can interrupt */
                    903:        bus_space_write_1(iot, ioh, INTDEF, (intdef | INTEN));
                    904:
                    905:        /* who are we on the scsi bus? */
                    906:        busid = (bus_space_read_1(iot, ioh, SCSIDEF) & HSCSIID);
                    907:
                    908:        /* if we want to fill in softc, do so now */
                    909:        if (sc != NULL) {
                    910:                sc->sc_irq = irq;
                    911:                sc->ahb_scsi_dev = busid;
                    912:        }
                    913:
                    914:        /*
                    915:         * Note that we are going and return (to probe)
                    916:         */
                    917:        return 0;
                    918: }
                    919:
                    920: void
                    921: ahb_init(sc)
                    922:        struct ahb_softc *sc;
                    923: {
                    924:
                    925: }
                    926:
                    927: void
                    928: ahbminphys(bp)
                    929:        struct buf *bp;
                    930: {
                    931:
                    932:        if (bp->b_bcount > ((AHB_NSEG - 1) << PGSHIFT))
                    933:                bp->b_bcount = ((AHB_NSEG - 1) << PGSHIFT);
                    934:        minphys(bp);
                    935: }
                    936:
                    937: /*
                    938:  * start a scsi operation given the command and the data address.  Also needs
                    939:  * the unit, target and lu.
                    940:  */
                    941: int
                    942: ahb_scsi_cmd(xs)
                    943:        struct scsi_xfer *xs;
                    944: {
                    945:        struct scsi_link *sc_link = xs->sc_link;
                    946:        struct ahb_softc *sc = sc_link->adapter_softc;
                    947:        struct ahb_ecb *ecb;
                    948:        struct ahb_dma_seg *sg;
                    949:        int seg;                /* scatter gather seg being worked on */
                    950:        u_long thiskv, thisphys, nextphys;
                    951:        int bytes_this_seg, bytes_this_page, datalen, flags;
                    952: #ifdef TFS
                    953:        struct iovec *iovp;
                    954: #endif
                    955:        int s;
                    956:
                    957:        SC_DEBUG(sc_link, SDEV_DB2, ("ahb_scsi_cmd\n"));
                    958:        /*
                    959:         * get a ecb (mbox-out) to use. If the transfer
                    960:         * is from a buf (possibly from interrupt time)
                    961:         * then we can't allow it to sleep
                    962:         */
                    963:        flags = xs->flags;
                    964:        if (flags & ITSDONE) {
                    965:                printf("%s: done?\n", sc->sc_dev.dv_xname);
                    966:                xs->flags &= ~ITSDONE;
                    967:        }
                    968:        if ((ecb = ahb_get_ecb(sc, flags)) == NULL) {
                    969:                return TRY_AGAIN_LATER;
                    970:        }
                    971:        ecb->xs = xs;
                    972:        timeout_set(&ecb->xs->stimeout, ahb_timeout, ecb);
                    973:
                    974:        /*
                    975:         * If it's a reset, we need to do an 'immediate'
                    976:         * command, and store its ecb for later
                    977:         * if there is already an immediate waiting,
                    978:         * then WE must wait
                    979:         */
                    980:        if (flags & SCSI_RESET) {
                    981:                ecb->flags |= ECB_IMMED;
                    982:                if (sc->immed_ecb)
                    983:                        return TRY_AGAIN_LATER;
                    984:                sc->immed_ecb = ecb;
                    985:
                    986:                s = splbio();
                    987:
                    988:                ahb_send_immed(sc, sc_link->target, AHB_TARG_RESET);
                    989:
                    990:                if ((flags & SCSI_POLL) == 0) {
                    991:                        splx(s);
                    992:                        timeout_add(&ecb->xs->stimeout, (xs->timeout * hz) / 1000);
                    993:                        return SUCCESSFULLY_QUEUED;
                    994:                }
                    995:
                    996:                splx(s);
                    997:
                    998:                /*
                    999:                 * If we can't use interrupts, poll on completion
                   1000:                 */
                   1001:                if (ahb_poll(sc, xs, xs->timeout))
                   1002:                        ahb_timeout(ecb);
                   1003:                return COMPLETE;
                   1004:        }
                   1005:
                   1006:        /*
                   1007:         * Put all the arguments for the xfer in the ecb
                   1008:         */
                   1009:        ecb->opcode = ECB_SCSI_OP;
                   1010:        ecb->opt1 = ECB_SES | ECB_DSB | ECB_ARS;
                   1011:        if (xs->datalen)
                   1012:                ecb->opt1 |= ECB_S_G;
                   1013:        ecb->opt2 = sc_link->lun | ECB_NRB;
                   1014:        ecb->scsi_cmd_length = xs->cmdlen;
                   1015:        ecb->sense_ptr = KVTOPHYS(&ecb->ecb_sense);
                   1016:        ecb->req_sense_length = sizeof(ecb->ecb_sense);
                   1017:        ecb->status = KVTOPHYS(&ecb->ecb_status);
                   1018:        ecb->ecb_status.host_stat = 0x00;
                   1019:        ecb->ecb_status.target_stat = 0x00;
                   1020:
                   1021:        if (xs->datalen && (flags & SCSI_RESET) == 0) {
                   1022:                ecb->data_addr = KVTOPHYS(ecb->ahb_dma);
                   1023:                sg = ecb->ahb_dma;
                   1024:                seg = 0;
                   1025: #ifdef TFS
                   1026:                if (flags & SCSI_DATA_UIO) {
                   1027:                        iovp = ((struct uio *) xs->data)->uio_iov;
                   1028:                        datalen = ((struct uio *) xs->data)->uio_iovcnt;
                   1029:                        xs->datalen = 0;
                   1030:                        while (datalen && seg < AHB_NSEG) {
                   1031:                                sg->seg_addr = (physaddr)iovp->iov_base;
                   1032:                                sg->seg_len = iovp->iov_len;
                   1033:                                xs->datalen += iovp->iov_len;
                   1034:                                SC_DEBUGN(sc_link, SDEV_DB4, ("(0x%x@0x%x)",
                   1035:                                    iovp->iov_len, iovp->iov_base));
                   1036:                                sg++;
                   1037:                                iovp++;
                   1038:                                seg++;
                   1039:                                datalen--;
                   1040:                        }
                   1041:                }
                   1042:                else
                   1043: #endif /*TFS */
                   1044:                {
                   1045:                        /*
                   1046:                         * Set up the scatter gather block
                   1047:                         */
                   1048:                        SC_DEBUG(sc_link, SDEV_DB4,
                   1049:                            ("%d @0x%x:- ", xs->datalen, xs->data));
                   1050:                        datalen = xs->datalen;
                   1051:                        thiskv = (long) xs->data;
                   1052:                        thisphys = KVTOPHYS(thiskv);
                   1053:
                   1054:                        while (datalen && seg < AHB_NSEG) {
                   1055:                                bytes_this_seg = 0;
                   1056:
                   1057:                                /* put in the base address */
                   1058:                                sg->seg_addr = thisphys;
                   1059:
                   1060:                                SC_DEBUGN(sc_link, SDEV_DB4, ("0x%x", thisphys));
                   1061:
                   1062:                                /* do it at least once */
                   1063:                                nextphys = thisphys;
                   1064:                                while (datalen && thisphys == nextphys) {
                   1065:                                        /*
                   1066:                                         * This page is contiguous (physically)
                   1067:                                         * with the last, just extend the
                   1068:                                         * length
                   1069:                                         */
                   1070:                                        /* how far to the end of the page */
                   1071:                                        nextphys = (thisphys & ~PGOFSET) + NBPG;
                   1072:                                        bytes_this_page = nextphys - thisphys;
                   1073:                                        /**** or the data ****/
                   1074:                                        bytes_this_page = min(bytes_this_page,
                   1075:                                                              datalen);
                   1076:                                        bytes_this_seg += bytes_this_page;
                   1077:                                        datalen -= bytes_this_page;
                   1078:
                   1079:                                        /* get more ready for the next page */
                   1080:                                        thiskv = (thiskv & ~PGOFSET) + NBPG;
                   1081:                                        if (datalen)
                   1082:                                                thisphys = KVTOPHYS(thiskv);
                   1083:                                }
                   1084:                                /*
                   1085:                                 * next page isn't contiguous, finish the seg
                   1086:                                 */
                   1087:                                SC_DEBUGN(sc_link, SDEV_DB4,
                   1088:                                    ("(0x%x)", bytes_this_seg));
                   1089:                                sg->seg_len = bytes_this_seg;
                   1090:                                sg++;
                   1091:                                seg++;
                   1092:                        }
                   1093:                }
                   1094:                /*end of iov/kv decision */
                   1095:                ecb->data_length = seg * sizeof(struct ahb_dma_seg);
                   1096:                SC_DEBUGN(sc_link, SDEV_DB4, ("\n"));
                   1097:                if (datalen) {
                   1098:                        /*
                   1099:                         * there's still data, must have run out of segs!
                   1100:                         */
                   1101:                        printf("%s: ahb_scsi_cmd, more than %d dma segs\n",
                   1102:                            sc->sc_dev.dv_xname, AHB_NSEG);
                   1103:                        xs->error = XS_DRIVER_STUFFUP;
                   1104:                        ahb_free_ecb(sc, ecb, flags);
                   1105:                        return COMPLETE;
                   1106:                }
                   1107:        } else {        /* No data xfer, use non S/G values */
                   1108:                ecb->data_addr = (physaddr)0;
                   1109:                ecb->data_length = 0;
                   1110:        }
                   1111:        ecb->link_addr = (physaddr)0;
                   1112:
                   1113:        /*
                   1114:         * Put the scsi command in the ecb and start it
                   1115:         */
                   1116:        if ((flags & SCSI_RESET) == 0)
                   1117:                bcopy(xs->cmd, &ecb->scsi_cmd, ecb->scsi_cmd_length);
                   1118:
                   1119:        s = splbio();
                   1120:
                   1121:        ahb_send_mbox(sc, OP_START_ECB, ecb);
                   1122:
                   1123:        /*
                   1124:         * Usually return SUCCESSFULLY QUEUED
                   1125:         */
                   1126:        if ((flags & SCSI_POLL) == 0) {
                   1127:                splx(s);
                   1128:                timeout_add(&ecb->xs->stimeout, (xs->timeout * hz) / 1000);
                   1129:                return SUCCESSFULLY_QUEUED;
                   1130:        }
                   1131:
                   1132:        splx(s);
                   1133:
                   1134:        /*
                   1135:         * If we can't use interrupts, poll on completion
                   1136:         */
                   1137:        if (ahb_poll(sc, xs, xs->timeout)) {
                   1138:                ahb_timeout(ecb);
                   1139:                if (ahb_poll(sc, xs, 2000))
                   1140:                        ahb_timeout(ecb);
                   1141:        }
                   1142:        return COMPLETE;
                   1143: }
                   1144:
                   1145: void
                   1146: ahb_timeout(arg)
                   1147:        void *arg;
                   1148: {
                   1149:        struct ahb_ecb *ecb = arg;
                   1150:        struct scsi_xfer *xs = ecb->xs;
                   1151:        struct scsi_link *sc_link = xs->sc_link;
                   1152:        struct ahb_softc *sc = sc_link->adapter_softc;
                   1153:        int s;
                   1154:
                   1155:        sc_print_addr(sc_link);
                   1156:        printf("timed out");
                   1157:
                   1158:        s = splbio();
                   1159:
                   1160:        if (ecb->flags & ECB_IMMED) {
                   1161:                printf("\n");
                   1162:                ecb->xs->retries = 0;   /* I MEAN IT ! */
                   1163:                ecb->flags |= ECB_IMMED_FAIL;
                   1164:                ahb_done(sc, ecb);
                   1165:                splx(s);
                   1166:                return;
                   1167:        }
                   1168:
                   1169:        /*
                   1170:         * If it has been through before, then
                   1171:         * a previous abort has failed, don't
                   1172:         * try abort again
                   1173:         */
                   1174:        if (ecb->flags == ECB_ABORTED) {
                   1175:                /* abort timed out */
                   1176:                printf(" AGAIN\n");
                   1177:                ecb->xs->retries = 0;   /* I MEAN IT ! */
                   1178:                ahb_done(sc, ecb);
                   1179:        } else {
                   1180:                /* abort the operation that has timed out */
                   1181:                printf("\n");
                   1182:                ecb->xs->error = XS_TIMEOUT;
                   1183:                ecb->flags = ECB_ABORTED;
                   1184:                ahb_send_mbox(sc, OP_ABORT_ECB, ecb);
                   1185:                /* 2 secs for the abort */
                   1186:                if ((xs->flags & SCSI_POLL) == 0)
                   1187:                        timeout_add(&ecb->xs->stimeout, 2 * hz);
                   1188:        }
                   1189:
                   1190:        splx(s);
                   1191: }
                   1192:
                   1193: #ifdef AHBDEBUG
                   1194: void
                   1195: ahb_print_ecb(ecb)
                   1196:        struct ahb_ecb *ecb;
                   1197: {
                   1198:        printf("ecb:%x op:%x cmdlen:%d senlen:%d\n",
                   1199:                ecb, ecb->opcode, ecb->cdblen, ecb->senselen);
                   1200:        printf("        datlen:%d hstat:%x tstat:%x flags:%x\n",
                   1201:                ecb->datalen, ecb->ecb_status.host_stat,
                   1202:                ecb->ecb_status.target_stat, ecb->flags);
                   1203:        show_scsi_cmd(ecb->xs);
                   1204: }
                   1205:
                   1206: void
                   1207: ahb_print_active_ecb(sc)
                   1208:        struct ahb_softc *sc;
                   1209: {
                   1210:        struct ahb_ecb *ecb;
                   1211:        int i = 0;
                   1212:
                   1213:        while (i++ < ECB_HASH_SIZE) {
                   1214:                ecb = sc->ecb_hash_list[i];
                   1215:                while (ecb) {
                   1216:                        if (ecb->flags != ECB_FREE)
                   1217:                                ahb_print_ecb(ecb);
                   1218:                        ecb = ecb->hash_list;
                   1219:                }
                   1220:        }
                   1221: }
                   1222: #endif /* AHBDEBUG */

CVSweb