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

Annotation of sys/dev/ic/dpt.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: dpt.c,v 1.12 2007/04/10 17:47:55 miod Exp $   */
                      2: /*     $NetBSD: dpt.c,v 1.12 1999/10/23 16:26:33 ad Exp $      */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Andy Doran, Charles M. Hannum and by Jason R. Thorpe of the Numerical
                     10:  * Aerospace Simulation Facility, NASA Ames Research Center.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *     This product includes software developed by the NetBSD
                     23:  *     Foundation, Inc. and its contributors.
                     24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     25:  *    contributors may be used to endorse or promote products derived
                     26:  *    from this software without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     38:  * POSSIBILITY OF SUCH DAMAGE.
                     39:  */
                     40:
                     41: /*
                     42:  * Portions of this code fall under the following copyright:
                     43:  *
                     44:  * Originally written by Julian Elischer (julian@tfs.com)
                     45:  * for TRW Financial Systems for use under the MACH(2.5) operating system.
                     46:  *
                     47:  * TRW Financial Systems, in accordance with their agreement with Carnegie
                     48:  * Mellon University, makes this software available to CMU to distribute
                     49:  * or use in any manner that they see fit as long as this message is kept with
                     50:  * the software. For this reason TFS also grants any other persons or
                     51:  * organisations permission to use or modify this software.
                     52:  *
                     53:  * TFS supplies this software to be publicly redistributed
                     54:  * on the understanding that TFS is not responsible for the correct
                     55:  * functioning of this software in any circumstances.
                     56:  */
                     57:
                     58: /*
                     59:  * Driver for DPT EATA SCSI adapters.
                     60:  *
                     61:  * TODO:
                     62:  *
                     63:  * o Need a front-end for (newer) ISA boards.
                     64:  * o Handle older firmware better.
                     65:  * o Find a bunch of different firmware EEPROMs and try them out.
                     66:  * o Test with a bunch of different boards.
                     67:  * o dpt_readcfg() should not be using CP_PIO_GETCFG.
                     68:  * o An interface to userland applications.
                     69:  * o Some sysctls or a utility (eg dptctl(8)) to control parameters.
                     70:  */
                     71:
                     72: #include <sys/cdefs.h>
                     73: #ifdef __NetBSD__
                     74: __KERNEL_RCSID(0, "$NetBSD: dpt.c,v 1.12 1999/10/23 16:26:33 ad Exp $");
                     75: #endif /* __NetBSD__ */
                     76:
                     77: #include <sys/param.h>
                     78: #include <sys/systm.h>
                     79: #include <sys/kernel.h>
                     80: #include <sys/device.h>
                     81: #include <sys/queue.h>
                     82: #include <sys/proc.h>
                     83: #include <sys/buf.h>
                     84:
                     85: #include <machine/endian.h>
                     86: #ifdef __NetBSD__
                     87: #include <machine/bswap.h>
                     88: #endif /* __NetBSD__ */
                     89: #include <machine/bus.h>
                     90:
                     91: #ifdef __NetBSD__
                     92: #include <dev/scsipi/scsi_all.h>
                     93: #include <dev/scsipi/scsipi_all.h>
                     94: #include <dev/scsipi/scsiconf.h>
                     95: #endif /* __NetBSD__ */
                     96: #ifdef __OpenBSD__
                     97: #include <scsi/scsi_all.h>
                     98: #include <scsi/scsiconf.h>
                     99: #endif /* __OpenBSD__ */
                    100:
                    101: #include <dev/ic/dptreg.h>
                    102: #include <dev/ic/dptvar.h>
                    103:
                    104: #ifdef __OpenBSD__
                    105: static void dpt_enqueue(struct dpt_softc *, struct scsi_xfer *, int);
                    106: static struct scsi_xfer *dpt_dequeue(struct dpt_softc *);
                    107:
                    108: struct cfdriver dpt_cd = {
                    109:        NULL, "dpt", DV_DULL
                    110: };
                    111: #endif /* __OpenBSD__ */
                    112:
                    113: /* A default for our link struct */
                    114: #ifdef __NetBSD__
                    115: static struct scsipi_device dpt_dev = {
                    116: #endif /* __NetBSD__ */
                    117: #ifdef __OpenBSD__
                    118: static struct scsi_device dpt_dev = {
                    119: #endif /* __OpenBSD__ */
                    120:        NULL,                   /* Use default error handler */
                    121:        NULL,                   /* have a queue, served by this */
                    122:        NULL,                   /* have no async handler */
                    123:        NULL,                   /* Use default 'done' routine */
                    124: };
                    125:
                    126: #ifndef offsetof
                    127: #define offsetof(type, member) (int)((&((type *)0)->member))
                    128: #endif /* offsetof */
                    129:
                    130: static char *dpt_cname[] = {
                    131:        "PM3334", "SmartRAID IV",
                    132:        "PM3332", "SmartRAID IV",
                    133:        "PM2144", "SmartCache IV",
                    134:        "PM2044", "SmartCache IV",
                    135:        "PM2142", "SmartCache IV",
                    136:        "PM2042", "SmartCache IV",
                    137:        "PM2041", "SmartCache IV",
                    138:        "PM3224", "SmartRAID III",
                    139:        "PM3222", "SmartRAID III",
                    140:        "PM3021", "SmartRAID III",
                    141:        "PM2124", "SmartCache III",
                    142:        "PM2024", "SmartCache III",
                    143:        "PM2122", "SmartCache III",
                    144:        "PM2022", "SmartCache III",
                    145:        "PM2021", "SmartCache III",
                    146:        "SK2012", "SmartCache Plus",
                    147:        "SK2011", "SmartCache Plus",
                    148:        NULL,     "unknown adapter, please report using sendbug(1)",
                    149: };
                    150:
                    151: /*
                    152:  * Handle an interrupt from the HBA.
                    153:  */
                    154: int
                    155: dpt_intr(xxx_sc)
                    156:        void *xxx_sc;
                    157: {
                    158:        struct dpt_softc *sc;
                    159:        struct dpt_ccb *ccb;
                    160:        struct eata_sp *sp;
                    161:        static int moretimo;
                    162:        int more;
                    163:
                    164:        sc = xxx_sc;
                    165:        sp = sc->sc_statpack;
                    166:
                    167:        if (!sp) {
                    168: #ifdef DEBUG
                    169:                printf("%s: premature intr (st:%02x aux:%02x)\n",
                    170:                        sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS),
                    171:                        dpt_inb(sc, HA_AUX_STATUS));
                    172: #else /* DEBUG */
                    173:                (void) dpt_inb(sc, HA_STATUS);
                    174: #endif /* DEBUG */
                    175:                return (0);
                    176:        }
                    177:
                    178:        more = 0;
                    179:
                    180: #ifdef DEBUG
                    181:        if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
                    182:                printf("%s: spurious intr\n", sc->sc_dv.dv_xname);
                    183: #endif
                    184:
                    185:        /* Don't get stalled by HA_ST_MORE */
                    186:        if (moretimo < DPT_MORE_TIMEOUT / 100)
                    187:                moretimo = 0;
                    188:
                    189:        for (;;) {
                    190:                /*
                    191:                 * HBA might have interrupted while we were dealing with the
                    192:                 * last completed command, since we ACK before we deal; keep
                    193:                 * polling. If no interrupt is signalled, but the HBA has
                    194:                 * indicated that more data will be available soon, hang
                    195:                 * around.
                    196:                 */
                    197:                if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0) {
                    198:                        if (more != 0 && moretimo++ < DPT_MORE_TIMEOUT / 100) {
                    199:                                DELAY(10);
                    200:                                continue;
                    201:                        }
                    202:                        break;
                    203:                }
                    204:
                    205:                bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
                    206:                    sizeof(struct eata_sp), BUS_DMASYNC_POSTREAD);
                    207:
                    208:                if (!sp) {
                    209:                        more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
                    210:
                    211:                        /* Don't get stalled by HA_ST_MORE */
                    212:                        if (moretimo < DPT_MORE_TIMEOUT / 100)
                    213:                                moretimo = 0;
                    214:                        continue;
                    215:                }
                    216:
                    217:                /* Might have looped before HBA can reset HBA_AUX_INTR */
                    218:                if (sp->sp_ccbid == -1) {
                    219:                        DELAY(50);
                    220: #ifdef DIAGNOSTIC
                    221:                        printf("%s: slow reset of HA_AUX_STATUS?",
                    222:                            sc->sc_dv.dv_xname);
                    223: #endif
                    224:                        if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
                    225:                                return (0);
                    226: #ifdef DIAGNOSTIC
                    227:                        printf("%s: was a slow reset of HA_AUX_STATUS",
                    228:                            sc->sc_dv.dv_xname);
                    229: #endif
                    230:                        /* Re-sync DMA map */
                    231:                        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb,
                    232:                            sc->sc_spoff, sizeof(struct eata_sp),
                    233:                            BUS_DMASYNC_POSTREAD);
                    234:                }
                    235:
                    236:                /* Make sure CCB ID from status packet is realistic */
                    237:                if (sp->sp_ccbid >= 0 && sp->sp_ccbid < sc->sc_nccbs) {
                    238:                        /* Sync up DMA map and cache cmd status */
                    239:                        ccb = sc->sc_ccbs + sp->sp_ccbid;
                    240:
                    241:                        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb,
                    242:                            CCB_OFF(sc, ccb), sizeof(struct dpt_ccb),
                    243:                            BUS_DMASYNC_POSTWRITE);
                    244:
                    245:                        ccb->ccb_hba_status = sp->sp_hba_status & 0x7F;
                    246:                        ccb->ccb_scsi_status = sp->sp_scsi_status;
                    247:
                    248:                        /*
                    249:                         * Ack the interrupt and process the CCB. If this
                    250:                         * is a private CCB it's up to dpt_poll() to notice.
                    251:                         */
                    252:                        sp->sp_ccbid = -1;
                    253:                        ccb->ccb_flg |= CCB_INTR;
                    254:                        more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
                    255:                        if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
                    256:                                dpt_done_ccb(sc, ccb);
                    257:                } else {
                    258:                        printf("%s: bogus status (returned CCB id %d)\n",
                    259:                            sc->sc_dv.dv_xname, sp->sp_ccbid);
                    260:
                    261:                        /* Ack the interrupt */
                    262:                        sp->sp_ccbid = -1;
                    263:                        more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
                    264:                }
                    265:
                    266:                /* Don't get stalled by HA_ST_MORE */
                    267:                if (moretimo < DPT_MORE_TIMEOUT / 100)
                    268:                        moretimo = 0;
                    269:        }
                    270:
                    271:        return (0);
                    272: }
                    273:
                    274: /*
                    275:  * Initialize and attach the HBA. This is the entry point from bus
                    276:  * specific probe-and-attach code.
                    277:  */
                    278: void
                    279: dpt_init(sc, intrstr)
                    280:        struct dpt_softc *sc;
                    281:        const char *intrstr;
                    282: {
                    283:        struct eata_inquiry_data *ei;
                    284:        int i, j, error, rseg, mapsize;
                    285:        bus_dma_segment_t seg;
                    286:        struct eata_cfg *ec;
                    287:        char model[16];
                    288:
                    289:        ec = &sc->sc_ec;
                    290:
                    291:        /* Allocate the CCB/status packet/scratch DMA map and load */
                    292:        sc->sc_nccbs = min(betoh16(*(int16_t *)ec->ec_queuedepth),
                    293:                           DPT_MAX_CCBS);
                    294:        sc->sc_spoff = sc->sc_nccbs * sizeof(struct dpt_ccb);
                    295:        sc->sc_scroff = sc->sc_spoff + sizeof(struct eata_sp);
                    296:        sc->sc_scrlen = 256; /* XXX */
                    297:        mapsize = sc->sc_nccbs * sizeof(struct dpt_ccb) + sc->sc_scrlen +
                    298:            sizeof(struct eata_sp);
                    299:
                    300:        if ((error = bus_dmamem_alloc(sc->sc_dmat, mapsize, NBPG, 0,
                    301:            &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
                    302:                printf("%s: unable to allocate CCBs, error = %d\n",
                    303:                    sc->sc_dv.dv_xname, error);
                    304:                return;
                    305:        }
                    306:
                    307:        if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, mapsize,
                    308:            (caddr_t *)&sc->sc_ccbs, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
                    309:                printf("%s: unable to map CCBs, error = %d\n",
                    310:                    sc->sc_dv.dv_xname, error);
                    311:                return;
                    312:        }
                    313:
                    314:        if ((error = bus_dmamap_create(sc->sc_dmat, mapsize, mapsize, 1, 0,
                    315:            BUS_DMA_NOWAIT, &sc->sc_dmamap_ccb)) != 0) {
                    316:                printf("%s: unable to create CCB DMA map, error = %d\n",
                    317:                    sc->sc_dv.dv_xname, error);
                    318:                return;
                    319:        }
                    320:
                    321:        if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_ccb,
                    322:            sc->sc_ccbs, mapsize, NULL, BUS_DMA_NOWAIT)) != 0) {
                    323:                printf("%s: unable to load CCB DMA map, error = %d\n",
                    324:                    sc->sc_dv.dv_xname, error);
                    325:                return;
                    326:        }
                    327:
                    328:        sc->sc_statpack = (struct eata_sp *)((caddr_t)sc->sc_ccbs +
                    329:            sc->sc_spoff);
                    330:        sc->sc_sppa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_spoff;
                    331:        sc->sc_scr = (caddr_t)sc->sc_ccbs + sc->sc_scroff;
                    332:        sc->sc_scrpa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_scroff;
                    333:        sc->sc_statpack->sp_ccbid = -1;
                    334:
                    335:        /* Initialize the CCBs */
                    336:        TAILQ_INIT(&sc->sc_free_ccb);
                    337:        i = dpt_create_ccbs(sc, sc->sc_ccbs, sc->sc_nccbs);
                    338:
                    339:        if (i == 0) {
                    340:                printf("%s: unable to create CCBs\n", sc->sc_dv.dv_xname);
                    341:                return;
                    342:        } else if (i != sc->sc_nccbs) {
                    343:                printf("%s: %d/%d CCBs created!\n", sc->sc_dv.dv_xname, i,
                    344:                    sc->sc_nccbs);
                    345:                sc->sc_nccbs = i;
                    346:        }
                    347:
                    348:        /* Set shutdownhook before we start any device activity */
                    349:        sc->sc_sdh = shutdownhook_establish(dpt_shutdown, sc);
                    350:
                    351:        /* Get the page 0 inquiry data from the HBA */
                    352:        dpt_hba_inquire(sc, &ei);
                    353:
                    354:        /*
                    355:         * dpt0 at pci0 dev 12 function 0: DPT SmartRAID III (PM3224A/9X-R)
                    356:         * dpt0: interrupting at irq 10
                    357:         * dpt0: 64 queued commands, 1 channel(s), adapter on ID(s) 7
                    358:         */
                    359:        for (i = 0; ei->ei_vendor[i] != ' ' && i < 8; i++)
                    360:                ;
                    361:        ei->ei_vendor[i] = '\0';
                    362:
                    363:        for (i = 0; ei->ei_model[i] != ' ' && i < 7; i++)
                    364:                model[i] = ei->ei_model[i];
                    365:        for (j = 0; ei->ei_suffix[j] != ' ' && j < 7; j++)
                    366:                model[i++] = ei->ei_suffix[j];
                    367:        model[i] = '\0';
                    368:
                    369:        /* Find the canonical name for the board */
                    370:        for (i = 0; dpt_cname[i] != NULL; i += 2)
                    371:                if (memcmp(ei->ei_model, dpt_cname[i], 6) == 0)
                    372:                        break;
                    373:
                    374:        printf("%s %s (%s)\n", ei->ei_vendor, dpt_cname[i + 1], model);
                    375:
                    376:        if (intrstr != NULL)
                    377:                printf("%s: interrupting at %s\n", sc->sc_dv.dv_xname, intrstr);
                    378:
                    379:        printf("%s: %d queued commands, %d channel(s), adapter on ID(s)",
                    380:            sc->sc_dv.dv_xname, sc->sc_nccbs, ec->ec_maxchannel + 1);
                    381:
                    382:        for (i = 0; i <= ec->ec_maxchannel; i++)
                    383:                printf(" %d", ec->ec_hba[3 - i]);
                    384:        printf("\n");
                    385:
                    386:        /* Reset the SCSI bus */
                    387:        if (dpt_cmd(sc, NULL, 0, CP_IMMEDIATE, CPI_BUS_RESET))
                    388:                panic("%s: dpt_cmd failed", sc->sc_dv.dv_xname);
                    389:         DELAY(20000);
                    390:
                    391:        /* Fill in the adapter, each link and attach in turn */
                    392: #ifdef __NetBSD__
                    393:        sc->sc_adapter.scsipi_cmd = dpt_scsi_cmd;
                    394:        sc->sc_adapter.scsipi_minphys = dpt_minphys;
                    395: #endif /* __NetBSD__ */
                    396: #ifdef __OpenBSD__
                    397:        sc->sc_adapter.scsi_cmd = dpt_scsi_cmd;
                    398:        sc->sc_adapter.scsi_minphys = dpt_minphys;
                    399: #endif /* __OpenBSD__ */
                    400:
                    401:        for (i = 0; i <= ec->ec_maxchannel; i++) {
                    402: #ifdef __NetBSD__
                    403:                struct scsipi_link *link;
                    404: #endif /* __NetBSD__ */
                    405: #ifdef __OpenBSD__
                    406:                struct scsi_link *link;
                    407: #endif /* __OpenBSD__ */
                    408:                sc->sc_hbaid[i] = ec->ec_hba[3 - i];
                    409:                link = &sc->sc_link[i];
                    410: #ifdef __NetBSD__
                    411:                link->scsipi_scsi.scsibus = i;
                    412:                link->scsipi_scsi.adapter_target = sc->sc_hbaid[i];
                    413:                link->scsipi_scsi.max_lun = ec->ec_maxlun;
                    414:                link->scsipi_scsi.max_target = ec->ec_maxtarget;
                    415:                link->type = BUS_SCSI;
                    416: #endif /* __NetBSD__ */
                    417: #ifdef __OpenBSD__
                    418:                link->scsibus = i;
                    419:                link->adapter_target = sc->sc_hbaid[i];
                    420:                link->luns = ec->ec_maxlun + 1;
                    421:                link->adapter_buswidth = ec->ec_maxtarget + 1;
                    422: #endif /* __OpenBSD__ */
                    423:                link->device = &dpt_dev;
                    424:                link->adapter = &sc->sc_adapter;
                    425:                link->adapter_softc = sc;
                    426:                link->openings = sc->sc_nccbs;
                    427:                config_found(&sc->sc_dv, link, scsiprint);
                    428:        }
                    429: }
                    430:
                    431: /*
                    432:  * Our 'shutdownhook' to cleanly shut down the HBA. The HBA must flush
                    433:  * all data from its cache and mark array groups as clean.
                    434:  */
                    435: void
                    436: dpt_shutdown(xxx_sc)
                    437:        void *xxx_sc;
                    438: {
                    439:        struct dpt_softc *sc;
                    440:
                    441:        sc = xxx_sc;
                    442:        printf("shutting down %s...", sc->sc_dv.dv_xname);
                    443:        dpt_cmd(sc, NULL, 0, CP_IMMEDIATE, CPI_POWEROFF_WARN);
                    444:        DELAY(5000*1000);
                    445:        printf(" done\n");
                    446: }
                    447:
                    448: /*
                    449:  * Send an EATA command to the HBA.
                    450:  */
                    451: int
                    452: dpt_cmd(sc, cp, addr, eatacmd, icmd)
                    453:        struct dpt_softc *sc;
                    454:        struct eata_cp *cp;
                    455:        u_int32_t addr;
                    456:        int eatacmd, icmd;
                    457: {
                    458:        int i;
                    459:
                    460:        for (i = 20000; i; i--) {
                    461:                if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_BUSY) == 0)
                    462:                        break;
                    463:                DELAY(50);
                    464:        }
                    465:
                    466:        /* Not the most graceful way to handle this */
                    467:        if (i == 0) {
                    468:                printf("%s: HBA timeout on EATA command issue; aborting\n",
                    469:                    sc->sc_dv.dv_xname);
                    470:                return (-1);
                    471:        }
                    472:
                    473:        if (cp == NULL)
                    474:                addr = 0;
                    475:
                    476:        dpt_outb(sc, HA_DMA_BASE + 0, (u_int32_t)addr);
                    477:        dpt_outb(sc, HA_DMA_BASE + 1, (u_int32_t)addr >> 8);
                    478:        dpt_outb(sc, HA_DMA_BASE + 2, (u_int32_t)addr >> 16);
                    479:        dpt_outb(sc, HA_DMA_BASE + 3, (u_int32_t)addr >> 24);
                    480:
                    481:        if (eatacmd == CP_IMMEDIATE) {
                    482:                if (cp == NULL) {
                    483:                        /* XXX should really pass meaningful values */
                    484:                        dpt_outb(sc, HA_ICMD_CODE2, 0);
                    485:                        dpt_outb(sc, HA_ICMD_CODE1, 0);
                    486:                }
                    487:                dpt_outb(sc, HA_ICMD, icmd);
                    488:        }
                    489:
                    490:         dpt_outb(sc, HA_COMMAND, eatacmd);
                    491:         return (0);
                    492: }
                    493:
                    494: /*
                    495:  * Wait for the HBA to reach an arbitrary state.
                    496:  */
                    497: int
                    498: dpt_wait(sc, mask, state, ms)
                    499:         struct dpt_softc *sc;
                    500:         u_int8_t mask, state;
                    501:         int ms;
                    502: {
                    503:
                    504:         for (ms *= 10; ms; ms--) {
                    505:                 if ((dpt_inb(sc, HA_STATUS) & mask) == state)
                    506:                        return (0);
                    507:                 DELAY(100);
                    508:         }
                    509:         return (-1);
                    510: }
                    511:
                    512: /*
                    513:  * Wait for the specified CCB to finish. This is used when we may not be
                    514:  * able to sleep and/or interrupts are disabled (eg autoconfiguration).
                    515:  * The timeout value from the CCB is used. This should only be used for
                    516:  * CCB_PRIVATE requests; otherwise the CCB will get recycled before we get
                    517:  * a look at it.
                    518:  */
                    519: int
                    520: dpt_poll(sc, ccb)
                    521:         struct dpt_softc *sc;
                    522:         struct dpt_ccb *ccb;
                    523: {
                    524:        int i;
                    525:
                    526: #ifdef DEBUG
                    527:        if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
                    528:                panic("dpt_poll: called for non-CCB_PRIVATE request");
                    529: #endif
                    530:
                    531:        if ((ccb->ccb_flg & CCB_INTR) != 0)
                    532:                return (0);
                    533:
                    534:         for (i = ccb->ccb_timeout * 20; i; i--) {
                    535:                 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) != 0)
                    536:                        dpt_intr(sc);
                    537:                 if ((ccb->ccb_flg & CCB_INTR) != 0)
                    538:                        return (0);
                    539:                 DELAY(50);
                    540:         }
                    541:         return (-1);
                    542: }
                    543:
                    544: /*
                    545:  * Read the EATA configuration from the HBA and perform some sanity checks.
                    546:  */
                    547: int
                    548: dpt_readcfg(sc)
                    549:        struct dpt_softc *sc;
                    550: {
                    551:        struct eata_cfg *ec;
                    552:        int i, j, stat;
                    553:        u_int16_t *p;
                    554:
                    555:        ec = &sc->sc_ec;
                    556:
                    557:        /* Older firmware may puke if we talk to it too soon after reset */
                    558:        dpt_outb(sc, HA_COMMAND, CP_RESET);
                    559:         DELAY(750000);
                    560:
                    561:        for (i = 1000; i; i--) {
                    562:                if ((dpt_inb(sc, HA_STATUS) & HA_ST_READY) != 0)
                    563:                        break;
                    564:                DELAY(2000);
                    565:        }
                    566:
                    567:        if (i == 0) {
                    568:                printf("%s: HBA not ready after reset: %02x\n",
                    569:                    sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS));
                    570:                return (-1);
                    571:        }
                    572:
                    573:        while((((stat = dpt_inb(sc, HA_STATUS))
                    574:             != (HA_ST_READY|HA_ST_SEEK_COMPLETE))
                    575:             && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR))
                    576:             && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR|HA_ST_DRQ)))
                    577:             || (dpt_wait(sc, HA_ST_BUSY, 0, 2000))) {
                    578:                /* RAID drives still spinning up? */
                    579:                 if((dpt_inb(sc, HA_ERROR) != 'D')
                    580:                     || (dpt_inb(sc, HA_ERROR + 1) != 'P')
                    581:                     || (dpt_inb(sc, HA_ERROR + 2) != 'T')) {
                    582:                        printf("%s: HBA not ready\n", sc->sc_dv.dv_xname);
                    583:                         return (-1);
                    584:                }
                    585:         }
                    586:
                    587:        /*
                    588:         * Issue the read-config command and wait for the data to appear.
                    589:         * XXX we shouldn't be doing this with PIO, but it makes it a lot
                    590:         * easier as no DMA setup is required.
                    591:         */
                    592:        dpt_outb(sc, HA_COMMAND, CP_PIO_GETCFG);
                    593:        memset(ec, 0, sizeof(*ec));
                    594:        i = ((int)&((struct eata_cfg *)0)->ec_cfglen +
                    595:            sizeof(ec->ec_cfglen)) >> 1;
                    596:        p = (u_int16_t *)ec;
                    597:
                    598:        if (dpt_wait(sc, 0xFF, HA_ST_DATA_RDY, 2000)) {
                    599:                printf("%s: cfg data didn't appear (status:%02x)\n",
                    600:                    sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS));
                    601:                return (-1);
                    602:        }
                    603:
                    604:        /* Begin reading */
                    605:        while (i--)
                    606:                *p++ = dpt_inw(sc, HA_DATA);
                    607:
                    608:         if ((i = ec->ec_cfglen) > (sizeof(struct eata_cfg)
                    609:             - (int)(&(((struct eata_cfg *)0L)->ec_cfglen))
                    610:             - sizeof(ec->ec_cfglen)))
                    611:                 i = sizeof(struct eata_cfg)
                    612:                   - (int)(&(((struct eata_cfg *)0L)->ec_cfglen))
                    613:                   - sizeof(ec->ec_cfglen);
                    614:
                    615:         j = i + (int)(&(((struct eata_cfg *)0L)->ec_cfglen)) +
                    616:             sizeof(ec->ec_cfglen);
                    617:         i >>= 1;
                    618:
                    619:        while (i--)
                    620:                 *p++ = dpt_inw(sc, HA_DATA);
                    621:
                    622:         /* Flush until we have read 512 bytes. */
                    623:         i = (512 - j + 1) >> 1;
                    624:        while (i--)
                    625:                dpt_inw(sc, HA_DATA);
                    626:
                    627:         /* Defaults for older Firmware */
                    628:        if (p <= (u_short *)&ec->ec_hba[DPT_MAX_CHANNELS - 1])
                    629:                ec->ec_hba[DPT_MAX_CHANNELS - 1] = 7;
                    630:
                    631:         if ((dpt_inb(sc, HA_STATUS) & HA_ST_ERROR) != 0) {
                    632:                printf("%s: HBA error\n", sc->sc_dv.dv_xname);
                    633:                return (-1);
                    634:         }
                    635:
                    636:         if (!ec->ec_hbavalid) {
                    637:                 printf("%s: ec_hba field invalid\n", sc->sc_dv.dv_xname);
                    638:                return (-1);
                    639:        }
                    640:
                    641:        if (memcmp(ec->ec_eatasig, "EATA", 4) != 0) {
                    642:                printf("%s: EATA signature mismatch\n", sc->sc_dv.dv_xname);
                    643:                return (-1);
                    644:        }
                    645:
                    646:        if (!ec->ec_dmasupported) {
                    647:                printf("%s: DMA not supported\n", sc->sc_dv.dv_xname);
                    648:                return (-1);
                    649:        }
                    650:
                    651:        return (0);
                    652: }
                    653:
                    654: /*
                    655:  * Adjust the size of each I/O before it passes to the SCSI layer.
                    656:  */
                    657: void
                    658: dpt_minphys(bp)
                    659:        struct buf *bp;
                    660: {
                    661:
                    662:        if (bp->b_bcount > DPT_MAX_XFER)
                    663:                bp->b_bcount = DPT_MAX_XFER;
                    664:        minphys(bp);
                    665: }
                    666:
                    667: /*
                    668:  * Put a CCB onto the freelist.
                    669:  */
                    670: void
                    671: dpt_free_ccb(sc, ccb)
                    672:        struct dpt_softc *sc;
                    673:        struct dpt_ccb *ccb;
                    674: {
                    675:        int s;
                    676:
                    677:        s = splbio();
                    678:        ccb->ccb_flg = 0;
                    679:        TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, ccb_chain);
                    680:
                    681:        /* Wake anybody waiting for a free ccb */
                    682:        if (TAILQ_NEXT(ccb, ccb_chain) == NULL)
                    683:                wakeup(&sc->sc_free_ccb);
                    684:        splx(s);
                    685: }
                    686:
                    687: /*
                    688:  * Initialize the specified CCB.
                    689:  */
                    690: int
                    691: dpt_init_ccb(sc, ccb)
                    692:        struct dpt_softc *sc;
                    693:        struct dpt_ccb *ccb;
                    694: {
                    695:        int error;
                    696:
                    697:        /* Create the DMA map for this CCB's data */
                    698:        error = bus_dmamap_create(sc->sc_dmat, DPT_MAX_XFER, DPT_SG_SIZE,
                    699:            DPT_MAX_XFER, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
                    700:            &ccb->ccb_dmamap_xfer);
                    701:
                    702:        if (error) {
                    703:                printf("%s: can't create ccb dmamap (%d)\n",
                    704:                   sc->sc_dv.dv_xname, error);
                    705:                return (error);
                    706:        }
                    707:
                    708:        ccb->ccb_flg = 0;
                    709:        ccb->ccb_ccbpa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
                    710:            CCB_OFF(sc, ccb);
                    711:        return (0);
                    712: }
                    713:
                    714: /*
                    715:  * Create a set of CCBs and add them to the free list.
                    716:  */
                    717: int
                    718: dpt_create_ccbs(sc, ccbstore, count)
                    719:        struct dpt_softc *sc;
                    720:        struct dpt_ccb *ccbstore;
                    721:        int count;
                    722: {
                    723:        struct dpt_ccb *ccb;
                    724:        int i, error;
                    725:
                    726:        memset(ccbstore, 0, sizeof(struct dpt_ccb) * count);
                    727:
                    728:        for (i = 0, ccb = ccbstore; i < count; i++, ccb++) {
                    729:                if ((error = dpt_init_ccb(sc, ccb)) != 0) {
                    730:                        printf("%s: unable to init ccb, error = %d\n",
                    731:                            sc->sc_dv.dv_xname, error);
                    732:                        break;
                    733:                }
                    734:                ccb->ccb_id = i;
                    735:                TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_chain);
                    736:        }
                    737:
                    738:        return (i);
                    739: }
                    740:
                    741: /*
                    742:  * Get a free ccb. If there are none, see if we can allocate a new one. If
                    743:  * none are available right now and we are permitted to sleep, then wait
                    744:  * until one becomes free, otherwise return an error.
                    745:  */
                    746: struct dpt_ccb *
                    747: dpt_alloc_ccb(sc, flg)
                    748:        struct dpt_softc *sc;
                    749:        int flg;
                    750: {
                    751:        struct dpt_ccb *ccb;
                    752:        int s;
                    753:
                    754:        s = splbio();
                    755:
                    756:        for (;;) {
                    757:                ccb = TAILQ_FIRST(&sc->sc_free_ccb);
                    758:                if (ccb) {
                    759:                        TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ccb_chain);
                    760:                        break;
                    761:                }
                    762: #ifdef __NetBSD__
                    763:                if ((flg & XS_CTL_NOSLEEP) != 0) {
                    764: #endif /* __NetBSD__ */
                    765: #ifdef __OpenBSD__
                    766:                if ((flg & SCSI_NOSLEEP) != 0) {
                    767: #endif /* __OpenBSD__ */
                    768:                        splx(s);
                    769:                        return (NULL);
                    770:                }
                    771:                tsleep(&sc->sc_free_ccb, PRIBIO, "dptccb", 0);
                    772:        }
                    773:
                    774:        ccb->ccb_flg |= CCB_ALLOC;
                    775:        splx(s);
                    776:        return (ccb);
                    777: }
                    778:
                    779: /*
                    780:  * We have a CCB which has been processed by the HBA, now we look to see how
                    781:  * the operation went. CCBs marked with CCB_PRIVATE are not automatically
                    782:  * passed here by dpt_intr().
                    783:  */
                    784: void
                    785: dpt_done_ccb(sc, ccb)
                    786:        struct dpt_softc *sc;
                    787:        struct dpt_ccb *ccb;
                    788: {
                    789: #ifdef __NetBSD__
                    790:        struct scsipi_sense_data *s1, *s2;
                    791:        struct scsipi_xfer *xs;
                    792: #endif /* __NetBSD__ */
                    793: #ifdef __OpenBSD__
                    794:        struct scsi_sense_data *s1, *s2;
                    795:        struct scsi_xfer *xs;
                    796: #endif /* __OpenBSD__ */
                    797:        bus_dma_tag_t dmat;
                    798:
                    799:        dmat = sc->sc_dmat;
                    800:        xs = ccb->ccb_xs;
                    801:
                    802:        SC_DEBUG(xs->sc_link, SDEV_DB2, ("dpt_done_ccb\n"));
                    803:
                    804:        /*
                    805:         * If we were a data transfer, unload the map that described the
                    806:         * data buffer.
                    807:         */
                    808:        if (xs->datalen) {
                    809:                bus_dmamap_sync(dmat, ccb->ccb_dmamap_xfer, 0,
                    810:                    ccb->ccb_dmamap_xfer->dm_mapsize,
                    811:                    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
                    812:                    BUS_DMASYNC_POSTWRITE);
                    813:                bus_dmamap_unload(dmat, ccb->ccb_dmamap_xfer);
                    814:        }
                    815:
                    816:        /*
                    817:         * Otherwise, put the results of the operation into the xfer and
                    818:         * call whoever started it.
                    819:         */
                    820: #ifdef DIAGNOSTIC
                    821:        if ((ccb->ccb_flg & CCB_ALLOC) == 0) {
                    822:                panic("%s: done ccb not allocated!", sc->sc_dv.dv_xname);
                    823:                return;
                    824:        }
                    825: #endif
                    826:
                    827:        if (xs->error == XS_NOERROR) {
                    828:                if (ccb->ccb_hba_status != HA_NO_ERROR) {
                    829:                        switch (ccb->ccb_hba_status) {
                    830:                        case HA_ERROR_SEL_TO:
                    831:                                xs->error = XS_SELTIMEOUT;
                    832:                                break;
                    833:                        case HA_ERROR_RESET:
                    834:                                xs->error = XS_RESET;
                    835:                                break;
                    836:                        default:        /* Other scsi protocol messes */
                    837:                                printf("%s: HBA status %x\n",
                    838:                                    sc->sc_dv.dv_xname, ccb->ccb_hba_status);
                    839:                                xs->error = XS_DRIVER_STUFFUP;
                    840:                        }
                    841:                } else if (ccb->ccb_scsi_status != SCSI_OK) {
                    842:                        switch (ccb->ccb_scsi_status) {
                    843:                        case SCSI_CHECK:
                    844:                                s1 = &ccb->ccb_sense;
                    845: #ifdef __NetBSD__
                    846:                                s2 = &xs->sense.scsi_sense;
                    847: #endif /* __NetBSD__ */
                    848: #ifdef __OpenBSD__
                    849:                                s2 = &xs->sense;
                    850: #endif /* __OpenBSD__ */
                    851:                                *s2 = *s1;
                    852:                                xs->error = XS_SENSE;
                    853:                                break;
                    854:                        case SCSI_BUSY:
                    855:                                xs->error = XS_BUSY;
                    856:                                break;
                    857:                        default:
                    858:                                printf("%s: SCSI status %x\n",
                    859:                                    sc->sc_dv.dv_xname, ccb->ccb_scsi_status);
                    860:                                xs->error = XS_DRIVER_STUFFUP;
                    861:                        }
                    862:                } else
                    863:                        xs->resid = 0;
                    864:
                    865:                xs->status = ccb->ccb_scsi_status;
                    866:        }
                    867:
                    868:        /* Free up the CCB and mark the command as done */
                    869:        dpt_free_ccb(sc, ccb);
                    870: #ifdef __NetBSD__
                    871:        xs->xs_status |= XS_STS_DONE;
                    872:        scsipi_done(xs);
                    873: #endif /* __NetBSD__ */
                    874: #ifdef __OpenBSD__
                    875:        xs->flags |= ITSDONE;
                    876:        scsi_done(xs);
                    877: #endif /* __OpenBSD__ */
                    878:
                    879:        /*
                    880:         * If there are entries in the software queue, try to run the first
                    881:         * one. We should be more or less guaranteed to succeed, since we
                    882:         * just freed an CCB. NOTE: dpt_scsi_cmd() relies on our calling it
                    883:         * with the first entry in the queue.
                    884:         */
                    885: #ifdef __NetBSD__
                    886:        if ((xs = TAILQ_FIRST(&sc->sc_queue)) != NULL)
                    887: #endif /* __NetBSD__ */
                    888: #ifdef __OpenBSD__
                    889:        if ((xs = LIST_FIRST(&sc->sc_queue)) != NULL)
                    890: #endif /* __OpenBSD__ */
                    891:                dpt_scsi_cmd(xs);
                    892: }
                    893:
                    894: #ifdef __OpenBSD__
                    895: /*
                    896:  * Insert a scsi_xfer into the software queue.  We overload xs->free_list
                    897:  * to avoid having to allocate additional resources (since we're used
                    898:  * only during resource shortages anyhow.
                    899:  */
                    900: static void
                    901: dpt_enqueue(sc, xs, infront)
                    902:        struct dpt_softc *sc;
                    903:        struct scsi_xfer *xs;
                    904:        int             infront;
                    905: {
                    906:
                    907:        if (infront || LIST_EMPTY(&sc->sc_queue)) {
                    908:                if (LIST_EMPTY(&sc->sc_queue))
                    909:                        sc->sc_queuelast = xs;
                    910:                LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
                    911:                return;
                    912:        }
                    913:        LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
                    914:        sc->sc_queuelast = xs;
                    915: }
                    916:
                    917: /*
                    918:  * Pull a scsi_xfer off the front of the software queue.
                    919:  */
                    920: static struct scsi_xfer *
                    921: dpt_dequeue(sc)
                    922:        struct dpt_softc *sc;
                    923: {
                    924:        struct scsi_xfer *xs;
                    925:
                    926:        xs = LIST_FIRST(&sc->sc_queue);
                    927:        LIST_REMOVE(xs, free_list);
                    928:
                    929:        if (LIST_EMPTY(&sc->sc_queue))
                    930:                sc->sc_queuelast = NULL;
                    931:
                    932:        return (xs);
                    933: }
                    934: #endif /* __OpenBSD__ */
                    935:
                    936: /*
                    937:  * Start a SCSI command.
                    938:  */
                    939: int
                    940: dpt_scsi_cmd(xs)
                    941: #ifdef __NetBSD__
                    942:        struct scsipi_xfer *xs;
                    943: #endif /* __NetBSD__ */
                    944: #ifdef __OpenBSD__
                    945:        struct scsi_xfer *xs;
                    946: #endif /* __OpenBSD__ */
                    947: {
                    948:        int error, i, flags, s, fromqueue, dontqueue;
                    949: #ifdef __NetBSD__
                    950:        struct scsipi_link *sc_link;
                    951: #endif /* __NetBSD__ */
                    952: #ifdef __OpenBSD__
                    953:        struct scsi_link *sc_link;
                    954: #endif /* __OpenBSD__ */
                    955:        struct dpt_softc *sc;
                    956:        struct dpt_ccb *ccb;
                    957:        struct eata_sg *sg;
                    958:        struct eata_cp *cp;
                    959:        bus_dma_tag_t dmat;
                    960:        bus_dmamap_t xfer;
                    961:
                    962:        sc_link = xs->sc_link;
                    963: #ifdef __NetBSD__
                    964:        flags = xs->xs_control;
                    965: #endif /* __NetBSD__ */
                    966: #ifdef __OpenBSD__
                    967:        flags = xs->flags;
                    968: #endif /* __OpenBSD__ */
                    969:        sc = sc_link->adapter_softc;
                    970:        dmat = sc->sc_dmat;
                    971:        fromqueue = 0;
                    972:        dontqueue = 0;
                    973:
                    974:        SC_DEBUG(sc_link, SDEV_DB2, ("dpt_scsi_cmd\n"));
                    975:
                    976:        /* Protect the queue */
                    977:        s = splbio();
                    978:
                    979:        /*
                    980:         * If we're running the queue from dpt_done_ccb(), we've been called
                    981:         * with the first queue entry as our argument.
                    982:         */
                    983: #ifdef __NetBSD__
                    984:        if (xs == TAILQ_FIRST(&sc->sc_queue)) {
                    985:                TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
                    986: #endif /* __NetBSD__ */
                    987: #ifdef __OpenBSD__
                    988:        if (xs == LIST_FIRST(&sc->sc_queue)) {
                    989:                xs = dpt_dequeue(sc);
                    990: #endif /* __OpenBSD__ */
                    991:                fromqueue = 1;
                    992:        } else {
                    993:                /* Cmds must be no more than 12 bytes for us */
                    994:                if (xs->cmdlen > 12) {
                    995:                        splx(s);
                    996:                        xs->error = XS_DRIVER_STUFFUP;
                    997:                        return (COMPLETE);
                    998:                }
                    999:
                   1000:                /* XXX we can't reset devices just yet */
                   1001: #ifdef __NetBSD__
                   1002:                if ((flags & XS_CTL_RESET) != 0) {
                   1003: #endif /* __NetBSD__ */
                   1004: #ifdef __OpenBSD__
                   1005:                if ((xs->flags & SCSI_RESET) != 0) {
                   1006: #endif /* __OpenBSD__ */
                   1007:                        splx(s);
                   1008:                        xs->error = XS_DRIVER_STUFFUP;
                   1009:                        return (COMPLETE);
                   1010:                }
                   1011:
                   1012:                /* Polled requests can't be queued for later */
                   1013: #ifdef __NetBSD__
                   1014:                dontqueue = flags & XS_CTL_POLL;
                   1015: #endif /* __NetBSD__ */
                   1016: #ifdef __OpenBSD__
                   1017:                dontqueue = xs->flags & SCSI_POLL;
                   1018: #endif /* __OpenBSD__ */
                   1019:
                   1020:                /* If there are jobs in the queue, run them first */
                   1021: #ifdef __NetBSD__
                   1022:                if (TAILQ_FIRST(&sc->sc_queue) != NULL) {
                   1023: #endif /* __NetBSD__ */
                   1024: #ifdef __OpenBSD__
                   1025:                if (!LIST_EMPTY(&sc->sc_queue)) {
                   1026: #endif /* __OpenBSD__ */
                   1027:                        /*
                   1028:                         * If we can't queue we abort, since we must
                   1029:                         * preserve the queue order.
                   1030:                         */
                   1031:                        if (dontqueue) {
                   1032:                                splx(s);
                   1033:                                return (TRY_AGAIN_LATER);
                   1034:                        }
                   1035:
                   1036:                        /* Swap with the first queue entry. */
                   1037: #ifdef __NetBSD__
                   1038:                        TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
                   1039:                        xs = TAILQ_FIRST(&sc->sc_queue);
                   1040:                        TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
                   1041: #endif /* __NetBSD__ */
                   1042: #ifdef __OpenBSD__
                   1043:                        dpt_enqueue(sc, xs, 0);
                   1044:                        xs = dpt_dequeue(sc);
                   1045: #endif /* __OpenBSD__ */
                   1046:                        fromqueue = 1;
                   1047:                }
                   1048:        }
                   1049:
                   1050:        /* Get a CCB */
                   1051: #ifdef __NetBSD__
                   1052:        if ((ccb = dpt_alloc_ccb(sc, flags)) == NULL) {
                   1053: #endif /* __NetBSD__ */
                   1054: #ifdef __OpenBSD__
                   1055:        if ((ccb = dpt_alloc_ccb(sc, xs->flags)) == NULL) {
                   1056: #endif /* __OpenBSD__ */
                   1057:                /* If we can't queue, we lose */
                   1058:                if (dontqueue) {
                   1059:                        splx(s);
                   1060:                        return (TRY_AGAIN_LATER);
                   1061:                }
                   1062:
                   1063:                /*
                   1064:                 * Stuff request into the queue, in front if we came off
                   1065:                 * it in the first place.
                   1066:                 */
                   1067: #ifdef __NetBSD__
                   1068:                if (fromqueue)
                   1069:                        TAILQ_INSERT_HEAD(&sc->sc_queue, xs, adapter_q);
                   1070:                else
                   1071:                        TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
                   1072: #endif /* __NetBSD__ */
                   1073: #ifdef __OpenBSD__
                   1074:                dpt_enqueue(sc, xs, fromqueue);
                   1075: #endif /* __OpenBSD__ */
                   1076:                splx(s);
                   1077:                return (SUCCESSFULLY_QUEUED);
                   1078:        }
                   1079:
                   1080:        splx(s);
                   1081:
                   1082:        ccb->ccb_xs = xs;
                   1083:        ccb->ccb_timeout = xs->timeout;
                   1084:
                   1085:        cp = &ccb->ccb_eata_cp;
                   1086: #ifdef __NetBSD__
                   1087:        memcpy(&cp->cp_scsi_cmd, xs->cmd, xs->cmdlen);
                   1088: #endif /* __NetBSD__ */
                   1089: #ifdef __OpenBSD__
                   1090:        bcopy(xs->cmd, &cp->cp_scsi_cmd, xs->cmdlen);
                   1091: #endif /* __OpenBSD__ */
                   1092:        cp->cp_ccbid = ccb->ccb_id;
                   1093: #ifdef __NetBSD__
                   1094:        cp->cp_id = sc_link->scsipi_scsi.target;
                   1095:        cp->cp_lun = sc_link->scsipi_scsi.lun;
                   1096:        cp->cp_channel = sc_link->scsipi_scsi.channel;
                   1097: #endif /* __NetBSD__ */
                   1098: #ifdef __OpenBSD__
                   1099:        cp->cp_id = sc_link->target;
                   1100:        cp->cp_lun = sc_link->lun;
                   1101:        cp->cp_channel = sc_link->scsibus;
                   1102: #endif /* __OpenBSD__ */
                   1103:        cp->cp_senselen = sizeof(ccb->ccb_sense);
                   1104:        cp->cp_stataddr = htobe32(sc->sc_sppa);
                   1105:        cp->cp_dispri = 1;
                   1106:        cp->cp_identify = 1;
                   1107:        cp->cp_autosense = 1;
                   1108: #ifdef __NetBSD__
                   1109:        cp->cp_datain = ((flags & XS_CTL_DATA_IN) != 0);
                   1110:        cp->cp_dataout = ((flags & XS_CTL_DATA_OUT) != 0);
                   1111:        cp->cp_interpret = (sc->sc_hbaid[sc_link->scsipi_scsi.channel] ==
                   1112:            sc_link->scsipi_scsi.target);
                   1113: #endif /* __NetBSD__ */
                   1114: #ifdef __OpenBSD__
                   1115:        cp->cp_datain = ((xs->flags & SCSI_DATA_IN) != 0);
                   1116:        cp->cp_dataout = ((xs->flags & SCSI_DATA_OUT) != 0);
                   1117:        cp->cp_interpret = (sc->sc_hbaid[sc_link->scsibus] == sc_link->target);
                   1118: #endif /* __OpenBSD__ */
                   1119:
                   1120:        /* Synchronous xfers musn't write-back through the cache */
                   1121:        if (xs->bp != NULL && (xs->bp->b_flags & (B_ASYNC | B_READ)) == 0)
                   1122:                cp->cp_nocache = 1;
                   1123:        else
                   1124:                cp->cp_nocache = 0;
                   1125:
                   1126:        cp->cp_senseaddr = htobe32(sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
                   1127:            CCB_OFF(sc, ccb) + offsetof(struct dpt_ccb, ccb_sense));
                   1128:
                   1129:        if (xs->datalen) {
                   1130:                xfer = ccb->ccb_dmamap_xfer;
                   1131: #ifdef TFS
                   1132: #ifdef __NetBSD__
                   1133:                if ((flags & XS_CTL_DATA_UIO) != 0) {
                   1134:                        error = bus_dmamap_load_uio(dmat, xfer,
                   1135:                            (struct uio *)xs->data, (flags & XS_CTL_NOSLEEP) ?
                   1136:                            BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
                   1137: #endif /* __NetBSD__ */
                   1138: #ifdef __OpenBSD__
                   1139:                if ((xs->flags & SCSI_DATA_UIO) != 0) {
                   1140:                        error = bus_dmamap_load_uio(dmat, xfer,
                   1141:                            (xs->flags & SCSI_NOSLEEP) ?
                   1142:                            BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
                   1143: #endif /* __OpenBSD__ */
                   1144:                } else
                   1145: #endif /*TFS */
                   1146:                {
                   1147: #ifdef __NetBSD__
                   1148:                        error = bus_dmamap_load(dmat, xfer, xs->data,
                   1149:                            xs->datalen, NULL, (flags & XS_CTL_NOSLEEP) ?
                   1150:                            BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
                   1151: #endif /* __NetBSD__ */
                   1152: #ifdef __OpenBSD__
                   1153:                        error = bus_dmamap_load(dmat, xfer, xs->data,
                   1154:                            xs->datalen, NULL, (xs->flags & SCSI_NOSLEEP) ?
                   1155:                            BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
                   1156: #endif /* __OpenBSD__ */
                   1157:                }
                   1158:
                   1159:                if (error) {
                   1160:                        printf("%s: dpt_scsi_cmd: ", sc->sc_dv.dv_xname);
                   1161:                        if (error == EFBIG)
                   1162:                                printf("more than %d dma segs\n", DPT_SG_SIZE);
                   1163:                        else
                   1164:                                printf("error %d loading dma map\n", error);
                   1165:
                   1166:                        xs->error = XS_DRIVER_STUFFUP;
                   1167:                        dpt_free_ccb(sc, ccb);
                   1168:                        return (COMPLETE);
                   1169:                }
                   1170:
                   1171:                bus_dmamap_sync(dmat, xfer, 0, xfer->dm_mapsize,
                   1172:                    (flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
                   1173:                    BUS_DMASYNC_PREWRITE);
                   1174:
                   1175:                /* Don't bother using scatter/gather for just 1 segment */
                   1176:                if (xfer->dm_nsegs == 1) {
                   1177:                        cp->cp_dataaddr = htobe32(xfer->dm_segs[0].ds_addr);
                   1178:                        cp->cp_datalen = htobe32(xfer->dm_segs[0].ds_len);
                   1179:                        cp->cp_scatter = 0;
                   1180:                } else {
                   1181:                        /*
                   1182:                         * Load the hardware scatter/gather map with the
                   1183:                         * contents of the DMA map.
                   1184:                         */
                   1185:                        sg = ccb->ccb_sg;
                   1186:                        for (i = 0; i < xfer->dm_nsegs; i++, sg++) {
                   1187:                                sg->sg_addr =
                   1188:                                  htobe32(xfer->dm_segs[i].ds_addr);
                   1189:                                sg->sg_len =
                   1190:                                  htobe32(xfer->dm_segs[i].ds_len);
                   1191:                        }
                   1192:                        cp->cp_dataaddr = htobe32(CCB_OFF(sc, ccb) +
                   1193:                            sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
                   1194:                            offsetof(struct dpt_ccb, ccb_sg));
                   1195:                        cp->cp_datalen = htobe32(i * sizeof(struct eata_sg));
                   1196:                        cp->cp_scatter = 1;
                   1197:                }
                   1198:        } else {
                   1199:                cp->cp_dataaddr = 0;
                   1200:                cp->cp_datalen = 0;
                   1201:                cp->cp_scatter = 0;
                   1202:        }
                   1203:
                   1204:        /* Sync up CCB and status packet */
                   1205:        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, CCB_OFF(sc, ccb),
                   1206:            sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
                   1207:        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
                   1208:            sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
                   1209:
                   1210:        /*
                   1211:         * Start the command. If we are polling on completion, mark it
                   1212:         * private so that dpt_intr/dpt_done_ccb don't recycle the CCB
                   1213:         * without us noticing.
                   1214:         */
                   1215:        if (dontqueue != 0)
                   1216:                ccb->ccb_flg |= CCB_PRIVATE;
                   1217:
                   1218:        if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, CP_DMA_CMD, 0)) {
                   1219:                printf("%s: dpt_cmd failed\n", sc->sc_dv.dv_xname);
                   1220:                dpt_free_ccb(sc, ccb);
                   1221:                return (TRY_AGAIN_LATER);
                   1222:        }
                   1223:
                   1224:        if (dontqueue == 0)
                   1225:                return (SUCCESSFULLY_QUEUED);
                   1226:
                   1227:        /* Don't wait longer than this single command wants to wait */
                   1228:        if (dpt_poll(sc, ccb)) {
                   1229:                dpt_timeout(ccb);
                   1230:                /* Wait for abort to complete */
                   1231:                if (dpt_poll(sc, ccb))
                   1232:                        dpt_timeout(ccb);
                   1233:        }
                   1234:
                   1235:        dpt_done_ccb(sc, ccb);
                   1236:        return (COMPLETE);
                   1237: }
                   1238:
                   1239: /*
                   1240:  * Specified CCB has timed out, abort it.
                   1241:  */
                   1242: void
                   1243: dpt_timeout(arg)
                   1244:        void *arg;
                   1245: {
                   1246: #ifdef __NetBSD__
                   1247:        struct scsipi_link *sc_link;
                   1248:        struct scsipi_xfer *xs;
                   1249: #endif /* __NetBSD__ */
                   1250: #ifdef __OpenBSD__
                   1251:        struct scsi_link *sc_link;
                   1252:        struct scsi_xfer *xs;
                   1253: #endif /* __OpenBSD__ */
                   1254:        struct dpt_softc *sc;
                   1255:        struct dpt_ccb *ccb;
                   1256:        int s;
                   1257:
                   1258:        ccb = arg;
                   1259:        xs = ccb->ccb_xs;
                   1260:        sc_link = xs->sc_link;
                   1261:        sc  = sc_link->adapter_softc;
                   1262:
                   1263: #ifdef __NetBSD__
                   1264:        scsi_print_addr(sc_link);
                   1265: #endif /* __NetBSD__ */
                   1266: #ifdef __OpenBSD__
                   1267:        sc_print_addr(sc_link);
                   1268: #endif /* __OpenBSD__ */
                   1269:        printf("timed out (status:%02x aux status:%02x)",
                   1270:            dpt_inb(sc, HA_STATUS), dpt_inb(sc, HA_AUX_STATUS));
                   1271:
                   1272:        s = splbio();
                   1273:
                   1274:        if ((ccb->ccb_flg & CCB_ABORT) != 0) {
                   1275:                /* Abort timed out, reset the HBA */
                   1276:                printf(" AGAIN, resetting HBA\n");
                   1277:                dpt_outb(sc, HA_COMMAND, CP_RESET);
                   1278:                DELAY(750000);
                   1279:        } else {
                   1280:                /* Abort the operation that has timed out */
                   1281:                printf("\n");
                   1282:                ccb->ccb_xs->error = XS_TIMEOUT;
                   1283:                ccb->ccb_timeout = DPT_ABORT_TIMEOUT;
                   1284:                ccb->ccb_flg |= CCB_ABORT;
                   1285:                /* Start the abort */
                   1286:                if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa,
                   1287:                    CP_IMMEDIATE, CPI_SPEC_ABORT))
                   1288:                    printf("%s: dpt_cmd failed\n", sc->sc_dv.dv_xname);
                   1289:        }
                   1290:
                   1291:        splx(s);
                   1292: }
                   1293:
                   1294: #ifdef DEBUG
                   1295: /*
                   1296:  * Dump the contents of an EATA status packet.
                   1297:  */
                   1298: void
                   1299: dpt_dump_sp(sp)
                   1300:        struct eata_sp *sp;
                   1301: {
                   1302:        int i;
                   1303:
                   1304:        printf("\thba_status\t%02x\n", sp->sp_hba_status);
                   1305:        printf("\tscsi_status\t%02x\n", sp->sp_scsi_status);
                   1306:        printf("\tinv_residue\t%d\n", sp->sp_inv_residue);
                   1307:        printf("\tccbid\t\t%d\n", sp->sp_ccbid);
                   1308:        printf("\tid_message\t%d\n", sp->sp_id_message);
                   1309:        printf("\tque_message\t%d\n", sp->sp_que_message);
                   1310:        printf("\ttag_message\t%d\n", sp->sp_tag_message);
                   1311:        printf("\tmessages\t");
                   1312:
                   1313:        for (i = 0; i < 9; i++)
                   1314:                printf("%d ", sp->sp_messages[i]);
                   1315:
                   1316:        printf("\n");
                   1317: }
                   1318: #endif /* DEBUG */
                   1319:
                   1320: /*
                   1321:  * Get inquiry data from the adapter.
                   1322:  */
                   1323: void
                   1324: dpt_hba_inquire(sc, ei)
                   1325:        struct dpt_softc *sc;
                   1326:        struct eata_inquiry_data **ei;
                   1327: {
                   1328:        struct dpt_ccb *ccb;
                   1329:        struct eata_cp *cp;
                   1330:        bus_dma_tag_t dmat;
                   1331:
                   1332:        *ei = (struct eata_inquiry_data *)sc->sc_scr;
                   1333:        dmat = sc->sc_dmat;
                   1334:
                   1335:        /* Get a CCB and mark as private */
                   1336:        if ((ccb = dpt_alloc_ccb(sc, 0)) == NULL)
                   1337:                panic("%s: no CCB for inquiry", sc->sc_dv.dv_xname);
                   1338:
                   1339:        ccb->ccb_flg |= CCB_PRIVATE;
                   1340:        ccb->ccb_timeout = 200;
                   1341:
                   1342:        /* Put all the arguments into the CCB */
                   1343:        cp = &ccb->ccb_eata_cp;
                   1344:        cp->cp_ccbid = ccb->ccb_id;
                   1345:        cp->cp_id = sc->sc_hbaid[0];
                   1346:        cp->cp_lun = 0;
                   1347:        cp->cp_channel = 0;
                   1348:        cp->cp_senselen = sizeof(ccb->ccb_sense);
                   1349:        cp->cp_stataddr = htobe32(sc->sc_sppa);
                   1350:        cp->cp_dispri = 1;
                   1351:        cp->cp_identify = 1;
                   1352:        cp->cp_autosense = 0;
                   1353:        cp->cp_interpret = 1;
                   1354:        cp->cp_nocache = 0;
                   1355:        cp->cp_datain = 1;
                   1356:        cp->cp_dataout = 0;
                   1357:        cp->cp_senseaddr = 0;
                   1358:        cp->cp_dataaddr = htobe32(sc->sc_scrpa);
                   1359:        cp->cp_datalen = htobe32(sizeof(struct eata_inquiry_data));
                   1360:        cp->cp_scatter = 0;
                   1361:
                   1362:        /* Put together the SCSI inquiry command */
                   1363:        memset(&cp->cp_scsi_cmd, 0, 12);        /* XXX */
                   1364:        cp->cp_scsi_cmd = INQUIRY;
                   1365:        cp->cp_len = sizeof(struct eata_inquiry_data);
                   1366:
                   1367:        /* Sync up CCB, status packet and scratch area */
                   1368:        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, CCB_OFF(sc, ccb),
                   1369:            sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
                   1370:        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
                   1371:            sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
                   1372:        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_scroff,
                   1373:            sizeof(struct eata_inquiry_data), BUS_DMASYNC_PREREAD);
                   1374:
                   1375:        /* Start the command and poll on completion */
                   1376:        if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, CP_DMA_CMD, 0))
                   1377:                panic("%s: dpt_cmd failed", sc->sc_dv.dv_xname);
                   1378:
                   1379:        if (dpt_poll(sc, ccb))
                   1380:                panic("%s: inquiry timed out", sc->sc_dv.dv_xname);
                   1381:
                   1382:        if (ccb->ccb_hba_status != HA_NO_ERROR ||
                   1383:            ccb->ccb_scsi_status != SCSI_OK)
                   1384:                panic("%s: inquiry failed (hba:%02x scsi:%02x",
                   1385:                    sc->sc_dv.dv_xname, ccb->ccb_hba_status,
                   1386:                    ccb->ccb_scsi_status);
                   1387:
                   1388:        /* Sync up the DMA map and free CCB, returning */
                   1389:        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_scroff,
                   1390:            sizeof(struct eata_inquiry_data), BUS_DMASYNC_POSTREAD);
                   1391:        dpt_free_ccb(sc, ccb);
                   1392: }

CVSweb