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

Annotation of sys/dev/i2o/iop.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: iop.c,v 1.29 2006/11/29 12:24:17 miod Exp $   */
                      2: /*     $NetBSD: iop.c,v 1.12 2001/03/21 14:27:05 ad Exp $      */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Andrew Doran.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *        This product includes software developed by the NetBSD
                     22:  *        Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: /*
                     41:  * Support for I2O IOPs (intelligent I/O processors).
                     42:  */
                     43:
                     44: #include <sys/param.h>
                     45: #include <sys/systm.h>
                     46: #include <sys/kernel.h>
                     47: #include <sys/device.h>
                     48: #include <sys/queue.h>
                     49: #include <sys/proc.h>
                     50: #include <sys/malloc.h>
                     51: #include <sys/ioctl.h>
                     52: #include <sys/endian.h>
                     53: #include <sys/conf.h>
                     54: #include <sys/kthread.h>
                     55:
                     56: #include <uvm/uvm_extern.h>
                     57:
                     58: #include <machine/bus.h>
                     59:
                     60: #include <dev/i2o/i2o.h>
                     61: #include <dev/i2o/iopio.h>
                     62: #include <dev/i2o/iopreg.h>
                     63: #include <dev/i2o/iopvar.h>
                     64:
                     65: #define POLL(ms, cond)                         \
                     66: do {                                           \
                     67:        int i;                                  \
                     68:        for (i = (ms) * 10; i; i--) {           \
                     69:                if (cond)                       \
                     70:                        break;                  \
                     71:                DELAY(100);                     \
                     72:        }                                       \
                     73: } while (/* CONSTCOND */0);
                     74:
                     75: #ifdef I2ODEBUG
                     76: #define DPRINTF(x)     printf x
                     77: #else
                     78: #define        DPRINTF(x)
                     79: #endif
                     80:
                     81: #ifdef I2OVERBOSE
                     82: #define IFVERBOSE(x)   x
                     83: #define        COMMENT(x)      NULL
                     84: #else
                     85: #define        IFVERBOSE(x)
                     86: #define        COMMENT(x)
                     87: #endif
                     88:
                     89: #define IOP_ICTXHASH_NBUCKETS  16
                     90: #define        IOP_ICTXHASH(ictx)      (&iop_ictxhashtbl[(ictx) & iop_ictxhash])
                     91:
                     92: #define        IOP_MAX_SEGS    (((IOP_MAX_XFER + PAGE_SIZE - 1) / PAGE_SIZE) + 1)
                     93:
                     94: #define        IOP_TCTX_SHIFT  12
                     95: #define        IOP_TCTX_MASK   ((1 << IOP_TCTX_SHIFT) - 1)
                     96:
                     97: LIST_HEAD(, iop_initiator) *iop_ictxhashtbl;
                     98: u_long iop_ictxhash;
                     99: void   *iop_sdh;
                    100: struct i2o_systab *iop_systab;
                    101: int    iop_systab_size;
                    102:
                    103: struct cfdriver iop_cd = {
                    104:        NULL, "iop", DV_DULL
                    105: };
                    106:
                    107: #define        IC_CONFIGURE    0x01
                    108: #define        IC_PRIORITY     0x02
                    109:
                    110: struct iop_class {
                    111:        u_short ic_class;
                    112:        u_short ic_flags;
                    113: #ifdef I2OVERBOSE
                    114:        const char      *ic_caption;
                    115: #endif
                    116: } static const iop_class[] = {
                    117:        {
                    118:                I2O_CLASS_EXECUTIVE,
                    119:                0,
                    120:                COMMENT("executive")
                    121:        },
                    122:        {
                    123:                I2O_CLASS_DDM,
                    124:                0,
                    125:                COMMENT("device driver module")
                    126:        },
                    127:        {
                    128:                I2O_CLASS_RANDOM_BLOCK_STORAGE,
                    129:                IC_CONFIGURE | IC_PRIORITY,
                    130:                IFVERBOSE("random block storage")
                    131:        },
                    132:        {
                    133:                I2O_CLASS_SEQUENTIAL_STORAGE,
                    134:                IC_CONFIGURE | IC_PRIORITY,
                    135:                IFVERBOSE("sequential storage")
                    136:        },
                    137:        {
                    138:                I2O_CLASS_LAN,
                    139:                IC_CONFIGURE | IC_PRIORITY,
                    140:                IFVERBOSE("LAN port")
                    141:        },
                    142:        {
                    143:                I2O_CLASS_WAN,
                    144:                IC_CONFIGURE | IC_PRIORITY,
                    145:                IFVERBOSE("WAN port")
                    146:        },
                    147:        {
                    148:                I2O_CLASS_FIBRE_CHANNEL_PORT,
                    149:                IC_CONFIGURE,
                    150:                IFVERBOSE("fibrechannel port")
                    151:        },
                    152:        {
                    153:                I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL,
                    154:                0,
                    155:                COMMENT("fibrechannel peripheral")
                    156:        },
                    157:        {
                    158:                I2O_CLASS_SCSI_PERIPHERAL,
                    159:                0,
                    160:                COMMENT("SCSI peripheral")
                    161:        },
                    162:        {
                    163:                I2O_CLASS_ATE_PORT,
                    164:                IC_CONFIGURE,
                    165:                IFVERBOSE("ATE port")
                    166:        },
                    167:        {
                    168:                I2O_CLASS_ATE_PERIPHERAL,
                    169:                0,
                    170:                COMMENT("ATE peripheral")
                    171:        },
                    172:        {
                    173:                I2O_CLASS_FLOPPY_CONTROLLER,
                    174:                IC_CONFIGURE,
                    175:                IFVERBOSE("floppy controller")
                    176:        },
                    177:        {
                    178:                I2O_CLASS_FLOPPY_DEVICE,
                    179:                0,
                    180:                COMMENT("floppy device")
                    181:        },
                    182:        {
                    183:                I2O_CLASS_BUS_ADAPTER_PORT,
                    184:                IC_CONFIGURE,
                    185:                IFVERBOSE("bus adapter port" )
                    186:        },
                    187: };
                    188:
                    189: #if defined(I2ODEBUG) && defined(I2OVERBOSE)
                    190: static const char * const iop_status[] = {
                    191:        "success",
                    192:        "abort (dirty)",
                    193:        "abort (no data transfer)",
                    194:        "abort (partial transfer)",
                    195:        "error (dirty)",
                    196:        "error (no data transfer)",
                    197:        "error (partial transfer)",
                    198:        "undefined error code",
                    199:        "process abort (dirty)",
                    200:        "process abort (no data transfer)",
                    201:        "process abort (partial transfer)",
                    202:        "transaction error",
                    203: };
                    204: #endif
                    205:
                    206: static inline u_int32_t        iop_inl(struct iop_softc *, int);
                    207: static inline void     iop_outl(struct iop_softc *, int, u_int32_t);
                    208:
                    209: void   iop_config_interrupts(struct device *);
                    210: void   iop_configure_devices(struct iop_softc *, int, int);
                    211: void   iop_devinfo(int, char *, size_t);
                    212: int    iop_print(void *, const char *);
                    213: int    iop_reconfigure(struct iop_softc *, u_int);
                    214: void   iop_shutdown(void *);
                    215: int    iop_submatch(struct device *, void *, void *);
                    216: #ifdef notyet
                    217: int    iop_vendor_print(void *, const char *);
                    218: #endif
                    219:
                    220: void   iop_adjqparam(struct iop_softc *, int);
                    221: void   iop_create_reconf_thread(void *);
                    222: int    iop_handle_reply(struct iop_softc *, u_int32_t);
                    223: int    iop_hrt_get(struct iop_softc *);
                    224: int    iop_hrt_get0(struct iop_softc *, struct i2o_hrt *, size_t);
                    225: void   iop_intr_event(struct device *, struct iop_msg *, void *);
                    226: int    iop_lct_get0(struct iop_softc *, struct i2o_lct *, size_t, u_int32_t);
                    227: void   iop_msg_poll(struct iop_softc *, struct iop_msg *, int);
                    228: void   iop_msg_wait(struct iop_softc *, struct iop_msg *, int);
                    229: int    iop_ofifo_init(struct iop_softc *);
                    230: int    iop_passthrough(struct iop_softc *, struct ioppt *);
                    231: int    iop_post(struct iop_softc *, u_int32_t *);
                    232: void   iop_reconf_thread(void *);
                    233: void   iop_release_mfa(struct iop_softc *, u_int32_t);
                    234: int    iop_reset(struct iop_softc *);
                    235: int    iop_status_get(struct iop_softc *, int);
                    236: int    iop_systab_set(struct iop_softc *);
                    237: void   iop_tfn_print(struct iop_softc *, struct i2o_fault_notify *);
                    238:
                    239: #ifdef I2ODEBUG
                    240: void   iop_reply_print(struct iop_softc *, struct i2o_reply *);
                    241: #endif
                    242:
                    243: cdev_decl(iop);
                    244:
                    245: static inline u_int32_t
                    246: iop_inl(struct iop_softc *sc, int off)
                    247: {
                    248:
                    249:        bus_space_barrier(sc->sc_iot, sc->sc_ioh, off, 4,
                    250:            BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ);
                    251:        return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, off));
                    252: }
                    253:
                    254: static inline void
                    255: iop_outl(struct iop_softc *sc, int off, u_int32_t val)
                    256: {
                    257:
                    258:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val);
                    259:        bus_space_barrier(sc->sc_iot, sc->sc_ioh, off, 4,
                    260:            BUS_SPACE_BARRIER_WRITE);
                    261: }
                    262:
                    263: /*
                    264:  * Initialise the IOP and our interface.
                    265:  */
                    266: void
                    267: iop_init(struct iop_softc *sc, const char *intrstr)
                    268: {
                    269:        struct iop_msg *im;
                    270:        u_int32_t mask;
                    271:        char ident[64];
                    272:        int rv, i, nsegs;
                    273:        int state = 0;
                    274:
                    275:        if (iop_ictxhashtbl == NULL) {
                    276:                iop_ictxhashtbl = hashinit(IOP_ICTXHASH_NBUCKETS, M_DEVBUF,
                    277:                    M_NOWAIT, &iop_ictxhash);
                    278:                if (iop_ictxhashtbl == NULL) {
                    279:                        printf("%s: cannot allocate hashtable\n",
                    280:                            sc->sc_dv.dv_xname);
                    281:                        return;
                    282:                }
                    283:        }
                    284:
                    285:        /* Reset the IOP and request status. */
                    286:        printf("I2O adapter");
                    287:
                    288:        /* Allocate a scratch DMA map for small miscellaneous shared data. */
                    289:        if (bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,
                    290:            BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_scr_dmamap) != 0) {
                    291:                printf("%s: cannot create scratch dmamap\n",
                    292:                    sc->sc_dv.dv_xname);
                    293:                return;
                    294:        }
                    295:        state++;
                    296:
                    297:        if (bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0,
                    298:            sc->sc_scr_seg, 1, &nsegs, BUS_DMA_NOWAIT) != 0) {
                    299:                printf("%s: cannot alloc scratch dmamem\n",
                    300:                    sc->sc_dv.dv_xname);
                    301:                goto bail_out;
                    302:        }
                    303:        state++;
                    304:
                    305:        if (bus_dmamem_map(sc->sc_dmat, sc->sc_scr_seg, nsegs, PAGE_SIZE,
                    306:            &sc->sc_scr, 0)) {
                    307:                printf("%s: cannot map scratch dmamem\n", sc->sc_dv.dv_xname);
                    308:                goto bail_out;
                    309:        }
                    310:        state++;
                    311:
                    312:        if (bus_dmamap_load(sc->sc_dmat, sc->sc_scr_dmamap, sc->sc_scr,
                    313:            PAGE_SIZE, NULL, BUS_DMA_NOWAIT)) {
                    314:                printf("%s: cannot load scratch dmamap\n", sc->sc_dv.dv_xname);
                    315:                goto bail_out;
                    316:        }
                    317:        state++;
                    318:
                    319:        if ((rv = iop_reset(sc)) != 0) {
                    320:                printf("%s: not responding (reset)\n", sc->sc_dv.dv_xname);
                    321:                goto bail_out;
                    322:        }
                    323:        if ((rv = iop_status_get(sc, 1)) != 0) {
                    324:                printf("%s: not responding (get status)\n",
                    325:                    sc->sc_dv.dv_xname);
                    326:                goto bail_out;
                    327:        }
                    328:        sc->sc_flags |= IOP_HAVESTATUS;
                    329:        iop_strvis(sc, sc->sc_status.productid,
                    330:            sizeof(sc->sc_status.productid), ident, sizeof(ident));
                    331:        printf(" <%s>\n", ident);
                    332:
                    333: #ifdef I2ODEBUG
                    334:        printf("%s: orgid=0x%04x version=%d\n", sc->sc_dv.dv_xname,
                    335:            letoh16(sc->sc_status.orgid),
                    336:            (letoh32(sc->sc_status.segnumber) >> 12) & 15);
                    337:        printf("%s: type want have cbase\n", sc->sc_dv.dv_xname);
                    338:        printf("%s: mem  %04x %04x %08x\n", sc->sc_dv.dv_xname,
                    339:            letoh32(sc->sc_status.desiredprivmemsize),
                    340:            letoh32(sc->sc_status.currentprivmemsize),
                    341:            letoh32(sc->sc_status.currentprivmembase));
                    342:        printf("%s: i/o  %04x %04x %08x\n", sc->sc_dv.dv_xname,
                    343:            letoh32(sc->sc_status.desiredpriviosize),
                    344:            letoh32(sc->sc_status.currentpriviosize),
                    345:            letoh32(sc->sc_status.currentpriviobase));
                    346: #endif
                    347:
                    348:        sc->sc_maxob = letoh32(sc->sc_status.maxoutboundmframes);
                    349:        if (sc->sc_maxob > IOP_MAX_OUTBOUND)
                    350:                sc->sc_maxob = IOP_MAX_OUTBOUND;
                    351:        sc->sc_maxib = letoh32(sc->sc_status.maxinboundmframes);
                    352:        if (sc->sc_maxib > IOP_MAX_INBOUND)
                    353:                sc->sc_maxib = IOP_MAX_INBOUND;
                    354:
                    355:        /* Allocate message wrappers. */
                    356:        im = malloc(sizeof(*im) * sc->sc_maxib, M_DEVBUF, M_NOWAIT);
                    357:        if (!im) {
                    358:                printf("%s: couldn't allocate message", sc->sc_dv.dv_xname);
                    359:                goto bail_out;
                    360:        }
                    361:        state++;
                    362:
                    363:        bzero(im, sizeof(*im) * sc->sc_maxib);
                    364:        sc->sc_ims = im;
                    365:        SLIST_INIT(&sc->sc_im_freelist);
                    366:
                    367:        for (i = 0; i < sc->sc_maxib; i++, im++) {
                    368:                rv = bus_dmamap_create(sc->sc_dmat, IOP_MAX_XFER,
                    369:                    IOP_MAX_SEGS, IOP_MAX_XFER, 0,
                    370:                    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
                    371:                    &im->im_xfer[0].ix_map);
                    372:                if (rv != 0) {
                    373:                        printf("%s: couldn't create dmamap (%d)",
                    374:                            sc->sc_dv.dv_xname, rv);
                    375:                        goto bail_out;
                    376:                }
                    377:
                    378:                im->im_tctx = i;
                    379:                SLIST_INSERT_HEAD(&sc->sc_im_freelist, im, im_chain);
                    380:        }
                    381:
                    382:        /* Initalise the IOP's outbound FIFO. */
                    383:        if (iop_ofifo_init(sc) != 0) {
                    384:                printf("%s: unable to init outbound FIFO\n",
                    385:                    sc->sc_dv.dv_xname);
                    386:                goto bail_out;
                    387:        }
                    388:
                    389:        /* Configure shutdown hook before we start any device activity. */
                    390:        if (iop_sdh == NULL)
                    391:                iop_sdh = shutdownhook_establish(iop_shutdown, NULL);
                    392:
                    393:        /* Ensure interrupts are enabled at the IOP. */
                    394:        mask = iop_inl(sc, IOP_REG_INTR_MASK);
                    395:        iop_outl(sc, IOP_REG_INTR_MASK, mask & ~IOP_INTR_OFIFO);
                    396:
                    397:        if (intrstr != NULL)
                    398:                printf("%s: interrupting at %s\n", sc->sc_dv.dv_xname,
                    399:                    intrstr);
                    400:
                    401: #ifdef I2ODEBUG
                    402:        printf("%s: queue depths: inbound %d/%d, outbound %d/%d\n",
                    403:            sc->sc_dv.dv_xname, sc->sc_maxib,
                    404:            letoh32(sc->sc_status.maxinboundmframes),
                    405:            sc->sc_maxob, letoh32(sc->sc_status.maxoutboundmframes));
                    406: #endif
                    407:
                    408:        lockinit(&sc->sc_conflock, PRIBIO, "iopconf", 0, 0);
                    409:
                    410:        startuphook_establish((void (*)(void *))iop_config_interrupts, sc);
                    411:        return;
                    412:
                    413:  bail_out:
                    414:        if (state > 4)
                    415:                free(im, M_DEVBUF);
                    416:        if (state > 3)
                    417:                bus_dmamap_unload(sc->sc_dmat, sc->sc_scr_dmamap);
                    418:        if (state > 2)
                    419:                bus_dmamem_unmap(sc->sc_dmat, sc->sc_scr, PAGE_SIZE);
                    420:        if (state > 1)
                    421:                bus_dmamem_free(sc->sc_dmat, sc->sc_scr_seg, nsegs);
                    422:        if (state > 0)
                    423:                bus_dmamap_destroy(sc->sc_dmat, sc->sc_scr_dmamap);
                    424: }
                    425:
                    426: /*
                    427:  * Perform autoconfiguration tasks.
                    428:  */
                    429: void
                    430: iop_config_interrupts(struct device *self)
                    431: {
                    432:        struct iop_softc *sc, *iop;
                    433:        struct i2o_systab_entry *ste;
                    434:        int rv, i, niop;
                    435:
                    436:        sc = (struct iop_softc *)self;
                    437:        LIST_INIT(&sc->sc_iilist);
                    438:
                    439:        printf("%s: configuring...\n", sc->sc_dv.dv_xname);
                    440:
                    441:        if (iop_hrt_get(sc) != 0) {
                    442:                printf("%s: unable to retrieve HRT\n", sc->sc_dv.dv_xname);
                    443:                return;
                    444:        }
                    445:
                    446:        /*
                    447:         * Build the system table.
                    448:         */
                    449:        if (iop_systab == NULL) {
                    450:                for (i = 0, niop = 0; i < iop_cd.cd_ndevs; i++) {
                    451:                        iop = (struct iop_softc *)device_lookup(&iop_cd, i);
                    452:                        if (iop == NULL)
                    453:                                continue;
                    454:                        if ((iop->sc_flags & IOP_HAVESTATUS) == 0)
                    455:                                continue;
                    456:                        if (iop_status_get(iop, 1) != 0) {
                    457:                                printf("%s: unable to retrieve status\n",
                    458:                                    sc->sc_dv.dv_xname);
                    459:                                iop->sc_flags &= ~IOP_HAVESTATUS;
                    460:                                continue;
                    461:                        }
                    462:                        niop++;
                    463:                }
                    464:                if (niop == 0)
                    465:                        return;
                    466:
                    467:                i = sizeof(struct i2o_systab_entry) * (niop - 1) +
                    468:                    sizeof(struct i2o_systab);
                    469:                iop_systab_size = i;
                    470:                iop_systab = malloc(i, M_DEVBUF, M_NOWAIT);
                    471:                if (!iop_systab)
                    472:                        return;
                    473:
                    474:                bzero(iop_systab, i);
                    475:                iop_systab->numentries = niop;
                    476:                iop_systab->version = I2O_VERSION_11;
                    477:
                    478:                for (i = 0, ste = iop_systab->entry; i < iop_cd.cd_ndevs; i++)
                    479:                    {
                    480:                        iop = (struct iop_softc *)device_lookup(&iop_cd, i);
                    481:                        if (iop == NULL)
                    482:                                continue;
                    483:                        if ((iop->sc_flags & IOP_HAVESTATUS) == 0)
                    484:                                continue;
                    485:
                    486:                        ste->orgid = iop->sc_status.orgid;
                    487:                        ste->iopid = iop->sc_dv.dv_unit + 2;
                    488:                        ste->segnumber =
                    489:                            htole32(letoh32(iop->sc_status.segnumber) & ~4095);
                    490:                        ste->iopcaps = iop->sc_status.iopcaps;
                    491:                        ste->inboundmsgframesize =
                    492:                            iop->sc_status.inboundmframesize;
                    493:                        ste->inboundmsgportaddresslow =
                    494:                            htole32(iop->sc_memaddr + IOP_REG_IFIFO);
                    495:                        ste++;
                    496:                }
                    497:        }
                    498:
                    499:        /*
                    500:         * Post the system table to the IOP and bring it to the OPERATIONAL
                    501:         * state.
                    502:         */
                    503:        if (iop_systab_set(sc) != 0) {
                    504:                printf("%s: unable to set system table\n", sc->sc_dv.dv_xname);
                    505:                return;
                    506:        }
                    507:        if (iop_simple_cmd(sc, I2O_TID_IOP, I2O_EXEC_SYS_ENABLE, IOP_ICTX, 1,
                    508:            30000) != 0) {
                    509:                printf("%s: unable to enable system\n", sc->sc_dv.dv_xname);
                    510:                return;
                    511:        }
                    512:
                    513:        /*
                    514:         * Set up an event handler for this IOP.
                    515:         */
                    516:        sc->sc_eventii.ii_dv = self;
                    517:        sc->sc_eventii.ii_intr = iop_intr_event;
                    518:        sc->sc_eventii.ii_flags = II_DISCARD | II_UTILITY;
                    519:        sc->sc_eventii.ii_tid = I2O_TID_IOP;
                    520:        iop_initiator_register(sc, &sc->sc_eventii);
                    521:
                    522:        rv = iop_util_eventreg(sc, &sc->sc_eventii,
                    523:            I2O_EVENT_EXEC_RESOURCE_LIMITS |
                    524:            I2O_EVENT_EXEC_CONNECTION_FAIL |
                    525:            I2O_EVENT_EXEC_ADAPTER_FAULT |
                    526:            I2O_EVENT_EXEC_POWER_FAIL |
                    527:            I2O_EVENT_EXEC_RESET_PENDING |
                    528:            I2O_EVENT_EXEC_RESET_IMMINENT |
                    529:            I2O_EVENT_EXEC_HARDWARE_FAIL |
                    530:            I2O_EVENT_EXEC_XCT_CHANGE |
                    531:            I2O_EVENT_EXEC_DDM_AVAILIBILITY |
                    532:            I2O_EVENT_GEN_DEVICE_RESET |
                    533:            I2O_EVENT_GEN_STATE_CHANGE |
                    534:            I2O_EVENT_GEN_GENERAL_WARNING);
                    535:        if (rv != 0) {
                    536:                printf("%s: unable to register for events",
                    537:                    sc->sc_dv.dv_xname);
                    538:                return;
                    539:        }
                    540:
                    541: #ifdef notyet
                    542:        /* Attempt to match and attach a product-specific extension. */
                    543:        ia.ia_class = I2O_CLASS_ANY;
                    544:        ia.ia_tid = I2O_TID_IOP;
                    545:        config_found_sm(self, &ia, iop_vendor_print, iop_submatch);
                    546: #endif
                    547:
                    548:        lockmgr(&sc->sc_conflock, LK_EXCLUSIVE, NULL);
                    549:        if ((rv = iop_reconfigure(sc, 0)) == -1) {
                    550:                printf("%s: configure failed (%d)\n", sc->sc_dv.dv_xname, rv);
                    551:                return;
                    552:        }
                    553:        lockmgr(&sc->sc_conflock, LK_RELEASE, NULL);
                    554:        kthread_create_deferred(iop_create_reconf_thread, sc);
                    555: }
                    556:
                    557: /*
                    558:  * Create the reconfiguration thread.  Called after the standard kernel
                    559:  * threads have been created.
                    560:  */
                    561: void
                    562: iop_create_reconf_thread(void *cookie)
                    563: {
                    564:        struct iop_softc *sc;
                    565:        int rv;
                    566:
                    567:        sc = cookie;
                    568:        sc->sc_flags |= IOP_ONLINE;
                    569:
                    570:        rv = kthread_create(iop_reconf_thread, sc, &sc->sc_reconf_proc,
                    571:            "%s", sc->sc_dv.dv_xname);
                    572:        if (rv != 0) {
                    573:                printf("%s: unable to create reconfiguration thread (%d)",
                    574:                    sc->sc_dv.dv_xname, rv);
                    575:                return;
                    576:        }
                    577: }
                    578:
                    579: /*
                    580:  * Reconfiguration thread; listens for LCT change notification, and
                    581:  * initiates re-configuration if received.
                    582:  */
                    583: void
                    584: iop_reconf_thread(void *cookie)
                    585: {
                    586:        struct iop_softc *sc = cookie;
                    587:        struct i2o_lct lct;
                    588:        u_int32_t chgind;
                    589:        int rv;
                    590:
                    591:        chgind = sc->sc_chgind + 1;
                    592:
                    593:        for (;;) {
                    594:                DPRINTF(("%s: async reconfig: requested 0x%08x\n",
                    595:                    sc->sc_dv.dv_xname, chgind));
                    596:
                    597:                rv = iop_lct_get0(sc, &lct, sizeof(lct), chgind);
                    598:
                    599:                DPRINTF(("%s: async reconfig: notified (0x%08x, %d)\n",
                    600:                    sc->sc_dv.dv_xname, letoh32(lct.changeindicator), rv));
                    601:
                    602:                if (rv == 0 &&
                    603:                    lockmgr(&sc->sc_conflock, LK_EXCLUSIVE, NULL) == 0) {
                    604:                        iop_reconfigure(sc, letoh32(lct.changeindicator));
                    605:                        chgind = sc->sc_chgind + 1;
                    606:                        lockmgr(&sc->sc_conflock, LK_RELEASE, NULL);
                    607:                }
                    608:
                    609:                tsleep(iop_reconf_thread, PWAIT, "iopzzz", hz * 5);
                    610:        }
                    611: }
                    612:
                    613: /*
                    614:  * Reconfigure: find new and removed devices.
                    615:  */
                    616: int
                    617: iop_reconfigure(struct iop_softc *sc, u_int chgind)
                    618: {
                    619:        struct iop_msg *im;
                    620:        struct i2o_hba_bus_scan mf;
                    621:        struct i2o_lct_entry *le;
                    622:        struct iop_initiator *ii, *nextii;
                    623:        int rv, tid, i;
                    624:
                    625:        /*
                    626:         * If the reconfiguration request isn't the result of LCT change
                    627:         * notification, then be more thorough: ask all bus ports to scan
                    628:         * their busses.  Wait up to 5 minutes for each bus port to complete
                    629:         * the request.
                    630:         */
                    631:        if (chgind == 0) {
                    632:                if ((rv = iop_lct_get(sc)) != 0) {
                    633:                        DPRINTF(("iop_reconfigure: unable to read LCT\n"));
                    634:                        return (rv);
                    635:                }
                    636:
                    637:                le = sc->sc_lct->entry;
                    638:                for (i = 0; i < sc->sc_nlctent; i++, le++) {
                    639:                        if ((letoh16(le->classid) & I2O_CLASS_MASK) !=
                    640:                            I2O_CLASS_BUS_ADAPTER_PORT)
                    641:                                continue;
                    642:                        tid = letoh16(le->localtid) & I2O_CLASS_MASK;
                    643:
                    644:                        im = iop_msg_alloc(sc, NULL, IM_WAIT);
                    645:
                    646:                        mf.msgflags = I2O_MSGFLAGS(i2o_hba_bus_scan);
                    647:                        mf.msgfunc = I2O_MSGFUNC(tid, I2O_HBA_BUS_SCAN);
                    648:                        mf.msgictx = IOP_ICTX;
                    649:                        mf.msgtctx = im->im_tctx;
                    650:
                    651:                        DPRINTF(("%s: scanning bus %d\n", sc->sc_dv.dv_xname,
                    652:                            tid));
                    653:
                    654:                        rv = iop_msg_post(sc, im, &mf, 5*60*1000);
                    655:                        iop_msg_free(sc, im);
                    656: #ifdef I2ODEBUG
                    657:                        if (rv != 0)
                    658:                                printf("%s: bus scan failed, status =%d\n",
                    659:                                    sc->sc_dv.dv_xname, rv);
                    660: #endif
                    661:                }
                    662:        } else if (chgind <= sc->sc_chgind) {
                    663:                DPRINTF(("%s: LCT unchanged (async)\n", sc->sc_dv.dv_xname));
                    664:                return (0);
                    665:        }
                    666:
                    667:        /* Re-read the LCT and determine if it has changed. */
                    668:        if ((rv = iop_lct_get(sc)) != 0) {
                    669:                DPRINTF(("iop_reconfigure: unable to re-read LCT\n"));
                    670:                return (rv);
                    671:        }
                    672:        DPRINTF(("%s: %d LCT entries\n", sc->sc_dv.dv_xname, sc->sc_nlctent));
                    673:
                    674:        chgind = letoh32(sc->sc_lct->changeindicator);
                    675:        if (chgind == sc->sc_chgind) {
                    676:                DPRINTF(("%s: LCT unchanged\n", sc->sc_dv.dv_xname));
                    677:                return (0);
                    678:        }
                    679:        DPRINTF(("%s: LCT changed\n", sc->sc_dv.dv_xname));
                    680:        sc->sc_chgind = chgind;
                    681:
                    682:        if (sc->sc_tidmap != NULL)
                    683:                free(sc->sc_tidmap, M_DEVBUF);
                    684:        sc->sc_tidmap = malloc(sc->sc_nlctent * sizeof(struct iop_tidmap),
                    685:            M_DEVBUF, M_NOWAIT);
                    686:        if (!sc->sc_tidmap) {
                    687:                DPRINTF(("iop_reconfigure: out of memory\n"));
                    688:                return (ENOMEM);
                    689:        }
                    690:        bzero(sc->sc_tidmap, sc->sc_nlctent * sizeof(struct iop_tidmap));
                    691:
                    692:        /* Allow 1 queued command per device while we're configuring. */
                    693:        iop_adjqparam(sc, 1);
                    694:
                    695:        /*
                    696:         * Match and attach child devices.  We configure high-level devices
                    697:         * first so that any claims will propagate throughout the LCT,
                    698:         * hopefully masking off aliased devices as a result.
                    699:         *
                    700:         * Re-reading the LCT at this point is a little dangerous, but we'll
                    701:         * trust the IOP (and the operator) to behave itself...
                    702:         */
                    703:        iop_configure_devices(sc, IC_CONFIGURE | IC_PRIORITY,
                    704:            IC_CONFIGURE | IC_PRIORITY);
                    705:        if ((rv = iop_lct_get(sc)) != 0)
                    706:                DPRINTF(("iop_reconfigure: unable to re-read LCT\n"));
                    707:        iop_configure_devices(sc, IC_CONFIGURE | IC_PRIORITY,
                    708:            IC_CONFIGURE);
                    709:
                    710:        for (ii = LIST_FIRST(&sc->sc_iilist); ii != NULL; ii = nextii) {
                    711:                nextii = LIST_NEXT(ii, ii_list);
                    712:
                    713:                /* Detach devices that were configured, but are now gone. */
                    714:                for (i = 0; i < sc->sc_nlctent; i++)
                    715:                        if (ii->ii_tid == sc->sc_tidmap[i].it_tid)
                    716:                                break;
                    717:                if (i == sc->sc_nlctent ||
                    718:                    (sc->sc_tidmap[i].it_flags & IT_CONFIGURED) == 0)
                    719:                        config_detach(ii->ii_dv, DETACH_FORCE);
                    720:
                    721:                /*
                    722:                 * Tell initiators that existed before the re-configuration
                    723:                 * to re-configure.
                    724:                 */
                    725:                if (ii->ii_reconfig == NULL)
                    726:                        continue;
                    727:                if ((rv = (*ii->ii_reconfig)(ii->ii_dv)) != 0)
                    728:                        printf("%s: %s failed reconfigure (%d)\n",
                    729:                            sc->sc_dv.dv_xname, ii->ii_dv->dv_xname, rv);
                    730:        }
                    731:
                    732:        /* Re-adjust queue parameters and return. */
                    733:        if (sc->sc_nii != 0)
                    734:                iop_adjqparam(sc, (sc->sc_maxib - sc->sc_nuii - IOP_MF_RESERVE)
                    735:                    / sc->sc_nii);
                    736:
                    737:        return (0);
                    738: }
                    739:
                    740: /*
                    741:  * Configure I2O devices into the system.
                    742:  */
                    743: void
                    744: iop_configure_devices(struct iop_softc *sc, int mask, int maskval)
                    745: {
                    746:        struct iop_attach_args ia;
                    747:        struct iop_initiator *ii;
                    748:        const struct i2o_lct_entry *le;
                    749:        struct device *dv;
                    750:        int i, j, nent;
                    751:        u_int usertid;
                    752:
                    753:        nent = sc->sc_nlctent;
                    754:        for (i = 0, le = sc->sc_lct->entry; i < nent; i++, le++) {
                    755:                sc->sc_tidmap[i].it_tid =
                    756:                    letoh16(le->localtid) & I2O_LCT_ENTRY_TID_MASK;
                    757:
                    758:                /* Ignore the device if it's in use. */
                    759:                usertid = letoh32(le->usertid) & I2O_LCT_ENTRY_TID_MASK;
                    760:                if (usertid != I2O_TID_NONE && usertid != I2O_TID_HOST)
                    761:                        continue;
                    762:
                    763:                ia.ia_class = letoh16(le->classid) & I2O_CLASS_MASK;
                    764:                ia.ia_tid = sc->sc_tidmap[i].it_tid;
                    765:
                    766:                /* Ignore uninteresting devices. */
                    767:                for (j = 0; j < sizeof(iop_class) / sizeof(iop_class[0]); j++)
                    768:                        if (iop_class[j].ic_class == ia.ia_class)
                    769:                                break;
                    770:                if (j < sizeof(iop_class) / sizeof(iop_class[0]) &&
                    771:                    (iop_class[j].ic_flags & mask) != maskval)
                    772:                        continue;
                    773:
                    774:                /*
                    775:                 * Try to configure the device only if it's not already
                    776:                 * configured.
                    777:                 */
                    778:                LIST_FOREACH(ii, &sc->sc_iilist, ii_list) {
                    779:                        if (ia.ia_tid == ii->ii_tid) {
                    780:                                sc->sc_tidmap[i].it_flags |= IT_CONFIGURED;
                    781:                                strlcpy(sc->sc_tidmap[i].it_dvname,
                    782:                                    ii->ii_dv->dv_xname,
                    783:                                    sizeof sc->sc_tidmap[i].it_dvname);
                    784:                                break;
                    785:                        }
                    786:                }
                    787:                if (ii != NULL)
                    788:                        continue;
                    789:                dv = config_found_sm(&sc->sc_dv, &ia, iop_print, iop_submatch);
                    790:                if (dv != NULL) {
                    791:                        sc->sc_tidmap[i].it_flags |= IT_CONFIGURED;
                    792:                        strlcpy(sc->sc_tidmap[i].it_dvname, dv->dv_xname,
                    793:                            sizeof sc->sc_tidmap[i].it_dvname);
                    794:                }
                    795:        }
                    796: }
                    797:
                    798: /*
                    799:  * Adjust queue parameters for all child devices.
                    800:  */
                    801: void
                    802: iop_adjqparam(struct iop_softc *sc, int mpi)
                    803: {
                    804:        struct iop_initiator *ii;
                    805:
                    806:        LIST_FOREACH(ii, &sc->sc_iilist, ii_list)
                    807:                if (ii->ii_adjqparam != NULL)
                    808:                        (*ii->ii_adjqparam)(ii->ii_dv, mpi);
                    809: }
                    810:
                    811: void
                    812: iop_devinfo(int class, char *devinfo, size_t di_len)
                    813: {
                    814: #ifdef I2OVERBOSE
                    815:        int i;
                    816:
                    817:        for (i = 0; i < sizeof(iop_class) / sizeof(iop_class[0]); i++)
                    818:                if (class == iop_class[i].ic_class)
                    819:                        break;
                    820:
                    821:        if (i == sizeof(iop_class) / sizeof(iop_class[0]))
                    822:                snprintf(devinfo, di_len, "device (class 0x%x)", class);
                    823:        else
                    824:                strlcpy(devinfo, iop_class[i].ic_caption, di_len);
                    825: #else
                    826:
                    827:        snprintf(devinfo, di_len, "device (class 0x%x)", class);
                    828: #endif
                    829: }
                    830:
                    831: int
                    832: iop_print(void *aux, const char *pnp)
                    833: {
                    834:        struct iop_attach_args *ia;
                    835:        char devinfo[256];
                    836:
                    837:        ia = aux;
                    838:
                    839:        if (pnp != NULL) {
                    840:                iop_devinfo(ia->ia_class, devinfo, sizeof devinfo);
                    841:                printf("%s at %s", devinfo, pnp);
                    842:        }
                    843:        printf(" tid %d", ia->ia_tid);
                    844:        return (UNCONF);
                    845: }
                    846:
                    847: #ifdef notyet
                    848: int
                    849: iop_vendor_print(void *aux, const char *pnp)
                    850: {
                    851:
                    852:        if (pnp != NULL)
                    853:                printf("vendor specific extension at %s", pnp);
                    854:        return (UNCONF);
                    855: }
                    856: #endif
                    857:
                    858: int
                    859: iop_submatch(struct device *parent, void *vcf, void *aux)
                    860: {
                    861:        struct cfdata *cf = vcf;
                    862:        struct iop_attach_args *ia;
                    863:
                    864:        ia = aux;
                    865:
                    866:        if (cf->iopcf_tid != IOPCF_TID_DEFAULT && cf->iopcf_tid != ia->ia_tid)
                    867:                return (0);
                    868:
                    869:        return ((*cf->cf_attach->ca_match)(parent, cf, aux));
                    870: }
                    871:
                    872: /*
                    873:  * Shut down all configured IOPs.
                    874:  */
                    875: void
                    876: iop_shutdown(void *junk)
                    877: {
                    878:        struct iop_softc *sc;
                    879:        int i;
                    880:
                    881:        printf("shutting down iop devices...");
                    882:
                    883:        for (i = 0; i < iop_cd.cd_ndevs; i++) {
                    884:                if (!(sc = (struct iop_softc *)device_lookup(&iop_cd, i)))
                    885:                        continue;
                    886:                if ((sc->sc_flags & IOP_ONLINE) == 0)
                    887:                        continue;
                    888:
                    889:                iop_simple_cmd(sc, I2O_TID_IOP, I2O_EXEC_SYS_QUIESCE, IOP_ICTX,
                    890:                    0, 5000);
                    891:
                    892:                if (letoh16(sc->sc_status.orgid) != I2O_ORG_AMI) {
                    893:                        /*
                    894:                         * Some AMI firmware revisions will go to sleep and
                    895:                         * never come back after this.
                    896:                         */
                    897:                        iop_simple_cmd(sc, I2O_TID_IOP, I2O_EXEC_IOP_CLEAR,
                    898:                            IOP_ICTX, 0, 1000);
                    899:                }
                    900:        }
                    901:
                    902:        /* Wait.  Some boards could still be flushing, stupidly enough. */
                    903:        delay(5000*1000);
                    904:        printf(" done.\n");
                    905: }
                    906:
                    907: /*
                    908:  * Retrieve IOP status.
                    909:  */
                    910: int
                    911: iop_status_get(struct iop_softc *sc, int nosleep)
                    912: {
                    913:        struct i2o_exec_status_get mf;
                    914:        paddr_t pa = sc->sc_scr_seg->ds_addr;
                    915:        struct i2o_status *st = (struct i2o_status *)sc->sc_scr;
                    916:        int rv;
                    917:
                    918:        mf.msgflags = I2O_MSGFLAGS(i2o_exec_status_get);
                    919:        mf.msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_STATUS_GET);
                    920:        mf.reserved[0] = 0;
                    921:        mf.reserved[1] = 0;
                    922:        mf.reserved[2] = 0;
                    923:        mf.reserved[3] = 0;
                    924:        mf.addrlow = pa & ~(u_int32_t)0;
                    925:        mf.addrhigh = sizeof pa > sizeof mf.addrlow ? pa >> 32 : 0;
                    926:        mf.length = sizeof(*st);
                    927:
                    928:        bzero(st, sizeof(*st));
                    929:        bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0, sizeof(*st),
                    930:            BUS_DMASYNC_PREREAD);
                    931:
                    932:        if ((rv = iop_post(sc, (u_int32_t *)&mf)))
                    933:                return (rv);
                    934:
                    935:        /* XXX */
                    936:        POLL(2500,
                    937:            (bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0,
                    938:                sizeof(*st), BUS_DMASYNC_POSTREAD), st->syncbyte == 0xff));
                    939:
                    940:        if (st->syncbyte != 0xff)
                    941:                return (EIO);
                    942:
                    943:        bcopy(st, &sc->sc_status, sizeof(sc->sc_status));
                    944:        return (0);
                    945: }
                    946:
                    947: /*
                    948:  * Initalize and populate the IOP's outbound FIFO.
                    949:  */
                    950: int
                    951: iop_ofifo_init(struct iop_softc *sc)
                    952: {
                    953:        bus_addr_t addr;
                    954:        bus_dma_segment_t seg;
                    955:        struct i2o_exec_outbound_init *mf;
                    956:        u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
                    957:        u_int32_t *sw = (u_int32_t *)sc->sc_scr;
                    958:        int i, rseg, rv;
                    959:
                    960:        mf = (struct i2o_exec_outbound_init *)mb;
                    961:        mf->msgflags = I2O_MSGFLAGS(i2o_exec_outbound_init);
                    962:        mf->msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_OUTBOUND_INIT);
                    963:        mf->msgictx = IOP_ICTX;
                    964:        mf->msgtctx = 0;
                    965:        mf->pagesize = PAGE_SIZE;
                    966:        mf->flags = IOP_INIT_CODE | ((IOP_MAX_MSG_SIZE >> 2) << 16);
                    967:        mb[sizeof(*mf) / sizeof(u_int32_t) + 0] = sizeof(*sw) |
                    968:            I2O_SGL_SIMPLE | I2O_SGL_END_BUFFER | I2O_SGL_END;
                    969:        mb[sizeof(*mf) / sizeof(u_int32_t) + 1] = sc->sc_scr_seg->ds_addr;
                    970:        mb[0] += 2 << 16;
                    971:
                    972:        *sw = 0;
                    973:        bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0, sizeof(*sw),
                    974:            BUS_DMASYNC_PREREAD);
                    975:
                    976:        /*
                    977:         * The I2O spec says that there are two SGLs: one for the status
                    978:         * word, and one for a list of discarded MFAs.  It continues to say
                    979:         * that if you don't want to get the list of MFAs, an IGNORE SGL is
                    980:         * necessary; this isn't the case (and is in fact a bad thing).
                    981:         */
                    982:        if ((rv = iop_post(sc, mb)))
                    983:                return (rv);
                    984:
                    985:        /* XXX */
                    986:        POLL(5000,
                    987:            (bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0, sizeof(*sw),
                    988:            BUS_DMASYNC_POSTREAD),
                    989:            *sw == htole32(I2O_EXEC_OUTBOUND_INIT_COMPLETE)));
                    990:        if (*sw != htole32(I2O_EXEC_OUTBOUND_INIT_COMPLETE)) {
                    991:                printf("%s: outbound FIFO init failed (%d)\n",
                    992:                    sc->sc_dv.dv_xname, letoh32(*sw));
                    993:                return (EIO);
                    994:        }
                    995:
                    996:        /* Allocate DMA safe memory for the reply frames. */
                    997:        if (sc->sc_rep_phys == 0) {
                    998:                sc->sc_rep_size = sc->sc_maxob * IOP_MAX_MSG_SIZE;
                    999:
                   1000:                rv = bus_dmamem_alloc(sc->sc_dmat, sc->sc_rep_size, PAGE_SIZE,
                   1001:                    0, &seg, 1, &rseg, BUS_DMA_NOWAIT);
                   1002:                if (rv != 0) {
                   1003:                        printf("%s: dma alloc = %d\n", sc->sc_dv.dv_xname,
                   1004:                           rv);
                   1005:                        return (rv);
                   1006:                }
                   1007:
                   1008:                rv = bus_dmamem_map(sc->sc_dmat, &seg, rseg, sc->sc_rep_size,
                   1009:                    &sc->sc_rep, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
                   1010:                if (rv != 0) {
                   1011:                        printf("%s: dma map = %d\n", sc->sc_dv.dv_xname, rv);
                   1012:                        return (rv);
                   1013:                }
                   1014:
                   1015:                rv = bus_dmamap_create(sc->sc_dmat, sc->sc_rep_size, 1,
                   1016:                    sc->sc_rep_size, 0, BUS_DMA_NOWAIT, &sc->sc_rep_dmamap);
                   1017:                if (rv != 0) {
                   1018:                        printf("%s: dma create = %d\n", sc->sc_dv.dv_xname,
                   1019:                            rv);
                   1020:                        return (rv);
                   1021:                }
                   1022:
                   1023:                rv = bus_dmamap_load(sc->sc_dmat, sc->sc_rep_dmamap,
                   1024:                    sc->sc_rep, sc->sc_rep_size, NULL, BUS_DMA_NOWAIT);
                   1025:                if (rv != 0) {
                   1026:                        printf("%s: dma load = %d\n", sc->sc_dv.dv_xname, rv);
                   1027:                        return (rv);
                   1028:                }
                   1029:
                   1030:                sc->sc_rep_phys = sc->sc_rep_dmamap->dm_segs[0].ds_addr;
                   1031:        }
                   1032:
                   1033:        /* Populate the outbound FIFO. */
                   1034:        for (i = sc->sc_maxob, addr = sc->sc_rep_phys; i != 0; i--) {
                   1035:                iop_outl(sc, IOP_REG_OFIFO, (u_int32_t)addr);
                   1036:                addr += IOP_MAX_MSG_SIZE;
                   1037:        }
                   1038:
                   1039:        return (0);
                   1040: }
                   1041:
                   1042: /*
                   1043:  * Read the specified number of bytes from the IOP's hardware resource table.
                   1044:  */
                   1045: int
                   1046: iop_hrt_get0(struct iop_softc *sc, struct i2o_hrt *hrt, size_t size)
                   1047: {
                   1048:        struct iop_msg *im;
                   1049:        struct i2o_exec_hrt_get *mf;
                   1050:        u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
                   1051:        int rv;
                   1052:
                   1053:        im = iop_msg_alloc(sc, NULL, IM_WAIT);
                   1054:        mf = (struct i2o_exec_hrt_get *)mb;
                   1055:        mf->msgflags = I2O_MSGFLAGS(i2o_exec_hrt_get);
                   1056:        mf->msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_HRT_GET);
                   1057:        mf->msgictx = IOP_ICTX;
                   1058:        mf->msgtctx = im->im_tctx;
                   1059:
                   1060:        iop_msg_map(sc, im, mb, hrt, size, 0);
                   1061:        rv = iop_msg_post(sc, im, mb, 30000);
                   1062:        iop_msg_unmap(sc, im);
                   1063:        iop_msg_free(sc, im);
                   1064:        return (rv);
                   1065: }
                   1066:
                   1067: /*
                   1068:  * Read the IOP's hardware resource table.
                   1069:  */
                   1070: int
                   1071: iop_hrt_get(struct iop_softc *sc)
                   1072: {
                   1073:        struct i2o_hrt hrthdr, *hrt;
                   1074:        size_t size;
                   1075:        int rv;
                   1076:
                   1077:        rv = iop_hrt_get0(sc, &hrthdr, sizeof(hrthdr));
                   1078:        if (rv != 0)
                   1079:                return (rv);
                   1080:
                   1081:        DPRINTF(("%s: %d hrt entries\n", sc->sc_dv.dv_xname,
                   1082:            letoh16(hrthdr.numentries)));
                   1083:
                   1084:        size = sizeof(struct i2o_hrt) +
                   1085:            (letoh16(hrthdr.numentries) - 1) * sizeof(struct i2o_hrt_entry);
                   1086:        hrt = (struct i2o_hrt *)malloc(size, M_DEVBUF, M_NOWAIT);
                   1087:        if (!hrt)
                   1088:                return (ENOMEM);
                   1089:
                   1090:        if ((rv = iop_hrt_get0(sc, hrt, size)) != 0) {
                   1091:                free(hrt, M_DEVBUF);
                   1092:                return (rv);
                   1093:        }
                   1094:
                   1095:        if (sc->sc_hrt != NULL)
                   1096:                free(sc->sc_hrt, M_DEVBUF);
                   1097:        sc->sc_hrt = hrt;
                   1098:        return (0);
                   1099: }
                   1100:
                   1101: /*
                   1102:  * Request the specified number of bytes from the IOP's logical
                   1103:  * configuration table.  If a change indicator is specified, this
                   1104:  * is a verbatim notification request, so the caller is prepared
                   1105:  * to wait indefinitely.
                   1106:  */
                   1107: int
                   1108: iop_lct_get0(struct iop_softc *sc, struct i2o_lct *lct, size_t size,
                   1109:             u_int32_t chgind)
                   1110: {
                   1111:        struct iop_msg *im;
                   1112:        struct i2o_exec_lct_notify *mf;
                   1113:        int rv;
                   1114:        u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
                   1115:
                   1116:        im = iop_msg_alloc(sc, NULL, IM_WAIT);
                   1117:        memset(lct, 0, size);
                   1118:
                   1119:        mf = (struct i2o_exec_lct_notify *)mb;
                   1120:        mf->msgflags = I2O_MSGFLAGS(i2o_exec_lct_notify);
                   1121:        mf->msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_LCT_NOTIFY);
                   1122:        mf->msgictx = IOP_ICTX;
                   1123:        mf->msgtctx = im->im_tctx;
                   1124:        mf->classid = I2O_CLASS_ANY;
                   1125:        mf->changeindicator = chgind;
                   1126:
                   1127: #ifdef I2ODEBUG
                   1128:        printf("iop_lct_get0: reading LCT");
                   1129:        if (chgind != 0)
                   1130:                printf(" (async)");
                   1131:        printf("\n");
                   1132: #endif
                   1133:
                   1134:        iop_msg_map(sc, im, mb, lct, size, 0);
                   1135:        rv = iop_msg_post(sc, im, mb, (chgind == 0 ? 120*1000 : 0));
                   1136:        iop_msg_unmap(sc, im);
                   1137:        iop_msg_free(sc, im);
                   1138:        return (rv);
                   1139: }
                   1140:
                   1141: /*
                   1142:  * Read the IOP's logical configuration table.
                   1143:  */
                   1144: int
                   1145: iop_lct_get(struct iop_softc *sc)
                   1146: {
                   1147:        size_t esize, size;
                   1148:        int rv;
                   1149:        struct i2o_lct *lct;
                   1150:
                   1151:        esize = letoh32(sc->sc_status.expectedlctsize);
                   1152:        lct = (struct i2o_lct *)malloc(esize, M_DEVBUF, M_WAITOK);
                   1153:        if (lct == NULL)
                   1154:                return (ENOMEM);
                   1155:
                   1156:        if ((rv = iop_lct_get0(sc, lct, esize, 0)) != 0) {
                   1157:                free(lct, M_DEVBUF);
                   1158:                return (rv);
                   1159:        }
                   1160:
                   1161:        size = letoh16(lct->tablesize) << 2;
                   1162:        if (esize != size) {
                   1163:                free(lct, M_DEVBUF);
                   1164:                lct = (struct i2o_lct *)malloc(size, M_DEVBUF, M_WAITOK);
                   1165:                if (lct == NULL)
                   1166:                        return (ENOMEM);
                   1167:
                   1168:                if ((rv = iop_lct_get0(sc, lct, size, 0)) != 0) {
                   1169:                        free(lct, M_DEVBUF);
                   1170:                        return (rv);
                   1171:                }
                   1172:        }
                   1173:
                   1174:        /* Swap in the new LCT. */
                   1175:        if (sc->sc_lct != NULL)
                   1176:                free(sc->sc_lct, M_DEVBUF);
                   1177:        sc->sc_lct = lct;
                   1178:        sc->sc_nlctent = ((letoh16(sc->sc_lct->tablesize) << 2) -
                   1179:            sizeof(struct i2o_lct) + sizeof(struct i2o_lct_entry)) /
                   1180:            sizeof(struct i2o_lct_entry);
                   1181:        return (0);
                   1182: }
                   1183:
                   1184: /*
                   1185:  * Request the specified parameter group from the target.  If an initiator
                   1186:  * is specified (a) don't wait for the operation to complete, but instead
                   1187:  * let the initiator's interrupt handler deal with the reply and (b) place a
                   1188:  * pointer to the parameter group op in the wrapper's `im_dvcontext' field.
                   1189:  */
                   1190: int
                   1191: iop_param_op(struct iop_softc *sc, int tid, struct iop_initiator *ii,
                   1192:     int write, int group, void *buf, size_t size)
                   1193: {
                   1194:        struct iop_msg *im;
                   1195:        struct i2o_util_params_op *mf;
                   1196:        struct i2o_reply *rf;
                   1197:        int rv, func, op;
                   1198:        struct iop_pgop *pgop;
                   1199:        u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
                   1200:
                   1201:        im = iop_msg_alloc(sc, ii, (ii == NULL ? IM_WAIT : 0) | IM_NOSTATUS);
                   1202:        if ((pgop = malloc(sizeof(*pgop), M_DEVBUF, M_WAITOK)) == NULL) {
                   1203:                iop_msg_free(sc, im);
                   1204:                return (ENOMEM);
                   1205:        }
                   1206:        if ((rf = malloc(sizeof(*rf), M_DEVBUF, M_WAITOK)) == NULL) {
                   1207:                iop_msg_free(sc, im);
                   1208:                free(pgop, M_DEVBUF);
                   1209:                return (ENOMEM);
                   1210:        }
                   1211:        im->im_dvcontext = pgop;
                   1212:        im->im_rb = rf;
                   1213:
                   1214:        if (write) {
                   1215:                func = I2O_UTIL_PARAMS_SET;
                   1216:                op = I2O_PARAMS_OP_FIELD_SET;
                   1217:        } else {
                   1218:                func = I2O_UTIL_PARAMS_GET;
                   1219:                op = I2O_PARAMS_OP_FIELD_GET;
                   1220:        }
                   1221:
                   1222:        mf = (struct i2o_util_params_op *)mb;
                   1223:        mf->msgflags = I2O_MSGFLAGS(i2o_util_params_op);
                   1224:        mf->msgfunc = I2O_MSGFUNC(tid, func);
                   1225:        mf->msgictx = IOP_ICTX;
                   1226:        mf->msgtctx = im->im_tctx;
                   1227:        mf->flags = 0;
                   1228:
                   1229:        pgop->olh.count = htole16(1);
                   1230:        pgop->olh.reserved = htole16(0);
                   1231:        pgop->oat.operation = htole16(op);
                   1232:        pgop->oat.fieldcount = htole16(0xffff);
                   1233:        pgop->oat.group = htole16(group);
                   1234:
                   1235:        memset(buf, 0, size);
                   1236:        iop_msg_map(sc, im, mb, pgop, sizeof(*pgop), 1);
                   1237:        iop_msg_map(sc, im, mb, buf, size, write);
                   1238:        rv = iop_msg_post(sc, im, mb, (ii == NULL ? 30000 : 0));
                   1239:
                   1240:        /* Detect errors; let partial transfers to count as success. */
                   1241:        if (ii == NULL && rv == 0) {
                   1242:                if (rf->reqstatus == I2O_STATUS_ERROR_PARTIAL_XFER &&
                   1243:                    rf->detail == htole16(I2O_DSC_UNKNOWN_ERROR))
                   1244:                        rv = 0;
                   1245:                else
                   1246:                        rv = (rf->reqstatus != 0 ? EIO : 0);
                   1247:        }
                   1248:
                   1249:        if (ii == NULL || rv != 0) {
                   1250:                iop_msg_unmap(sc, im);
                   1251:                iop_msg_free(sc, im);
                   1252:                free(pgop, M_DEVBUF);
                   1253:                free(rf, M_DEVBUF);
                   1254:        }
                   1255:
                   1256:        return (rv);
                   1257: }
                   1258:
                   1259: /*
                   1260:  * Execute a simple command (no parameters).
                   1261:  */
                   1262: int
                   1263: iop_simple_cmd(struct iop_softc *sc, int tid, int function, int ictx,
                   1264:               int async, int timo)
                   1265: {
                   1266:        struct iop_msg *im;
                   1267:        struct i2o_msg mf;
                   1268:        int rv, fl;
                   1269:
                   1270:        fl = (async != 0 ? IM_WAIT : IM_POLL);
                   1271:        im = iop_msg_alloc(sc, NULL, fl);
                   1272:
                   1273:        mf.msgflags = I2O_MSGFLAGS(i2o_msg);
                   1274:        mf.msgfunc = I2O_MSGFUNC(tid, function);
                   1275:        mf.msgictx = ictx;
                   1276:        mf.msgtctx = im->im_tctx;
                   1277:
                   1278:        rv = iop_msg_post(sc, im, &mf, timo);
                   1279:        iop_msg_free(sc, im);
                   1280:        return (rv);
                   1281: }
                   1282:
                   1283: /*
                   1284:  * Post the system table to the IOP.
                   1285:  */
                   1286: int
                   1287: iop_systab_set(struct iop_softc *sc)
                   1288: {
                   1289:        struct i2o_exec_sys_tab_set *mf;
                   1290:        struct iop_msg *im;
                   1291:        bus_space_handle_t bsh;
                   1292:        bus_addr_t boo;
                   1293:        u_int32_t mema[2], ioa[2];
                   1294:        int rv;
                   1295:        u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
                   1296:
                   1297:        im = iop_msg_alloc(sc, NULL, IM_WAIT);
                   1298:
                   1299:        mf = (struct i2o_exec_sys_tab_set *)mb;
                   1300:        mf->msgflags = I2O_MSGFLAGS(i2o_exec_sys_tab_set);
                   1301:        mf->msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_SYS_TAB_SET);
                   1302:        mf->msgictx = IOP_ICTX;
                   1303:        mf->msgtctx = im->im_tctx;
                   1304:        mf->iopid = (sc->sc_dv.dv_unit + 2) << 12;
                   1305:        mf->segnumber = 0;
                   1306:
                   1307:        mema[1] = sc->sc_status.desiredprivmemsize;
                   1308:        ioa[1] = sc->sc_status.desiredpriviosize;
                   1309:
                   1310:        if (mema[1] != 0) {
                   1311:                /*
                   1312:                 * XXX This will waste virtual memory.  We need a flag to tell
                   1313:                 * bus_space_alloc to just reserve, not actually map the area.
                   1314:                 */
                   1315:                rv = bus_space_alloc(sc->sc_bus_memt, 0, 0xffffffff,
                   1316:                    letoh32(mema[1]), PAGE_SIZE, 0, 0, &boo, &bsh);
                   1317:                mema[0] = htole32(boo);
                   1318:                if (rv != 0) {
                   1319:                        printf("%s: can't alloc priv mem space, err = %d\n",
                   1320:                            sc->sc_dv.dv_xname, rv);
                   1321:                        mema[0] = 0;
                   1322:                        mema[1] = 0;
                   1323:                }
                   1324:        }
                   1325:
                   1326:        if (ioa[1] != 0) {
                   1327:                /*
                   1328:                 * XXX This will potentially waste virtual memory.  We
                   1329:                 * need a flag to tell bus_space_alloc to just
                   1330:                 * reserve, not actually map the area.
                   1331:                 */
                   1332:                rv = bus_space_alloc(sc->sc_bus_iot, 0, 0xffff,
                   1333:                    letoh32(ioa[1]), 0, 0, 0, &boo, &bsh);
                   1334:                ioa[0] = htole32(boo);
                   1335:                if (rv != 0) {
                   1336:                        printf("%s: can't alloc priv i/o space, err = %d\n",
                   1337:                            sc->sc_dv.dv_xname, rv);
                   1338:                        ioa[0] = 0;
                   1339:                        ioa[1] = 0;
                   1340:                }
                   1341:        }
                   1342:
                   1343:        iop_msg_map(sc, im, mb, iop_systab, iop_systab_size, 1);
                   1344:        iop_msg_map(sc, im, mb, mema, sizeof(mema), 1);
                   1345:        iop_msg_map(sc, im, mb, ioa, sizeof(ioa), 1);
                   1346:        rv = iop_msg_post(sc, im, mb, 5000);
                   1347:        iop_msg_unmap(sc, im);
                   1348:        iop_msg_free(sc, im);
                   1349:        return (rv);
                   1350: }
                   1351:
                   1352: /*
                   1353:  * Reset the IOP.  Must be called with interrupts disabled.
                   1354:  */
                   1355: int
                   1356: iop_reset(struct iop_softc *sc)
                   1357: {
                   1358:        struct i2o_exec_iop_reset mf;
                   1359:        paddr_t pa = sc->sc_scr_seg->ds_addr;
                   1360:        u_int32_t *sw = (u_int32_t *)sc->sc_scr;
                   1361:        u_int32_t mfa;
                   1362:        int rv = 0;
                   1363:
                   1364:        mf.msgflags = I2O_MSGFLAGS(i2o_exec_iop_reset);
                   1365:        mf.msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_IOP_RESET);
                   1366:        mf.reserved[0] = 0;
                   1367:        mf.reserved[1] = 0;
                   1368:        mf.reserved[2] = 0;
                   1369:        mf.reserved[3] = 0;
                   1370:        mf.statuslow = pa & ~(u_int32_t)0;
                   1371:        mf.statushigh = sizeof pa > sizeof mf.statuslow ? pa >> 32 : 0;
                   1372:
                   1373:        *sw = htole32(0);
                   1374:        bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0, sizeof(*sw),
                   1375:            BUS_DMASYNC_PREREAD);
                   1376:
                   1377:        if ((rv = iop_post(sc, (u_int32_t *)&mf)))
                   1378:                return (rv);
                   1379:
                   1380:        /* XXX */
                   1381:        POLL(2500,
                   1382:            (bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0, sizeof(*sw),
                   1383:            BUS_DMASYNC_POSTREAD), *sw != htole32(0)));
                   1384:        if (*sw != htole32(I2O_RESET_IN_PROGRESS)) {
                   1385:                printf("%s: reset rejected, status 0x%x\n",
                   1386:                    sc->sc_dv.dv_xname, letoh32(*sw));
                   1387:                return (EIO);
                   1388:        }
                   1389:
                   1390:        /*
                   1391:         * IOP is now in the INIT state.  Wait no more than 10 seconds for
                   1392:         * the inbound queue to become responsive.
                   1393:         */
                   1394:        POLL(10000, (mfa = iop_inl(sc, IOP_REG_IFIFO)) != IOP_MFA_EMPTY);
                   1395:        if (mfa == IOP_MFA_EMPTY) {
                   1396:                printf("%s: reset failed\n", sc->sc_dv.dv_xname);
                   1397:                return (EIO);
                   1398:        }
                   1399:
                   1400:        iop_release_mfa(sc, mfa);
                   1401:
                   1402:        return (0);
                   1403: }
                   1404:
                   1405: /*
                   1406:  * Register a new initiator.  Must be called with the configuration lock
                   1407:  * held.
                   1408:  */
                   1409: void
                   1410: iop_initiator_register(struct iop_softc *sc, struct iop_initiator *ii)
                   1411: {
                   1412:        static int ictxgen;
                   1413:        int s;
                   1414:
                   1415:        /* 0 is reserved (by us) for system messages. */
                   1416:        ii->ii_ictx = ++ictxgen;
                   1417:
                   1418:        /*
                   1419:         * `Utility initiators' don't make it onto the per-IOP initiator list
                   1420:         * (which is used only for configuration), but do get one slot on
                   1421:         * the inbound queue.
                   1422:         */
                   1423:        if ((ii->ii_flags & II_UTILITY) == 0) {
                   1424:                LIST_INSERT_HEAD(&sc->sc_iilist, ii, ii_list);
                   1425:                sc->sc_nii++;
                   1426:        } else
                   1427:                sc->sc_nuii++;
                   1428:
                   1429:        s = splbio();
                   1430:        LIST_INSERT_HEAD(IOP_ICTXHASH(ii->ii_ictx), ii, ii_hash);
                   1431:        splx(s);
                   1432: }
                   1433:
                   1434: /*
                   1435:  * Unregister an initiator.  Must be called with the configuration lock
                   1436:  * held.
                   1437:  */
                   1438: void
                   1439: iop_initiator_unregister(struct iop_softc *sc, struct iop_initiator *ii)
                   1440: {
                   1441:        int s;
                   1442:
                   1443:        if ((ii->ii_flags & II_UTILITY) == 0) {
                   1444:                LIST_REMOVE(ii, ii_list);
                   1445:                sc->sc_nii--;
                   1446:        } else
                   1447:                sc->sc_nuii--;
                   1448:
                   1449:        s = splbio();
                   1450:        LIST_REMOVE(ii, ii_hash);
                   1451:        splx(s);
                   1452: }
                   1453:
                   1454: /*
                   1455:  * Handle a reply frame from the IOP.
                   1456:  */
                   1457: int
                   1458: iop_handle_reply(struct iop_softc *sc, u_int32_t rmfa)
                   1459: {
                   1460:        struct iop_msg *im;
                   1461:        struct i2o_reply *rb;
                   1462:        struct i2o_fault_notify *fn;
                   1463:        struct iop_initiator *ii;
                   1464:        u_int off, ictx, tctx, status, size;
                   1465:
                   1466:        off = (int)(rmfa - sc->sc_rep_phys);
                   1467:        rb = (struct i2o_reply *)(sc->sc_rep + off);
                   1468:
                   1469:        /* Perform reply queue DMA synchronisation.  XXX This is rubbish. */
                   1470:        bus_dmamap_sync(sc->sc_dmat, sc->sc_rep_dmamap, off,
                   1471:            sc->sc_rep_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   1472:        if (--sc->sc_curib != 0)
                   1473:                bus_dmamap_sync(sc->sc_dmat, sc->sc_rep_dmamap, 0,
                   1474:                    sc->sc_rep_size, BUS_DMASYNC_PREREAD);
                   1475:
                   1476: #ifdef I2ODEBUG
                   1477:        if ((letoh32(rb->msgflags) & I2O_MSGFLAGS_64BIT) != 0)
                   1478:                panic("iop_handle_reply: 64-bit reply");
                   1479: #endif
                   1480:        /*
                   1481:         * Find the initiator.
                   1482:         */
                   1483:        ictx = letoh32(rb->msgictx);
                   1484:        if (ictx == IOP_ICTX)
                   1485:                ii = NULL;
                   1486:        else {
                   1487:                ii = LIST_FIRST(IOP_ICTXHASH(ictx));
                   1488:                for (; ii != NULL; ii = LIST_NEXT(ii, ii_hash))
                   1489:                        if (ii->ii_ictx == ictx)
                   1490:                                break;
                   1491:                if (ii == NULL) {
                   1492: #ifdef I2ODEBUG
                   1493:                        iop_reply_print(sc, rb);
                   1494: #endif
                   1495:                        printf("%s: WARNING: bad ictx returned (%x)\n",
                   1496:                            sc->sc_dv.dv_xname, ictx);
                   1497:                        return (-1);
                   1498:                }
                   1499:        }
                   1500:
                   1501:        /*
                   1502:         * If we received a transport failure notice, we've got to dig the
                   1503:         * transaction context (if any) out of the original message frame,
                   1504:         * and then release the original MFA back to the inbound FIFO.
                   1505:         */
                   1506:        if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0) {
                   1507:                status = I2O_STATUS_SUCCESS;
                   1508:
                   1509:                fn = (struct i2o_fault_notify *)rb;
                   1510:                tctx = iop_inl(sc, fn->lowmfa + 12);    /* XXX */
                   1511:                iop_release_mfa(sc, fn->lowmfa);
                   1512:                iop_tfn_print(sc, fn);
                   1513:        } else {
                   1514:                status = rb->reqstatus;
                   1515:                tctx = letoh32(rb->msgtctx);
                   1516:        }
                   1517:
                   1518:        if (ii == NULL || (ii->ii_flags & II_DISCARD) == 0) {
                   1519:                /*
                   1520:                 * This initiator tracks state using message wrappers.
                   1521:                 *
                   1522:                 * Find the originating message wrapper, and if requested
                   1523:                 * notify the initiator.
                   1524:                 */
                   1525:                im = sc->sc_ims + (tctx & IOP_TCTX_MASK);
                   1526:                if ((tctx & IOP_TCTX_MASK) > sc->sc_maxib ||
                   1527:                    (im->im_flags & IM_ALLOCED) == 0 ||
                   1528:                    tctx != im->im_tctx) {
                   1529:                        printf("%s: WARNING: bad tctx returned (0x%08x, %p)\n",
                   1530:                            sc->sc_dv.dv_xname, tctx, im);
                   1531:                        if (im != NULL)
                   1532:                                printf("%s: flags=0x%08x tctx=0x%08x\n",
                   1533:                                    sc->sc_dv.dv_xname, im->im_flags,
                   1534:                                    im->im_tctx);
                   1535: #ifdef I2ODEBUG
                   1536:                        if ((rb->msgflags & I2O_MSGFLAGS_FAIL) == 0)
                   1537:                                iop_reply_print(sc, rb);
                   1538: #endif
                   1539:                        return (-1);
                   1540:                }
                   1541:
                   1542:                if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0)
                   1543:                        im->im_flags |= IM_FAIL;
                   1544:
                   1545: #ifdef I2ODEBUG
                   1546:                if ((im->im_flags & IM_REPLIED) != 0)
                   1547:                        panic("%s: dup reply", sc->sc_dv.dv_xname);
                   1548: #endif
                   1549:                im->im_flags |= IM_REPLIED;
                   1550:
                   1551: #ifdef I2ODEBUG
                   1552:                if (status != I2O_STATUS_SUCCESS)
                   1553:                        iop_reply_print(sc, rb);
                   1554: #endif
                   1555:                im->im_reqstatus = status;
                   1556:
                   1557:                /* Copy the reply frame, if requested. */
                   1558:                if (im->im_rb != NULL) {
                   1559:                        size = (letoh32(rb->msgflags) >> 14) & ~3;
                   1560: #ifdef I2ODEBUG
                   1561:                        if (size > IOP_MAX_MSG_SIZE)
                   1562:                                panic("iop_handle_reply: reply too large");
                   1563: #endif
                   1564:                        memcpy(im->im_rb, rb, size);
                   1565:                }
                   1566:
                   1567:                /* Notify the initiator. */
                   1568:                if ((im->im_flags & IM_WAIT) != 0)
                   1569:                        wakeup(im);
                   1570:                else if ((im->im_flags & (IM_POLL | IM_POLL_INTR)) != IM_POLL)
                   1571:                        (*ii->ii_intr)(ii->ii_dv, im, rb);
                   1572:        } else {
                   1573:                /*
                   1574:                 * This initiator discards message wrappers.
                   1575:                 *
                   1576:                 * Simply pass the reply frame to the initiator.
                   1577:                 */
                   1578:                (*ii->ii_intr)(ii->ii_dv, NULL, rb);
                   1579:        }
                   1580:
                   1581:        return (status);
                   1582: }
                   1583:
                   1584: /*
                   1585:  * Handle an interrupt from the IOP.
                   1586:  */
                   1587: int
                   1588: iop_intr(void *arg)
                   1589: {
                   1590:        struct iop_softc *sc;
                   1591:        u_int32_t rmfa;
                   1592:
                   1593:        sc = arg;
                   1594:
                   1595:        if ((iop_inl(sc, IOP_REG_INTR_STATUS) & IOP_INTR_OFIFO) == 0)
                   1596:                return (0);
                   1597:
                   1598:        for (;;) {
                   1599:                /* Double read to account for IOP bug. */
                   1600:                if ((rmfa = iop_inl(sc, IOP_REG_OFIFO)) == IOP_MFA_EMPTY) {
                   1601:                        rmfa = iop_inl(sc, IOP_REG_OFIFO);
                   1602:                        if (rmfa == IOP_MFA_EMPTY)
                   1603:                                break;
                   1604:                }
                   1605:                iop_handle_reply(sc, rmfa);
                   1606:                iop_outl(sc, IOP_REG_OFIFO, rmfa);
                   1607:        }
                   1608:
                   1609:        return (1);
                   1610: }
                   1611:
                   1612: /*
                   1613:  * Handle an event signalled by the executive.
                   1614:  */
                   1615: void
                   1616: iop_intr_event(struct device *dv, struct iop_msg *im, void *reply)
                   1617: {
                   1618:        struct i2o_util_event_register_reply *rb;
                   1619:        struct iop_softc *sc;
                   1620:        u_int event;
                   1621:
                   1622:        sc = (struct iop_softc *)dv;
                   1623:        rb = reply;
                   1624:
                   1625:        if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0)
                   1626:                return;
                   1627:
                   1628:        event = letoh32(rb->event);
                   1629:        printf("%s: event 0x%08x received\n", dv->dv_xname, event);
                   1630: }
                   1631:
                   1632: /*
                   1633:  * Allocate a message wrapper.
                   1634:  */
                   1635: struct iop_msg *
                   1636: iop_msg_alloc(struct iop_softc *sc, struct iop_initiator *ii, int flags)
                   1637: {
                   1638:        struct iop_msg *im;
                   1639:        static u_int tctxgen;
                   1640:        int s, i;
                   1641:
                   1642: #ifdef I2ODEBUG
                   1643:        if ((flags & IM_SYSMASK) != 0)
                   1644:                panic("iop_msg_alloc: system flags specified");
                   1645: #endif
                   1646:
                   1647:        s = splbio();   /* XXX */
                   1648:        im = SLIST_FIRST(&sc->sc_im_freelist);
                   1649: #if defined(DIAGNOSTIC) || defined(I2ODEBUG)
                   1650:        if (im == NULL)
                   1651:                panic("iop_msg_alloc: no free wrappers");
                   1652: #endif
                   1653:        SLIST_REMOVE_HEAD(&sc->sc_im_freelist, im_chain);
                   1654:        splx(s);
                   1655:
                   1656:        if (ii != NULL && (ii->ii_flags & II_DISCARD) != 0)
                   1657:                flags |= IM_DISCARD;
                   1658:
                   1659:        im->im_tctx = (im->im_tctx & IOP_TCTX_MASK) | tctxgen;
                   1660:        tctxgen += (1 << IOP_TCTX_SHIFT);
                   1661:        im->im_flags = flags | IM_ALLOCED;
                   1662:        im->im_rb = NULL;
                   1663:        i = 0;
                   1664:        do {
                   1665:                im->im_xfer[i++].ix_size = 0;
                   1666:        } while (i < IOP_MAX_MSG_XFERS);
                   1667:
                   1668:        return (im);
                   1669: }
                   1670:
                   1671: /*
                   1672:  * Free a message wrapper.
                   1673:  */
                   1674: void
                   1675: iop_msg_free(struct iop_softc *sc, struct iop_msg *im)
                   1676: {
                   1677:        int s;
                   1678:
                   1679: #ifdef I2ODEBUG
                   1680:        if ((im->im_flags & IM_ALLOCED) == 0)
                   1681:                panic("iop_msg_free: wrapper not allocated");
                   1682: #endif
                   1683:
                   1684:        im->im_flags = 0;
                   1685:        s = splbio();
                   1686:        SLIST_INSERT_HEAD(&sc->sc_im_freelist, im, im_chain);
                   1687:        splx(s);
                   1688: }
                   1689:
                   1690: /*
                   1691:  * Map a data transfer.  Write a scatter-gather list into the message frame.
                   1692:  */
                   1693: int
                   1694: iop_msg_map(struct iop_softc *sc, struct iop_msg *im, u_int32_t *mb,
                   1695:     void *xferaddr, size_t xfersize, int out)
                   1696: {
                   1697:        bus_dmamap_t dm;
                   1698:        bus_dma_segment_t *ds;
                   1699:        struct iop_xfer *ix;
                   1700:        u_int rv, i, nsegs, flg, off, xn;
                   1701:        u_int32_t *p;
                   1702:
                   1703:        for (xn = 0, ix = im->im_xfer; xn < IOP_MAX_MSG_XFERS; xn++, ix++)
                   1704:                if (ix->ix_size == 0)
                   1705:                        break;
                   1706:
                   1707: #ifdef I2ODEBUG
                   1708:        if (xfersize == 0)
                   1709:                panic("iop_msg_map: null transfer");
                   1710:        if (xfersize > IOP_MAX_XFER)
                   1711:                panic("iop_msg_map: transfer too large");
                   1712:        if (xn == IOP_MAX_MSG_XFERS)
                   1713:                panic("iop_msg_map: too many xfers");
                   1714: #endif
                   1715:
                   1716:        /*
                   1717:         * Only the first DMA map is static.
                   1718:         */
                   1719:        if (xn != 0) {
                   1720:                rv = bus_dmamap_create(sc->sc_dmat, IOP_MAX_XFER,
                   1721:                    IOP_MAX_SEGS, IOP_MAX_XFER, 0,
                   1722:                    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ix->ix_map);
                   1723:                if (rv != 0)
                   1724:                        return (rv);
                   1725:        }
                   1726:
                   1727:        dm = ix->ix_map;
                   1728:        rv = bus_dmamap_load(sc->sc_dmat, dm, xferaddr, xfersize, NULL, 0);
                   1729:        if (rv != 0)
                   1730:                goto bad;
                   1731:
                   1732:        /*
                   1733:         * How many SIMPLE SG elements can we fit in this message?
                   1734:         */
                   1735:        off = mb[0] >> 16;
                   1736:        p = mb + off;
                   1737:        nsegs = ((IOP_MAX_MSG_SIZE / sizeof *mb) - off) >> 1;
                   1738:
                   1739:        if (dm->dm_nsegs > nsegs) {
                   1740:                bus_dmamap_unload(sc->sc_dmat, ix->ix_map);
                   1741:                rv = EFBIG;
                   1742:                DPRINTF(("iop_msg_map: too many segs\n"));
                   1743:                goto bad;
                   1744:        }
                   1745:
                   1746:        nsegs = dm->dm_nsegs;
                   1747:        xfersize = 0;
                   1748:
                   1749:        /*
                   1750:         * Write out the SG list.
                   1751:         */
                   1752:        if (out)
                   1753:                flg = I2O_SGL_SIMPLE | I2O_SGL_DATA_OUT;
                   1754:        else
                   1755:                flg = I2O_SGL_SIMPLE;
                   1756:
                   1757:        for (i = nsegs, ds = dm->dm_segs; i > 1; i--, p += 2, ds++) {
                   1758:                p[0] = (u_int32_t)ds->ds_len | flg;
                   1759:                p[1] = (u_int32_t)ds->ds_addr;
                   1760:                xfersize += ds->ds_len;
                   1761:        }
                   1762:
                   1763:        p[0] = (u_int32_t)ds->ds_len | flg | I2O_SGL_END_BUFFER;
                   1764:        p[1] = (u_int32_t)ds->ds_addr;
                   1765:        xfersize += ds->ds_len;
                   1766:
                   1767:        /* Fix up the transfer record, and sync the map. */
                   1768:        ix->ix_flags = (out ? IX_OUT : IX_IN);
                   1769:        ix->ix_size = xfersize;
                   1770:        bus_dmamap_sync(sc->sc_dmat, ix->ix_map, 0, xfersize,
                   1771:            out ? BUS_DMASYNC_POSTWRITE : BUS_DMASYNC_POSTREAD);
                   1772:
                   1773:        /*
                   1774:         * If this is the first xfer we've mapped for this message, adjust
                   1775:         * the SGL offset field in the message header.
                   1776:         */
                   1777:        if ((im->im_flags & IM_SGLOFFADJ) == 0) {
                   1778:                mb[0] += (mb[0] >> 12) & 0xf0;
                   1779:                im->im_flags |= IM_SGLOFFADJ;
                   1780:        }
                   1781:        mb[0] += (nsegs << 17);
                   1782:        return (0);
                   1783:
                   1784:  bad:
                   1785:        if (xn != 0)
                   1786:                bus_dmamap_destroy(sc->sc_dmat, ix->ix_map);
                   1787:        return (rv);
                   1788: }
                   1789:
                   1790: /*
                   1791:  * Map a block I/O data transfer (different in that there's only one per
                   1792:  * message maximum, and PAGE addressing may be used).  Write a scatter
                   1793:  * gather list into the message frame.
                   1794:  */
                   1795: int
                   1796: iop_msg_map_bio(struct iop_softc *sc, struct iop_msg *im, u_int32_t *mb,
                   1797:                void *xferaddr, int xfersize, int out)
                   1798: {
                   1799:        bus_dma_segment_t *ds;
                   1800:        bus_dmamap_t dm;
                   1801:        struct iop_xfer *ix;
                   1802:        u_int rv, i, nsegs, off, slen, tlen, flg;
                   1803:        paddr_t saddr, eaddr;
                   1804:        u_int32_t *p;
                   1805:
                   1806: #ifdef I2ODEBUG
                   1807:        if (xfersize == 0)
                   1808:                panic("iop_msg_map_bio: null transfer");
                   1809:        if (xfersize > IOP_MAX_XFER)
                   1810:                panic("iop_msg_map_bio: transfer too large");
                   1811:        if ((im->im_flags & IM_SGLOFFADJ) != 0)
                   1812:                panic("iop_msg_map_bio: SGLOFFADJ");
                   1813: #endif
                   1814:
                   1815:        ix = im->im_xfer;
                   1816:        dm = ix->ix_map;
                   1817:        rv = bus_dmamap_load(sc->sc_dmat, dm, xferaddr, xfersize, NULL, 0);
                   1818:        if (rv != 0)
                   1819:                return (rv);
                   1820:
                   1821:        off = mb[0] >> 16;
                   1822:        nsegs = ((IOP_MAX_MSG_SIZE / 4) - off) >> 1;
                   1823:
                   1824:        /*
                   1825:         * If the transfer is highly fragmented and won't fit using SIMPLE
                   1826:         * elements, use PAGE_LIST elements instead.  SIMPLE elements are
                   1827:         * potentially more efficient, both for us and the IOP.
                   1828:         */
                   1829:        if (dm->dm_nsegs > nsegs) {
                   1830:                nsegs = 1;
                   1831:                p = mb + off + 1;
                   1832:
                   1833:                /* XXX This should be done with a bus_space flag. */
                   1834:                for (i = dm->dm_nsegs, ds = dm->dm_segs; i > 0; i--, ds++) {
                   1835:                        slen = ds->ds_len;
                   1836:                        saddr = ds->ds_addr;
                   1837:
                   1838:                        while (slen > 0) {
                   1839:                                eaddr = (saddr + PAGE_SIZE) & ~(PAGE_SIZE - 1);
                   1840:                                tlen = min(eaddr - saddr, slen);
                   1841:                                slen -= tlen;
                   1842:                                *p++ = letoh32(saddr);
                   1843:                                saddr = eaddr;
                   1844:                                nsegs++;
                   1845:                        }
                   1846:                }
                   1847:
                   1848:                mb[off] = xfersize | I2O_SGL_PAGE_LIST | I2O_SGL_END_BUFFER |
                   1849:                    I2O_SGL_END;
                   1850:                if (out)
                   1851:                        mb[off] |= I2O_SGL_DATA_OUT;
                   1852:        } else {
                   1853:                p = mb + off;
                   1854:                nsegs = dm->dm_nsegs;
                   1855:
                   1856:                if (out)
                   1857:                        flg = I2O_SGL_SIMPLE | I2O_SGL_DATA_OUT;
                   1858:                else
                   1859:                        flg = I2O_SGL_SIMPLE;
                   1860:
                   1861:                for (i = nsegs, ds = dm->dm_segs; i > 1; i--, p += 2, ds++) {
                   1862:                        p[0] = (u_int32_t)ds->ds_len | flg;
                   1863:                        p[1] = (u_int32_t)ds->ds_addr;
                   1864:                }
                   1865:
                   1866:                p[0] = (u_int32_t)ds->ds_len | flg | I2O_SGL_END_BUFFER |
                   1867:                    I2O_SGL_END;
                   1868:                p[1] = (u_int32_t)ds->ds_addr;
                   1869:                nsegs <<= 1;
                   1870:        }
                   1871:
                   1872:        /* Fix up the transfer record, and sync the map. */
                   1873:        ix->ix_flags = (out ? IX_OUT : IX_IN);
                   1874:        ix->ix_size = xfersize;
                   1875:        bus_dmamap_sync(sc->sc_dmat, ix->ix_map, 0,
                   1876:            ix->ix_map->dm_mapsize,
                   1877:            out ? BUS_DMASYNC_POSTWRITE : BUS_DMASYNC_POSTREAD);
                   1878:
                   1879:        /*
                   1880:         * Adjust the SGL offset and total message size fields.  We don't
                   1881:         * set IM_SGLOFFADJ, since it's used only for SIMPLE elements.
                   1882:         */
                   1883:        mb[0] += ((off << 4) + (nsegs << 16));
                   1884:        return (0);
                   1885: }
                   1886:
                   1887: /*
                   1888:  * Unmap all data transfers associated with a message wrapper.
                   1889:  */
                   1890: void
                   1891: iop_msg_unmap(struct iop_softc *sc, struct iop_msg *im)
                   1892: {
                   1893:        struct iop_xfer *ix;
                   1894:        int i;
                   1895:
                   1896: #ifdef I2ODEBUG
                   1897:        if (im->im_xfer[0].ix_size == 0)
                   1898:                panic("iop_msg_unmap: no transfers mapped");
                   1899: #endif
                   1900:
                   1901:        for (ix = im->im_xfer, i = 0;;) {
                   1902:                bus_dmamap_sync(sc->sc_dmat, ix->ix_map, 0, ix->ix_size,
                   1903:                    ix->ix_flags & IX_OUT ? BUS_DMASYNC_POSTWRITE :
                   1904:                    BUS_DMASYNC_POSTREAD);
                   1905:                bus_dmamap_unload(sc->sc_dmat, ix->ix_map);
                   1906:
                   1907:                /* Only the first DMA map is static. */
                   1908:                if (i != 0)
                   1909:                        bus_dmamap_destroy(sc->sc_dmat, ix->ix_map);
                   1910:                if ((++ix)->ix_size == 0)
                   1911:                        break;
                   1912:                if (++i >= IOP_MAX_MSG_XFERS)
                   1913:                        break;
                   1914:        }
                   1915: }
                   1916:
                   1917: /*
                   1918:  * Post a message frame to the IOP's inbound queue.
                   1919:  */
                   1920: int
                   1921: iop_post(struct iop_softc *sc, u_int32_t *mb)
                   1922: {
                   1923:        u_int32_t mfa;
                   1924:        int s;
                   1925:        size_t size = mb[0] >> 14 & ~3;
                   1926:
                   1927:        /* ZZZ */
                   1928:        if (size > IOP_MAX_MSG_SIZE)
                   1929:                panic("iop_post: frame too large");
                   1930:
                   1931: #ifdef I2ODEBUG
                   1932:        {
                   1933:                int i;
                   1934:
                   1935:                printf("\niop_post\n");
                   1936:                for (i = 0; i < size / sizeof *mb; i++)
                   1937:                        printf("%4d %08x\n", i, mb[i]);
                   1938:        }
                   1939: #endif
                   1940:
                   1941:        s = splbio();   /* XXX */
                   1942:
                   1943:        /* Allocate a slot with the IOP. */
                   1944:        if ((mfa = iop_inl(sc, IOP_REG_IFIFO)) == IOP_MFA_EMPTY)
                   1945:                if ((mfa = iop_inl(sc, IOP_REG_IFIFO)) == IOP_MFA_EMPTY) {
                   1946:                        splx(s);
                   1947:                        printf("%s: mfa not forthcoming\n",
                   1948:                            sc->sc_dv.dv_xname);
                   1949:                        return (EAGAIN);
                   1950:                }
                   1951:
                   1952: #ifdef I2ODEBUG
                   1953:        printf("mfa = %u\n", mfa);
                   1954: #endif
                   1955:
                   1956:        /* Copy out the message frame. */
                   1957:        bus_space_write_region_4(sc->sc_iot, sc->sc_ioh, mfa, mb,
                   1958:            size / sizeof *mb);
                   1959:        bus_space_barrier(sc->sc_iot, sc->sc_ioh, mfa, size,
                   1960:            BUS_SPACE_BARRIER_WRITE);
                   1961:
                   1962:        /* Post the MFA back to the IOP. */
                   1963:        iop_outl(sc, IOP_REG_IFIFO, mfa);
                   1964:
                   1965:        splx(s);
                   1966:        return (0);
                   1967: }
                   1968:
                   1969: /*
                   1970:  * Post a message to the IOP and deal with completion.
                   1971:  */
                   1972: int
                   1973: iop_msg_post(struct iop_softc *sc, struct iop_msg *im, void *xmb, int timo)
                   1974: {
                   1975:        u_int32_t *mb = xmb;
                   1976:        int rv, s;
                   1977:        size_t size = mb[0] >> 14 & 3;
                   1978:
                   1979:        /* Terminate the scatter/gather list chain. */
                   1980:        if ((im->im_flags & IM_SGLOFFADJ) != 0)
                   1981:                mb[size - 2] |= I2O_SGL_END;
                   1982:
                   1983:        /* Perform reply buffer DMA synchronisation. */
                   1984:        if (sc->sc_curib++ == 0)
                   1985:                bus_dmamap_sync(sc->sc_dmat, sc->sc_rep_dmamap, 0,
                   1986:                    sc->sc_rep_size, BUS_DMASYNC_PREREAD);
                   1987:
                   1988:        if ((rv = iop_post(sc, mb)) != 0)
                   1989:                return (rv);
                   1990:
                   1991:        if ((im->im_flags & IM_DISCARD) != 0)
                   1992:                iop_msg_free(sc, im);
                   1993:        else if ((im->im_flags & IM_POLL) != 0 && timo == 0) {
                   1994:                /* XXX For ofifo_init(). */
                   1995:                rv = 0;
                   1996:        } else if ((im->im_flags & (IM_POLL | IM_WAIT)) != 0) {
                   1997:                if ((im->im_flags & IM_POLL) != 0)
                   1998:                        iop_msg_poll(sc, im, timo);
                   1999:                else
                   2000:                        iop_msg_wait(sc, im, timo);
                   2001:
                   2002:                s = splbio();
                   2003:                if ((im->im_flags & IM_REPLIED) != 0) {
                   2004:                        if ((im->im_flags & IM_NOSTATUS) != 0)
                   2005:                                rv = 0;
                   2006:                        else if ((im->im_flags & IM_FAIL) != 0)
                   2007:                                rv = ENXIO;
                   2008:                        else if (im->im_reqstatus != I2O_STATUS_SUCCESS)
                   2009:                                rv = EIO;
                   2010:                        else
                   2011:                                rv = 0;
                   2012:                } else
                   2013:                        rv = EBUSY;
                   2014:                splx(s);
                   2015:        } else
                   2016:                rv = 0;
                   2017:
                   2018:        return (rv);
                   2019: }
                   2020:
                   2021: /*
                   2022:  * Spin until the specified message is replied to.
                   2023:  */
                   2024: void
                   2025: iop_msg_poll(struct iop_softc *sc, struct iop_msg *im, int timo)
                   2026: {
                   2027:        u_int32_t rmfa;
                   2028:        int s, status;
                   2029:
                   2030:        s = splbio();   /* XXX */
                   2031:
                   2032:        /* Wait for completion. */
                   2033:        for (timo *= 10; timo != 0; timo--) {
                   2034:                if ((iop_inl(sc, IOP_REG_INTR_STATUS) & IOP_INTR_OFIFO) != 0) {
                   2035:                        /* Double read to account for IOP bug. */
                   2036:                        rmfa = iop_inl(sc, IOP_REG_OFIFO);
                   2037:                        if (rmfa == IOP_MFA_EMPTY)
                   2038:                                rmfa = iop_inl(sc, IOP_REG_OFIFO);
                   2039:                        if (rmfa != IOP_MFA_EMPTY) {
                   2040:                                status = iop_handle_reply(sc, rmfa);
                   2041:
                   2042:                                /*
                   2043:                                 * Return the reply frame to the IOP's
                   2044:                                 * outbound FIFO.
                   2045:                                 */
                   2046:                                iop_outl(sc, IOP_REG_OFIFO, rmfa);
                   2047:                        }
                   2048:                }
                   2049:                if ((im->im_flags & IM_REPLIED) != 0)
                   2050:                        break;
                   2051:                DELAY(100);
                   2052:        }
                   2053:
                   2054:        if (timo == 0) {
                   2055: #ifdef I2ODEBUG
                   2056:                printf("%s: poll - no reply\n", sc->sc_dv.dv_xname);
                   2057:                if (iop_status_get(sc, 1) != 0)
                   2058:                        printf("iop_msg_poll: unable to retrieve status\n");
                   2059:                else
                   2060:                        printf("iop_msg_poll: IOP state = %d\n",
                   2061:                            (letoh32(sc->sc_status.segnumber) >> 16) & 0xff);
                   2062: #endif
                   2063:        }
                   2064:
                   2065:        splx(s);
                   2066: }
                   2067:
                   2068: /*
                   2069:  * Sleep until the specified message is replied to.
                   2070:  */
                   2071: void
                   2072: iop_msg_wait(struct iop_softc *sc, struct iop_msg *im, int timo)
                   2073: {
                   2074:        int s, rv;
                   2075:
                   2076:        s = splbio();
                   2077:        if ((im->im_flags & IM_REPLIED) != 0) {
                   2078:                splx(s);
                   2079:                return;
                   2080:        }
                   2081:        rv = tsleep(im, PRIBIO, "iopmsg", timo * hz / 1000);
                   2082:        splx(s);
                   2083:
                   2084: #ifdef I2ODEBUG
                   2085:        if (rv != 0) {
                   2086:                printf("iop_msg_wait: tsleep() == %d\n", rv);
                   2087:                if (iop_status_get(sc, 0) != 0)
                   2088:                        printf("iop_msg_wait: unable to retrieve status\n");
                   2089:                else
                   2090:                        printf("iop_msg_wait: IOP state = %d\n",
                   2091:                            (letoh32(sc->sc_status.segnumber) >> 16) & 0xff);
                   2092:        }
                   2093: #endif
                   2094: }
                   2095:
                   2096: /*
                   2097:  * Release an unused message frame back to the IOP's inbound fifo.
                   2098:  */
                   2099: void
                   2100: iop_release_mfa(struct iop_softc *sc, u_int32_t mfa)
                   2101: {
                   2102:
                   2103:        /* Use the frame to issue a no-op. */
                   2104:        iop_outl(sc, mfa, I2O_VERSION_11 | (4 << 16));
                   2105:        iop_outl(sc, mfa + 4, I2O_MSGFUNC(I2O_TID_IOP, I2O_UTIL_NOP));
                   2106:        iop_outl(sc, mfa + 8, 0);
                   2107:        iop_outl(sc, mfa + 12, 0);
                   2108:
                   2109:        iop_outl(sc, IOP_REG_IFIFO, mfa);
                   2110: }
                   2111:
                   2112: #ifdef I2ODEBUG
                   2113: /*
                   2114:  * Dump a reply frame header.
                   2115:  */
                   2116: void
                   2117: iop_reply_print(struct iop_softc *sc, struct i2o_reply *rb)
                   2118: {
                   2119:        u_int function, detail;
                   2120: #ifdef I2OVERBOSE
                   2121:        const char *statusstr;
                   2122: #endif
                   2123:
                   2124:        function = (letoh32(rb->msgfunc) >> 24) & 0xff;
                   2125:        detail = letoh16(rb->detail);
                   2126:
                   2127:        printf("%s: reply:\n", sc->sc_dv.dv_xname);
                   2128:
                   2129: #ifdef I2OVERBOSE
                   2130:        if (rb->reqstatus < sizeof(iop_status) / sizeof(iop_status[0]))
                   2131:                statusstr = iop_status[rb->reqstatus];
                   2132:        else
                   2133:                statusstr = "undefined error code";
                   2134:
                   2135:        printf("%s:   function=0x%02x status=0x%02x (%s)\n",
                   2136:            sc->sc_dv.dv_xname, function, rb->reqstatus, statusstr);
                   2137: #else
                   2138:        printf("%s:   function=0x%02x status=0x%02x\n",
                   2139:            sc->sc_dv.dv_xname, function, rb->reqstatus);
                   2140: #endif
                   2141:        printf("%s:   detail=0x%04x ictx=0x%08x tctx=0x%08x\n",
                   2142:            sc->sc_dv.dv_xname, detail, letoh32(rb->msgictx),
                   2143:            letoh32(rb->msgtctx));
                   2144:        printf("%s:   tidi=%d tidt=%d flags=0x%02x\n", sc->sc_dv.dv_xname,
                   2145:            (letoh32(rb->msgfunc) >> 12) & 4095, letoh32(rb->msgfunc) & 4095,
                   2146:            (letoh32(rb->msgflags) >> 8) & 0xff);
                   2147: }
                   2148: #endif
                   2149:
                   2150: /*
                   2151:  * Dump a transport failure reply.
                   2152:  */
                   2153: void
                   2154: iop_tfn_print(struct iop_softc *sc, struct i2o_fault_notify *fn)
                   2155: {
                   2156:
                   2157:        printf("%s: WARNING: transport failure:\n", sc->sc_dv.dv_xname);
                   2158:
                   2159:        printf("%s:   ictx=0x%08x tctx=0x%08x\n", sc->sc_dv.dv_xname,
                   2160:            letoh32(fn->msgictx), letoh32(fn->msgtctx));
                   2161:        printf("%s:  failurecode=0x%02x severity=0x%02x\n",
                   2162:            sc->sc_dv.dv_xname, fn->failurecode, fn->severity);
                   2163:        printf("%s:  highestver=0x%02x lowestver=0x%02x\n",
                   2164:            sc->sc_dv.dv_xname, fn->highestver, fn->lowestver);
                   2165: }
                   2166:
                   2167: /*
                   2168:  * Translate an I2O ASCII field into a C string.
                   2169:  */
                   2170: void
                   2171: iop_strvis(struct iop_softc *sc, const char *src, int slen, char *dst, int dlen)
                   2172: {
                   2173:        int hc, lc, i, nit;
                   2174:
                   2175:        dlen--;
                   2176:        lc = 0;
                   2177:        hc = 0;
                   2178:        i = 0;
                   2179:
                   2180:        /*
                   2181:         * DPT use NUL as a space, whereas AMI use it as a terminator.  The
                   2182:         * spec has nothing to say about it.  Since AMI fields are usually
                   2183:         * filled with junk after the terminator, ...
                   2184:         */
                   2185:        nit = (letoh16(sc->sc_status.orgid) != I2O_ORG_DPT);
                   2186:
                   2187:        while (slen-- != 0 && dlen-- != 0) {
                   2188:                if (nit && *src == '\0')
                   2189:                        break;
                   2190:                else if (*src <= 0x20 || *src >= 0x7f) {
                   2191:                        if (hc)
                   2192:                                dst[i++] = ' ';
                   2193:                } else {
                   2194:                        hc = 1;
                   2195:                        dst[i++] = *src;
                   2196:                        lc = i;
                   2197:                }
                   2198:                src++;
                   2199:        }
                   2200:
                   2201:        dst[lc] = '\0';
                   2202: }
                   2203:
                   2204: /*
                   2205:  * Retrieve the DEVICE_IDENTITY parameter group from the target and dump it.
                   2206:  */
                   2207: int
                   2208: iop_print_ident(struct iop_softc *sc, int tid)
                   2209: {
                   2210:        struct {
                   2211:                struct  i2o_param_op_results pr;
                   2212:                struct  i2o_param_read_results prr;
                   2213:                struct  i2o_param_device_identity di;
                   2214:        } __attribute__ ((__packed__)) p;
                   2215:        char buf[32];
                   2216:        int rv;
                   2217:
                   2218:        rv = iop_param_op(sc, tid, NULL, 0, I2O_PARAM_DEVICE_IDENTITY, &p,
                   2219:            sizeof(p));
                   2220:        if (rv != 0)
                   2221:                return (rv);
                   2222:
                   2223:        iop_strvis(sc, p.di.vendorinfo, sizeof(p.di.vendorinfo), buf,
                   2224:            sizeof(buf));
                   2225:        printf(" <%s, ", buf);
                   2226:        iop_strvis(sc, p.di.productinfo, sizeof(p.di.productinfo), buf,
                   2227:            sizeof(buf));
                   2228:        printf("%s, ", buf);
                   2229:        iop_strvis(sc, p.di.revlevel, sizeof(p.di.revlevel), buf, sizeof(buf));
                   2230:        printf("%s>", buf);
                   2231:
                   2232:        return (0);
                   2233: }
                   2234:
                   2235: /*
                   2236:  * Claim or unclaim the specified TID.
                   2237:  */
                   2238: int
                   2239: iop_util_claim(struct iop_softc *sc, struct iop_initiator *ii, int release,
                   2240:              int flags)
                   2241: {
                   2242:        struct iop_msg *im;
                   2243:        struct i2o_util_claim mf;
                   2244:        int rv, func;
                   2245:
                   2246:        func = release ? I2O_UTIL_CLAIM_RELEASE : I2O_UTIL_CLAIM;
                   2247:        im = iop_msg_alloc(sc, ii, IM_WAIT);
                   2248:
                   2249:        /* We can use the same structure, as they're identical. */
                   2250:        mf.msgflags = I2O_MSGFLAGS(i2o_util_claim);
                   2251:        mf.msgfunc = I2O_MSGFUNC(ii->ii_tid, func);
                   2252:        mf.msgictx = ii->ii_ictx;
                   2253:        mf.msgtctx = im->im_tctx;
                   2254:        mf.flags = flags;
                   2255:
                   2256:        rv = iop_msg_post(sc, im, &mf, 5000);
                   2257:        iop_msg_free(sc, im);
                   2258:        return (rv);
                   2259: }
                   2260:
                   2261: /*
                   2262:  * Perform an abort.
                   2263:  */
                   2264: int iop_util_abort(struct iop_softc *sc, struct iop_initiator *ii, int func,
                   2265:                  int tctxabort, int flags)
                   2266: {
                   2267:        struct iop_msg *im;
                   2268:        struct i2o_util_abort mf;
                   2269:        int rv;
                   2270:
                   2271:        im = iop_msg_alloc(sc, ii, IM_WAIT);
                   2272:
                   2273:        mf.msgflags = I2O_MSGFLAGS(i2o_util_abort);
                   2274:        mf.msgfunc = I2O_MSGFUNC(ii->ii_tid, I2O_UTIL_ABORT);
                   2275:        mf.msgictx = ii->ii_ictx;
                   2276:        mf.msgtctx = im->im_tctx;
                   2277:        mf.flags = (func << 24) | flags;
                   2278:        mf.tctxabort = tctxabort;
                   2279:
                   2280:        rv = iop_msg_post(sc, im, &mf, 5000);
                   2281:        iop_msg_free(sc, im);
                   2282:        return (rv);
                   2283: }
                   2284:
                   2285: /*
                   2286:  * Enable or disable reception of events for the specified device.
                   2287:  */
                   2288: int iop_util_eventreg(struct iop_softc *sc, struct iop_initiator *ii, int mask)
                   2289: {
                   2290:        struct iop_msg *im;
                   2291:        struct i2o_util_event_register mf;
                   2292:
                   2293:        im = iop_msg_alloc(sc, ii, 0);
                   2294:
                   2295:        mf.msgflags = I2O_MSGFLAGS(i2o_util_event_register);
                   2296:        mf.msgfunc = I2O_MSGFUNC(ii->ii_tid, I2O_UTIL_EVENT_REGISTER);
                   2297:        mf.msgictx = ii->ii_ictx;
                   2298:        mf.msgtctx = im->im_tctx;
                   2299:        mf.eventmask = mask;
                   2300:
                   2301:        /* This message is replied to only when events are signalled. */
                   2302:        return (iop_msg_post(sc, im, &mf, 0));
                   2303: }
                   2304:
                   2305: int
                   2306: iopopen(dev_t dev, int flag, int mode, struct proc *p)
                   2307: {
                   2308:        struct iop_softc *sc;
                   2309:
                   2310:        if (!(sc = (struct iop_softc *)device_lookup(&iop_cd, minor(dev))))
                   2311:                return (ENXIO);
                   2312:        if ((sc->sc_flags & IOP_ONLINE) == 0)
                   2313:                return (ENXIO);
                   2314:        if ((sc->sc_flags & IOP_OPEN) != 0)
                   2315:                return (EBUSY);
                   2316:        sc->sc_flags |= IOP_OPEN;
                   2317:
                   2318:        sc->sc_ptb = malloc(IOP_MAX_XFER * IOP_MAX_MSG_XFERS, M_DEVBUF,
                   2319:            M_WAITOK);
                   2320:        if (sc->sc_ptb == NULL) {
                   2321:                sc->sc_flags ^= IOP_OPEN;
                   2322:                return (ENOMEM);
                   2323:        }
                   2324:
                   2325:        return (0);
                   2326: }
                   2327:
                   2328: int
                   2329: iopclose(dev_t dev, int flag, int mode, struct proc *p)
                   2330: {
                   2331:        struct iop_softc *sc;
                   2332:
                   2333:        sc = (struct iop_softc *)device_lookup(&iop_cd, minor(dev)); /* XXX */
                   2334:        free(sc->sc_ptb, M_DEVBUF);
                   2335:        sc->sc_flags &= ~IOP_OPEN;
                   2336:        return (0);
                   2337: }
                   2338:
                   2339: int
                   2340: iopioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
                   2341: {
                   2342:        struct iop_softc *sc;
                   2343:        struct iovec *iov;
                   2344:        int rv, i;
                   2345:
                   2346:        if (securelevel >= 2)
                   2347:                return (EPERM);
                   2348:
                   2349:        sc = (struct iop_softc *)device_lookup(&iop_cd, minor(dev)); /* XXX */
                   2350:
                   2351:        switch (cmd) {
                   2352:        case IOPIOCPT:
                   2353:                return (iop_passthrough(sc, (struct ioppt *)data));
                   2354:
                   2355:        case IOPIOCGSTATUS:
                   2356:                iov = (struct iovec *)data;
                   2357:                i = sizeof(struct i2o_status);
                   2358:                if (i > iov->iov_len)
                   2359:                        i = iov->iov_len;
                   2360:                else
                   2361:                        iov->iov_len = i;
                   2362:                if ((rv = iop_status_get(sc, 0)) == 0)
                   2363:                        rv = copyout(&sc->sc_status, iov->iov_base, i);
                   2364:                return (rv);
                   2365:
                   2366:        case IOPIOCGLCT:
                   2367:        case IOPIOCGTIDMAP:
                   2368:        case IOPIOCRECONFIG:
                   2369:                break;
                   2370:
                   2371:        default:
                   2372: #if defined(DIAGNOSTIC) || defined(I2ODEBUG)
                   2373:                printf("%s: unknown ioctl %lx\n", sc->sc_dv.dv_xname, cmd);
                   2374: #endif
                   2375:                return (ENOTTY);
                   2376:        }
                   2377:
                   2378:        if ((rv = lockmgr(&sc->sc_conflock, LK_SHARED, NULL)) != 0)
                   2379:                return (rv);
                   2380:
                   2381:        switch (cmd) {
                   2382:        case IOPIOCGLCT:
                   2383:                iov = (struct iovec *)data;
                   2384:                i = letoh16(sc->sc_lct->tablesize) << 2;
                   2385:                if (i > iov->iov_len)
                   2386:                        i = iov->iov_len;
                   2387:                else
                   2388:                        iov->iov_len = i;
                   2389:                rv = copyout(sc->sc_lct, iov->iov_base, i);
                   2390:                break;
                   2391:
                   2392:        case IOPIOCRECONFIG:
                   2393:                rv = iop_reconfigure(sc, 0);
                   2394:                break;
                   2395:
                   2396:        case IOPIOCGTIDMAP:
                   2397:                iov = (struct iovec *)data;
                   2398:                i = sizeof(struct iop_tidmap) * sc->sc_nlctent;
                   2399:                if (i > iov->iov_len)
                   2400:                        i = iov->iov_len;
                   2401:                else
                   2402:                        iov->iov_len = i;
                   2403:                rv = copyout(sc->sc_tidmap, iov->iov_base, i);
                   2404:                break;
                   2405:        }
                   2406:
                   2407:        lockmgr(&sc->sc_conflock, LK_RELEASE, NULL);
                   2408:        return (rv);
                   2409: }
                   2410:
                   2411: int
                   2412: iop_passthrough(struct iop_softc *sc, struct ioppt *pt)
                   2413: {
                   2414:        struct iop_msg *im;
                   2415:        struct i2o_msg *mf;
                   2416:        struct ioppt_buf *ptb;
                   2417:        int rv, i, mapped;
                   2418:        void *buf;
                   2419:
                   2420:        mf = NULL;
                   2421:        im = NULL;
                   2422:        mapped = 1;
                   2423:
                   2424:        if (pt->pt_msglen > IOP_MAX_MSG_SIZE ||
                   2425:            pt->pt_msglen > (letoh16(sc->sc_status.inboundmframesize) << 2) ||
                   2426:            pt->pt_msglen < sizeof(struct i2o_msg) ||
                   2427:            pt->pt_nbufs > IOP_MAX_MSG_XFERS ||
                   2428:            pt->pt_nbufs < 0 || pt->pt_replylen < 0 ||
                   2429:             pt->pt_timo < 1000 || pt->pt_timo > 5*60*1000)
                   2430:                return (EINVAL);
                   2431:
                   2432:        for (i = 0; i < pt->pt_nbufs; i++)
                   2433:                if (pt->pt_bufs[i].ptb_datalen > IOP_MAX_XFER) {
                   2434:                        rv = ENOMEM;
                   2435:                        goto bad;
                   2436:                }
                   2437:
                   2438:        mf = malloc(IOP_MAX_MSG_SIZE, M_DEVBUF, M_WAITOK);
                   2439:        if (mf == NULL)
                   2440:                return (ENOMEM);
                   2441:
                   2442:        if ((rv = copyin(pt->pt_msg, mf, pt->pt_msglen)) != 0)
                   2443:                goto bad;
                   2444:
                   2445:        im = iop_msg_alloc(sc, NULL, IM_WAIT | IM_NOSTATUS);
                   2446:        im->im_rb = (struct i2o_reply *)mf;
                   2447:        mf->msgictx = IOP_ICTX;
                   2448:        mf->msgtctx = im->im_tctx;
                   2449:
                   2450:        for (i = 0; i < pt->pt_nbufs; i++) {
                   2451:                ptb = &pt->pt_bufs[i];
                   2452:                buf = sc->sc_ptb + i * IOP_MAX_XFER;
                   2453:
                   2454:                if ((u_int)ptb->ptb_datalen > IOP_MAX_XFER) {
                   2455:                        rv = EINVAL;
                   2456:                        goto bad;
                   2457:                }
                   2458:
                   2459:                if (ptb->ptb_out != 0) {
                   2460:                        rv = copyin(ptb->ptb_data, buf, ptb->ptb_datalen);
                   2461:                        if (rv != 0)
                   2462:                                goto bad;
                   2463:                }
                   2464:
                   2465:                rv = iop_msg_map(sc, im, (u_int32_t *)mf, buf,
                   2466:                    ptb->ptb_datalen, ptb->ptb_out != 0);
                   2467:                if (rv != 0)
                   2468:                        goto bad;
                   2469:                mapped = 1;
                   2470:        }
                   2471:
                   2472:        if ((rv = iop_msg_post(sc, im, mf, pt->pt_timo)) != 0)
                   2473:                goto bad;
                   2474:
                   2475:        i = (letoh32(im->im_rb->msgflags) >> 14) & ~3;
                   2476:        if (i > IOP_MAX_MSG_SIZE)
                   2477:                i = IOP_MAX_MSG_SIZE;
                   2478:        if (i > pt->pt_replylen)
                   2479:                i = pt->pt_replylen;
                   2480:        if ((rv = copyout(im->im_rb, pt->pt_reply, i)) != 0)
                   2481:                goto bad;
                   2482:
                   2483:        iop_msg_unmap(sc, im);
                   2484:        mapped = 0;
                   2485:
                   2486:        for (i = 0; i < pt->pt_nbufs; i++) {
                   2487:                ptb = &pt->pt_bufs[i];
                   2488:                if (ptb->ptb_out != 0)
                   2489:                        continue;
                   2490:                buf = sc->sc_ptb + i * IOP_MAX_XFER;
                   2491:                rv = copyout(buf, ptb->ptb_data, ptb->ptb_datalen);
                   2492:                if (rv != 0)
                   2493:                        break;
                   2494:        }
                   2495:
                   2496:  bad:
                   2497:        if (mapped != 0)
                   2498:                iop_msg_unmap(sc, im);
                   2499:        if (im != NULL)
                   2500:                iop_msg_free(sc, im);
                   2501:        if (mf != NULL)
                   2502:                free(mf, M_DEVBUF);
                   2503:        return (rv);
                   2504: }

CVSweb