[BACK]Return to mscp_subr.c CVS log [TXT][DIR] Up to [local] / sys / arch / vax / mscp

Annotation of sys/arch/vax/mscp/mscp_subr.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: mscp_subr.c,v 1.9 2005/11/24 04:54:49 brad Exp $      */
                      2: /*     $NetBSD: mscp_subr.c,v 1.18 2001/11/13 07:38:28 lukem Exp $     */
                      3: /*
                      4:  * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
                      5:  * Copyright (c) 1988 Regents of the University of California.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to Berkeley by
                      9:  * Chris Torek.
                     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. Neither the name of the University nor the names of its contributors
                     20:  *    may be used to endorse or promote products derived from this software
                     21:  *    without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  *
                     35:  *     @(#)mscp.c      7.5 (Berkeley) 12/16/90
                     36:  */
                     37:
                     38: /*
                     39:  * MSCP generic driver routines
                     40:  */
                     41:
                     42: #include <sys/cdefs.h>
                     43:
                     44: #include <sys/param.h>
                     45: #include <sys/device.h>
                     46: #include <sys/buf.h>
                     47: #include <sys/systm.h>
                     48: #include <sys/proc.h>
                     49:
                     50: #include <machine/bus.h>
                     51: #include <machine/sid.h>
                     52:
                     53: #include <arch/vax/mscp/mscp.h>
                     54: #include <arch/vax/mscp/mscpreg.h>
                     55: #include <arch/vax/mscp/mscpvar.h>
                     56:
                     57: #include "ra.h"
                     58: #include "mt.h"
                     59:
                     60: #define b_forw b_hash.le_next
                     61:
                     62: int    mscp_match(struct device *, struct cfdata *, void *);
                     63: void   mscp_attach(struct device *, struct device *, void *);
                     64: void   mscp_start(struct       mscp_softc *);
                     65: int    mscp_init(struct  mscp_softc *);
                     66: void   mscp_initds(struct mscp_softc *);
                     67: int    mscp_waitstep(struct mscp_softc *, int, int);
                     68:
                     69: struct cfattach mscpbus_ca = {
                     70:        sizeof(struct mscp_softc), (cfmatch_t)mscp_match, mscp_attach
                     71: };
                     72:
                     73: struct cfdriver mscpbus_cd = {
                     74:        NULL, "mscpbus", DV_DULL
                     75: };
                     76:
                     77: #define        READ_SA         (bus_space_read_2(mi->mi_iot, mi->mi_sah, 0))
                     78: #define        READ_IP         (bus_space_read_2(mi->mi_iot, mi->mi_iph, 0))
                     79: #define        WRITE_IP(x)     bus_space_write_2(mi->mi_iot, mi->mi_iph, 0, (x))
                     80: #define        WRITE_SW(x)     bus_space_write_2(mi->mi_iot, mi->mi_swh, 0, (x))
                     81:
                     82: struct mscp slavereply;
                     83:
                     84: /*
                     85:  * This function is for delay during init. Some MSCP clone card (Dilog)
                     86:  * can't handle fast read from its registers, and therefore need
                     87:  * a delay between them.
                     88:  */
                     89:
                     90: #define DELAYTEN 1000
                     91: int
                     92: mscp_waitstep(mi, mask, result)
                     93:        struct mscp_softc *mi;
                     94:        int mask, result;
                     95: {
                     96:        int     status = 1;
                     97:
                     98:        if ((READ_SA & mask) != result) {
                     99:                volatile int count = 0;
                    100:                while ((READ_SA & mask) != result) {
                    101:                        DELAY(10000);
                    102:                        count += 1;
                    103:                        if (count > DELAYTEN)
                    104:                                break;
                    105:                }
                    106:                if (count > DELAYTEN)
                    107:                        status = 0;
                    108:        }
                    109:        return status;
                    110: }
                    111:
                    112: int
                    113: mscp_match(parent, match, aux)
                    114:        struct device *parent;
                    115:        struct cfdata *match;
                    116:        void *aux;
                    117: {
                    118:        struct  mscp_attach_args *ma = aux;
                    119:
                    120: #if NRA || NRX
                    121:        if (ma->ma_type & MSCPBUS_DISK)
                    122:                return 1;
                    123: #endif
                    124: #if NMT
                    125:        if (ma->ma_type & MSCPBUS_TAPE)
                    126:                return 1;
                    127: #endif
                    128:        return 0;
                    129: };
                    130:
                    131: void
                    132: mscp_attach(parent, self, aux)
                    133:        struct device *parent, *self;
                    134:        void *aux;
                    135: {
                    136:        struct  mscp_attach_args *ma = aux;
                    137:        struct  mscp_softc *mi = (void *)self;
                    138:        volatile struct mscp *mp;
                    139:        volatile int i;
                    140:        int     timeout, next = 0;
                    141:
                    142:        mi->mi_mc = ma->ma_mc;
                    143:        mi->mi_me = NULL;
                    144:        mi->mi_type = ma->ma_type;
                    145:        mi->mi_uda = ma->ma_uda;
                    146:        mi->mi_dmat = ma->ma_dmat;
                    147:        mi->mi_dmam = ma->ma_dmam;
                    148:        mi->mi_iot = ma->ma_iot;
                    149:        mi->mi_iph = ma->ma_iph;
                    150:        mi->mi_sah = ma->ma_sah;
                    151:        mi->mi_swh = ma->ma_swh;
                    152:        mi->mi_ivec = ma->ma_ivec;
                    153:        mi->mi_adapnr = ma->ma_adapnr;
                    154:        mi->mi_ctlrnr = ma->ma_ctlrnr;
                    155:        *ma->ma_softc = mi;
                    156:        /*
                    157:         * Go out to init the bus, so that we can give commands
                    158:         * to its devices.
                    159:         */
                    160:        mi->mi_cmd.mri_size = NCMD;
                    161:        mi->mi_cmd.mri_desc = mi->mi_uda->mp_ca.ca_cmddsc;
                    162:        mi->mi_cmd.mri_ring = mi->mi_uda->mp_cmd;
                    163:        mi->mi_rsp.mri_size = NRSP;
                    164:        mi->mi_rsp.mri_desc = mi->mi_uda->mp_ca.ca_rspdsc;
                    165:        mi->mi_rsp.mri_ring = mi->mi_uda->mp_rsp;
                    166:        SIMPLEQ_INIT(&mi->mi_resq);
                    167:
                    168:        if (mscp_init(mi)) {
                    169:                printf("%s: can't init, controller hung\n",
                    170:                    mi->mi_dev.dv_xname);
                    171:                return;
                    172:        }
                    173:        for (i = 0; i < NCMD; i++) {
                    174:                mi->mi_mxiuse |= (1 << i);
                    175:                if (bus_dmamap_create(mi->mi_dmat, (64*1024), 16, (64*1024),
                    176:                    0, BUS_DMA_NOWAIT, &mi->mi_xi[i].mxi_dmam)) {
                    177:                        printf("Couldn't alloc dmamap %d\n", i);
                    178:                        return;
                    179:                }
                    180:        }
                    181:
                    182:
                    183: #if NRA
                    184:        if (ma->ma_type & MSCPBUS_DISK) {
                    185:                extern  struct mscp_device ra_device;
                    186:
                    187:                mi->mi_me = &ra_device;
                    188:        }
                    189: #endif
                    190: #if NMT
                    191:        if (ma->ma_type & MSCPBUS_TAPE) {
                    192:                extern  struct mscp_device mt_device;
                    193:
                    194:                mi->mi_me = &mt_device;
                    195:        }
                    196: #endif
                    197:        /*
                    198:         * Go out and search for sub-units on this MSCP bus,
                    199:         * and call config_found for each found.
                    200:         */
                    201: findunit:
                    202:        mp = mscp_getcp(mi, MSCP_DONTWAIT);
                    203:        if (mp == NULL)
                    204:                panic("mscpattach: no packets");
                    205:        mp->mscp_opcode = M_OP_GETUNITST;
                    206:        mp->mscp_unit = next;
                    207:        mp->mscp_modifier = M_GUM_NEXTUNIT;
                    208:        *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
                    209:        slavereply.mscp_opcode = 0;
                    210:
                    211:        i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
                    212:        mp = &slavereply;
                    213:        timeout = 1000;
                    214:        while (timeout-- > 0) {
                    215:                DELAY(10000);
                    216:                if (mp->mscp_opcode)
                    217:                        goto gotit;
                    218:        }
                    219:        printf("%s: no response to Get Unit Status request\n",
                    220:            mi->mi_dev.dv_xname);
                    221:        return;
                    222:
                    223: gotit: /*
                    224:         * Got a slave response.  If the unit is there, use it.
                    225:         */
                    226:        switch (mp->mscp_status & M_ST_MASK) {
                    227:
                    228:        case M_ST_SUCCESS:      /* worked */
                    229:        case M_ST_AVAILABLE:    /* found another drive */
                    230:                break;          /* use it */
                    231:
                    232:        case M_ST_OFFLINE:
                    233:                /*
                    234:                 * Figure out why it is off line.  It may be because
                    235:                 * it is nonexistent, or because it is spun down, or
                    236:                 * for some other reason.
                    237:                 */
                    238:                switch (mp->mscp_status & ~M_ST_MASK) {
                    239:
                    240:                case M_OFFLINE_UNKNOWN:
                    241:                        /*
                    242:                         * No such drive, and there are none with
                    243:                         * higher unit numbers either, if we are
                    244:                         * using M_GUM_NEXTUNIT.
                    245:                         */
                    246:                        mi->mi_ierr = 3;
                    247:                        return;
                    248:
                    249:                case M_OFFLINE_UNMOUNTED:
                    250:                        /*
                    251:                         * The drive is not spun up.  Use it anyway.
                    252:                         *
                    253:                         * N.B.: this seems to be a common occurrance
                    254:                         * after a power failure.  The first attempt
                    255:                         * to bring it on line seems to spin it up
                    256:                         * (and thus takes several minutes).  Perhaps
                    257:                         * we should note here that the on-line may
                    258:                         * take longer than usual.
                    259:                         */
                    260:                        break;
                    261:
                    262:                default:
                    263:                        /*
                    264:                         * In service, or something else equally unusable.
                    265:                         */
                    266:                        printf("%s: unit %d off line: ", mi->mi_dev.dv_xname,
                    267:                                mp->mscp_unit);
                    268:                        mscp_printevent((struct mscp *)mp);
                    269:                        next++;
                    270:                        goto findunit;
                    271:                }
                    272:                break;
                    273:
                    274:        default:
                    275:                printf("%s: unable to get unit status: ", mi->mi_dev.dv_xname);
                    276:                mscp_printevent((struct mscp *)mp);
                    277:                return;
                    278:        }
                    279:
                    280:        /*
                    281:         * If we get a lower number, we have circulated around all
                    282:         * devices and are finished, otherwise try to find next unit.
                    283:         * We shouldn't ever get this, it's a workaround.
                    284:         */
                    285:        if (mp->mscp_unit < next)
                    286:                return;
                    287:
                    288:        next = mp->mscp_unit + 1;
                    289:        goto findunit;
                    290: }
                    291:
                    292:
                    293: /*
                    294:  * The ctlr gets initialised, normally after boot but may also be
                    295:  * done if the ctlr gets in an unknown state. Returns 1 if init
                    296:  * fails, 0 otherwise.
                    297:  */
                    298: int
                    299: mscp_init(mi)
                    300:        struct  mscp_softc *mi;
                    301: {
                    302:        struct  mscp *mp;
                    303:        volatile int i;
                    304:        int     status, count;
                    305:        unsigned int j = 0;
                    306:
                    307:        /*
                    308:         * While we are thinking about it, reset the next command
                    309:         * and response indices.
                    310:         */
                    311:        mi->mi_cmd.mri_next = 0;
                    312:        mi->mi_rsp.mri_next = 0;
                    313:
                    314:        mi->mi_flags |= MSC_IGNOREINTR;
                    315:
                    316:        if ((mi->mi_type & MSCPBUS_KDB) == 0)
                    317:                WRITE_IP(0); /* Kick off */;
                    318:
                    319:        status = mscp_waitstep(mi, MP_STEP1, MP_STEP1);/* Wait to it wakes up */
                    320:        if (status == 0)
                    321:                return 1; /* Init failed */
                    322:        if (READ_SA & MP_ERR) {
                    323:                (*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0);
                    324:                return 1;
                    325:        }
                    326:
                    327:        /* step1 */
                    328:        WRITE_SW(MP_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) |
                    329:            MP_IE | (mi->mi_ivec >> 2));
                    330:        status = mscp_waitstep(mi, STEP1MASK, STEP1GOOD);
                    331:        if (status == 0) {
                    332:                (*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0);
                    333:                return 1;
                    334:        }
                    335:
                    336:        /* step2 */
                    337:        WRITE_SW(((mi->mi_dmam->dm_segs[0].ds_addr & 0xffff) +
                    338:            offsetof(struct mscp_pack, mp_ca.ca_rspdsc[0])) |
                    339:            (vax_cputype == VAX_780 || vax_cputype == VAX_8600 ? MP_PI : 0));
                    340:        status = mscp_waitstep(mi, STEP2MASK, STEP2GOOD(mi->mi_ivec >> 2));
                    341:        if (status == 0) {
                    342:                (*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0);
                    343:                return 1;
                    344:        }
                    345:
                    346:        /* step3 */
                    347:        WRITE_SW((mi->mi_dmam->dm_segs[0].ds_addr >> 16));
                    348:        status = mscp_waitstep(mi, STEP3MASK, STEP3GOOD);
                    349:        if (status == 0) {
                    350:                (*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0);
                    351:                return 1;
                    352:        }
                    353:        i = READ_SA & 0377;
                    354:        printf(": version %d model %d\n", i & 15, i >> 4);
                    355:
                    356: #define BURST 4 /* XXX */
                    357:        if (mi->mi_type & MSCPBUS_UDA) {
                    358:                WRITE_SW(MP_GO | (BURST - 1) << 2);
                    359:                printf("%s: DMA burst size set to %d\n",
                    360:                    mi->mi_dev.dv_xname, BURST);
                    361:        }
                    362:        WRITE_SW(MP_GO);
                    363:
                    364:        mscp_initds(mi);
                    365:        mi->mi_flags &= ~MSC_IGNOREINTR;
                    366:
                    367:        /*
                    368:         * Set up all necessary info in the bus softc struct, get a
                    369:         * mscp packet and set characteristics for this controller.
                    370:         */
                    371:        mi->mi_credits = MSCP_MINCREDITS + 1;
                    372:        mp = mscp_getcp(mi, MSCP_DONTWAIT);
                    373:
                    374:        mi->mi_credits = 0;
                    375:        mp->mscp_opcode = M_OP_SETCTLRC;
                    376:        mp->mscp_unit = mp->mscp_modifier = mp->mscp_flags =
                    377:            mp->mscp_sccc.sccc_version = mp->mscp_sccc.sccc_hosttimo =
                    378:            mp->mscp_sccc.sccc_time = mp->mscp_sccc.sccc_time1 =
                    379:            mp->mscp_sccc.sccc_errlgfl = 0;
                    380:        mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC | M_CF_THIS;
                    381:        *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
                    382:        i = READ_IP;
                    383:
                    384:        count = 0;
                    385:        while (count < DELAYTEN) {
                    386:                if (((volatile int)mi->mi_flags & MSC_READY) != 0)
                    387:                        break;
                    388:                if ((j = READ_SA) & MP_ERR)
                    389:                        goto out;
                    390:                DELAY(10000);
                    391:                count += 1;
                    392:        }
                    393:        if (count == DELAYTEN) {
                    394: out:
                    395:                printf("%s: couldn't set ctlr characteristics, sa=%x\n",
                    396:                    mi->mi_dev.dv_xname, j);
                    397:                return 1;
                    398:        }
                    399:        return 0;
                    400: }
                    401:
                    402: /*
                    403:  * Initialise the various data structures that control the mscp protocol.
                    404:  */
                    405: void
                    406: mscp_initds(mi)
                    407:        struct mscp_softc *mi;
                    408: {
                    409:        struct mscp_pack *ud = mi->mi_uda;
                    410:        struct mscp *mp;
                    411:        int i;
                    412:
                    413:        for (i = 0, mp = ud->mp_rsp; i < NRSP; i++, mp++) {
                    414:                ud->mp_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT |
                    415:                    (mi->mi_dmam->dm_segs[0].ds_addr +
                    416:                    offsetof(struct mscp_pack, mp_rsp[i].mscp_cmdref));
                    417:                mp->mscp_addr = &ud->mp_ca.ca_rspdsc[i];
                    418:                mp->mscp_msglen = MSCP_MSGLEN;
                    419:        }
                    420:        for (i = 0, mp = ud->mp_cmd; i < NCMD; i++, mp++) {
                    421:                ud->mp_ca.ca_cmddsc[i] = MSCP_INT |
                    422:                    (mi->mi_dmam->dm_segs[0].ds_addr +
                    423:                    offsetof(struct mscp_pack, mp_cmd[i].mscp_cmdref));
                    424:                mp->mscp_addr = &ud->mp_ca.ca_cmddsc[i];
                    425:                mp->mscp_msglen = MSCP_MSGLEN;
                    426:                if (mi->mi_type & MSCPBUS_TAPE)
                    427:                        mp->mscp_vcid = 1;
                    428:        }
                    429: }
                    430:
                    431: static void mscp_kickaway(struct mscp_softc *);
                    432:
                    433: void
                    434: mscp_intr(mi)
                    435:        struct mscp_softc *mi;
                    436: {
                    437:        struct mscp_pack *ud = mi->mi_uda;
                    438:
                    439:        if (mi->mi_flags & MSC_IGNOREINTR)
                    440:                return;
                    441:        /*
                    442:         * Check for response and command ring transitions.
                    443:         */
                    444:        if (ud->mp_ca.ca_rspint) {
                    445:                ud->mp_ca.ca_rspint = 0;
                    446:                mscp_dorsp(mi);
                    447:        }
                    448:        if (ud->mp_ca.ca_cmdint) {
                    449:                ud->mp_ca.ca_cmdint = 0;
                    450:                MSCP_DOCMD(mi);
                    451:        }
                    452:
                    453:        /*
                    454:         * If there are any not-yet-handled request, try them now.
                    455:         */
                    456:        if (SIMPLEQ_FIRST(&mi->mi_resq))
                    457:                mscp_kickaway(mi);
                    458: }
                    459:
                    460: int
                    461: mscp_print(aux, name)
                    462:        void *aux;
                    463:        const char *name;
                    464: {
                    465:        struct drive_attach_args *da = aux;
                    466:        struct  mscp *mp = da->da_mp;
                    467:        int type = mp->mscp_guse.guse_mediaid;
                    468:
                    469:        if (name) {
                    470:                printf("%c%c", MSCP_MID_CHAR(2, type), MSCP_MID_CHAR(1, type));
                    471:                if (MSCP_MID_ECH(0, type))
                    472:                        printf("%c", MSCP_MID_CHAR(0, type));
                    473:                printf("%d at %s drive %d", MSCP_MID_NUM(type), name,
                    474:                    mp->mscp_unit);
                    475:        }
                    476:        return UNCONF;
                    477: }
                    478:
                    479: /*
                    480:  * common strategy routine for all types of MSCP devices.
                    481:  */
                    482: void
                    483: mscp_strategy(bp, usc)
                    484:        struct buf *bp;
                    485:        struct device *usc;
                    486: {
                    487:        struct  mscp_softc *mi = (void *)usc;
                    488:        int s = spl6();
                    489:
                    490: /*     SIMPLEQ_INSERT_TAIL(&mi->mi_resq, bp, xxx) */
                    491:        bp->b_actf = NULL;
                    492:        *mi->mi_resq.sqh_last = bp;
                    493:        mi->mi_resq.sqh_last = &bp->b_actf;
                    494:        mscp_kickaway(mi);
                    495:        splx(s);
                    496: }
                    497:
                    498:
                    499: void
                    500: mscp_kickaway(mi)
                    501:        struct  mscp_softc *mi;
                    502: {
                    503:        struct buf *bp;
                    504:        struct  mscp *mp;
                    505:        int next;
                    506:
                    507:        while ((bp = SIMPLEQ_FIRST(&mi->mi_resq))) {
                    508:                /*
                    509:                 * Ok; we are ready to try to start a xfer. Get a MSCP packet
                    510:                 * and try to start...
                    511:                 */
                    512:                if ((mp = mscp_getcp(mi, MSCP_DONTWAIT)) == NULL) {
                    513:                        if (mi->mi_credits > MSCP_MINCREDITS)
                    514:                                printf("%s: command ring too small\n",
                    515:                                    mi->mi_dev.dv_parent->dv_xname);
                    516:                        /*
                    517:                         * By some (strange) reason we didn't get a MSCP packet.
                    518:                         * Just return and wait for free packets.
                    519:                         */
                    520:                        return;
                    521:                }
                    522:
                    523:                if ((next = (ffs(mi->mi_mxiuse) - 1)) < 0)
                    524:                        panic("no mxi buffers");
                    525:                mi->mi_mxiuse &= ~(1 << next);
                    526:                if (mi->mi_xi[next].mxi_inuse)
                    527:                        panic("mxi inuse");
                    528:                /*
                    529:                 * Set up the MSCP packet and ask the ctlr to start.
                    530:                 */
                    531:                mp->mscp_opcode =
                    532:                    (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE;
                    533:                mp->mscp_cmdref = next;
                    534:                mi->mi_xi[next].mxi_bp = bp;
                    535:                mi->mi_xi[next].mxi_mp = mp;
                    536:                mi->mi_xi[next].mxi_inuse = 1;
                    537:                bp->b_resid = next;
                    538:                (*mi->mi_me->me_fillin)(bp, mp);
                    539:                (*mi->mi_mc->mc_go)(mi->mi_dev.dv_parent, &mi->mi_xi[next]);
                    540:                if ((mi->mi_resq.sqh_first = bp->b_actf) == NULL)
                    541:                        mi->mi_resq.sqh_last = &mi->mi_resq.sqh_first;
                    542: #if 0
                    543:                mi->mi_w = bp->b_actf;
                    544: #endif
                    545:        }
                    546: }
                    547:
                    548: void
                    549: mscp_dgo(mi, mxi)
                    550:        struct mscp_softc *mi;
                    551:        struct mscp_xi *mxi;
                    552: {
                    553:        volatile int i;
                    554:        struct  mscp *mp;
                    555:
                    556:        /*
                    557:         * Fill in the MSCP packet and move the buffer to the I/O wait queue.
                    558:         */
                    559:        mp = mxi->mxi_mp;
                    560:        mp->mscp_seq.seq_buffer = mxi->mxi_dmam->dm_segs[0].ds_addr;
                    561:
                    562:        *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
                    563:        i = READ_IP;
                    564: }
                    565:
                    566: #ifdef DIAGNOSTIC
                    567: /*
                    568:  * Dump the entire contents of an MSCP packet in hex.  Mainly useful
                    569:  * for debugging....
                    570:  */
                    571: void
                    572: mscp_hexdump(mp)
                    573:        struct mscp *mp;
                    574: {
                    575:        long *p = (long *) mp;
                    576:        int i = mp->mscp_msglen;
                    577:
                    578:        if (i > 256)            /* sanity */
                    579:                i = 256;
                    580:        i /= sizeof (*p);       /* ASSUMES MULTIPLE OF sizeof(long) */
                    581:        while (--i >= 0)
                    582:                printf("0x%x ", (int)*p++);
                    583:        printf("\n");
                    584: }
                    585: #endif
                    586:
                    587: /*
                    588:  * MSCP error reporting
                    589:  */
                    590:
                    591: /*
                    592:  * Messages for the various subcodes.
                    593:  */
                    594: static char unknown_msg[] = "unknown subcode";
                    595:
                    596: /*
                    597:  * Subcodes for Success (0)
                    598:  */
                    599: static char *succ_msgs[] = {
                    600:        "normal",               /* 0 */
                    601:        "spin down ignored",    /* 1 = Spin-Down Ignored */
                    602:        "still connected",      /* 2 = Still Connected */
                    603:        unknown_msg,
                    604:        "dup. unit #",          /* 4 = Duplicate Unit Number */
                    605:        unknown_msg,
                    606:        unknown_msg,
                    607:        unknown_msg,
                    608:        "already online",       /* 8 = Already Online */
                    609:        unknown_msg,
                    610:        unknown_msg,
                    611:        unknown_msg,
                    612:        unknown_msg,
                    613:        unknown_msg,
                    614:        unknown_msg,
                    615:        unknown_msg,
                    616:        "still online",         /* 16 = Still Online */
                    617: };
                    618:
                    619: /*
                    620:  * Subcodes for Invalid Command (1)
                    621:  */
                    622: static char *icmd_msgs[] = {
                    623:        "invalid msg length",   /* 0 = Invalid Message Length */
                    624: };
                    625:
                    626: /*
                    627:  * Subcodes for Command Aborted (2)
                    628:  */
                    629: /* none known */
                    630:
                    631: /*
                    632:  * Subcodes for Unit Offline (3)
                    633:  */
                    634: static char *offl_msgs[] = {
                    635:        "unknown drive",        /* 0 = Unknown, or online to other ctlr */
                    636:        "not mounted",          /* 1 = Unmounted, or RUN/STOP at STOP */
                    637:        "inoperative",          /* 2 = Unit Inoperative */
                    638:        unknown_msg,
                    639:        "duplicate",            /* 4 = Duplicate Unit Number */
                    640:        unknown_msg,
                    641:        unknown_msg,
                    642:        unknown_msg,
                    643:        "in diagnosis",         /* 8 = Disabled by FS or diagnostic */
                    644: };
                    645:
                    646: /*
                    647:  * Subcodes for Unit Available (4)
                    648:  */
                    649: /* none known */
                    650:
                    651: /*
                    652:  * Subcodes for Media Format Error (5)
                    653:  */
                    654: static char *media_fmt_msgs[] = {
                    655:        "fct unread - edc",     /* 0 = FCT unreadable */
                    656:        "invalid sector header",/* 1 = Invalid Sector Header */
                    657:        "not 512 sectors",      /* 2 = Not 512 Byte Sectors */
                    658:        "not formatted",        /* 3 = Not Formatted */
                    659:        "fct ecc",              /* 4 = FCT ECC */
                    660: };
                    661:
                    662: /*
                    663:  * Subcodes for Write Protected (6)
                    664:  * N.B.:  Code 6 subcodes are 7 bits higher than other subcodes
                    665:  * (i.e., bits 12-15).
                    666:  */
                    667: static char *wrprot_msgs[] = {
                    668:        unknown_msg,
                    669:        "software",             /* 1 = Software Write Protect */
                    670:        "hardware",             /* 2 = Hardware Write Protect */
                    671: };
                    672:
                    673: /*
                    674:  * Subcodes for Compare Error (7)
                    675:  */
                    676: /* none known */
                    677:
                    678: /*
                    679:  * Subcodes for Data Error (8)
                    680:  */
                    681: static char *data_msgs[] = {
                    682:        "forced error",         /* 0 = Forced Error (software) */
                    683:        unknown_msg,
                    684:        "header compare",       /* 2 = Header Compare Error */
                    685:        "sync timeout",         /* 3 = Sync Timeout Error */
                    686:        unknown_msg,
                    687:        unknown_msg,
                    688:        unknown_msg,
                    689:        "uncorrectable ecc",    /* 7 = Uncorrectable ECC */
                    690:        "1 symbol ecc",         /* 8 = 1 bit ECC */
                    691:        "2 symbol ecc",         /* 9 = 2 bit ECC */
                    692:        "3 symbol ecc",         /* 10 = 3 bit ECC */
                    693:        "4 symbol ecc",         /* 11 = 4 bit ECC */
                    694:        "5 symbol ecc",         /* 12 = 5 bit ECC */
                    695:        "6 symbol ecc",         /* 13 = 6 bit ECC */
                    696:        "7 symbol ecc",         /* 14 = 7 bit ECC */
                    697:        "8 symbol ecc",         /* 15 = 8 bit ECC */
                    698: };
                    699:
                    700: /*
                    701:  * Subcodes for Host Buffer Access Error (9)
                    702:  */
                    703: static char *host_buffer_msgs[] = {
                    704:        unknown_msg,
                    705:        "odd xfer addr",        /* 1 = Odd Transfer Address */
                    706:        "odd xfer count",       /* 2 = Odd Transfer Count */
                    707:        "non-exist. memory",    /* 3 = Non-Existent Memory */
                    708:        "memory parity",        /* 4 = Memory Parity Error */
                    709: };
                    710:
                    711: /*
                    712:  * Subcodes for Controller Error (10)
                    713:  */
                    714: static char *cntlr_msgs[] = {
                    715:        unknown_msg,
                    716:        "serdes overrun",       /* 1 = Serialiser/Deserialiser Overrun */
                    717:        "edc",                  /* 2 = Error Detection Code? */
                    718:        "inconsistent internal data struct",/* 3 = Internal Error */
                    719: };
                    720:
                    721: /*
                    722:  * Subcodes for Drive Error (11)
                    723:  */
                    724: static char *drive_msgs[] = {
                    725:        unknown_msg,
                    726:        "sdi command timeout",  /* 1 = SDI Command Timeout */
                    727:        "ctlr detected protocol",/* 2 = Controller Detected Protocol Error */
                    728:        "positioner",           /* 3 = Positioner Error */
                    729:        "lost rd/wr ready",     /* 4 = Lost R/W Ready Error */
                    730:        "drive clock dropout",  /* 5 = Lost Drive Clock */
                    731:        "lost recvr ready",     /* 6 = Lost Receiver Ready */
                    732:        "drive detected error", /* 7 = Drive Error */
                    733:        "ctlr detected pulse or parity",/* 8 = Pulse or Parity Error */
                    734: };
                    735:
                    736: /*
                    737:  * The following table correlates message codes with the
                    738:  * decoding strings.
                    739:  */
                    740: struct code_decode {
                    741:        char    *cdc_msg;
                    742:        int     cdc_nsubcodes;
                    743:        char    **cdc_submsgs;
                    744: } code_decode[] = {
                    745: #define SC(m)  sizeof (m) / sizeof (m[0]), m
                    746:        {"success",                     SC(succ_msgs)},
                    747:        {"invalid command",             SC(icmd_msgs)},
                    748:        {"command aborted",             0, 0},
                    749:        {"unit offline",                SC(offl_msgs)},
                    750:        {"unit available",              0, 0},
                    751:        {"media format error",          SC(media_fmt_msgs)},
                    752:        {"write protected",             SC(wrprot_msgs)},
                    753:        {"compare error",               0, 0},
                    754:        {"data error",                  SC(data_msgs)},
                    755:        {"host buffer access error",    SC(host_buffer_msgs)},
                    756:        {"controller error",            SC(cntlr_msgs)},
                    757:        {"drive error",                 SC(drive_msgs)},
                    758: #undef SC
                    759: };
                    760:
                    761: /*
                    762:  * Print the decoded error event from an MSCP error datagram.
                    763:  */
                    764: void
                    765: mscp_printevent(mp)
                    766:        struct mscp *mp;
                    767: {
                    768:        int event = mp->mscp_event;
                    769:        struct code_decode *cdc;
                    770:        int c, sc;
                    771:        char *cm, *scm;
                    772:
                    773:        /*
                    774:         * The code is the lower six bits of the event number (aka
                    775:         * status).  If that is 6 (write protect), the subcode is in
                    776:         * bits 12-15; otherwise, it is in bits 5-11.
                    777:         * I WONDER WHAT THE OTHER BITS ARE FOR.  IT SURE WOULD BE
                    778:         * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
                    779:         */
                    780:        c = event & M_ST_MASK;
                    781:        sc = (c != 6 ? event >> 5 : event >> 12) & 0x7ff;
                    782:        if (c >= sizeof code_decode / sizeof code_decode[0])
                    783:                cm = "- unknown code", scm = "??";
                    784:        else {
                    785:                cdc = &code_decode[c];
                    786:                cm = cdc->cdc_msg;
                    787:                if (sc >= cdc->cdc_nsubcodes)
                    788:                        scm = unknown_msg;
                    789:                else
                    790:                        scm = cdc->cdc_submsgs[sc];
                    791:        }
                    792:        printf(" %s (%s) (code %d, subcode %d)\n", cm, scm, c, sc);
                    793: }
                    794:
                    795: static char *codemsg[16] = {
                    796:        "lbn", "code 1", "code 2", "code 3",
                    797:        "code 4", "code 5", "rbn", "code 7",
                    798:        "code 8", "code 9", "code 10", "code 11",
                    799:        "code 12", "code 13", "code 14", "code 15"
                    800: };
                    801: /*
                    802:  * Print the code and logical block number for an error packet.
                    803:  * THIS IS PROBABLY PECULIAR TO DISK DRIVES.  IT SURE WOULD BE
                    804:  * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
                    805:  */
                    806: int
                    807: mscp_decodeerror(name, mp, mi)
                    808:        char *name;
                    809:        struct mscp *mp;
                    810:        struct mscp_softc *mi;
                    811: {
                    812:        int issoft;
                    813:        /*
                    814:         * We will get three sdi errors of type 11 after autoconfig
                    815:         * is finished; depending of searching for non-existing units.
                    816:         * How can we avoid this???
                    817:         */
                    818:        if (((mp->mscp_event & M_ST_MASK) == 11) && (mi->mi_ierr++ < 3))
                    819:                return 1;
                    820:        /*
                    821:         * For bad blocks, mp->mscp_erd.erd_hdr identifies a code and
                    822:         * the logical block number.  Code 0 is a regular block; code 6
                    823:         * is a replacement block.  The remaining codes are currently
                    824:         * undefined.  The code is in the upper four bits of the header
                    825:         * (bits 0-27 are the lbn).
                    826:         */
                    827:        issoft = mp->mscp_flags & (M_LF_SUCC | M_LF_CONT);
                    828: #define BADCODE(h)     (codemsg[(unsigned)(h) >> 28])
                    829: #define BADLBN(h)      ((h) & 0xfffffff)
                    830:
                    831:        printf("%s: drive %d %s error datagram%s:", name, mp->mscp_unit,
                    832:                issoft ? "soft" : "hard",
                    833:                mp->mscp_flags & M_LF_CONT ? " (continuing)" : "");
                    834:        switch (mp->mscp_format & 0377) {
                    835:
                    836:        case M_FM_CTLRERR:      /* controller error */
                    837:                break;
                    838:
                    839:        case M_FM_BUSADDR:      /* host memory access error */
                    840:                printf(" memory addr 0x%x:", (int)mp->mscp_erd.erd_busaddr);
                    841:                break;
                    842:
                    843:        case M_FM_DISKTRN:
                    844:                printf(" unit %d: level %d retry %d, %s %d:",
                    845:                        mp->mscp_unit,
                    846:                        mp->mscp_erd.erd_level, mp->mscp_erd.erd_retry,
                    847:                        BADCODE(mp->mscp_erd.erd_hdr),
                    848:                        (int)BADLBN(mp->mscp_erd.erd_hdr));
                    849:                break;
                    850:
                    851:        case M_FM_SDI:
                    852:                printf(" unit %d: %s %d:", mp->mscp_unit,
                    853:                        BADCODE(mp->mscp_erd.erd_hdr),
                    854:                        (int)BADLBN(mp->mscp_erd.erd_hdr));
                    855:                break;
                    856:
                    857:        case M_FM_SMLDSK:
                    858:                printf(" unit %d: small disk error, cyl %d:",
                    859:                        mp->mscp_unit, mp->mscp_erd.erd_sdecyl);
                    860:                break;
                    861:
                    862:        case M_FM_TAPETRN:
                    863:                printf(" unit %d: tape transfer error, grp 0x%x event 0%o:",
                    864:                    mp->mscp_unit, mp->mscp_erd.erd_sdecyl, mp->mscp_event);
                    865:                break;
                    866:
                    867:        case M_FM_STIERR:
                    868:                printf(" unit %d: STI error, event 0%o:", mp->mscp_unit,
                    869:                    mp->mscp_event);
                    870:                break;
                    871:
                    872:        default:
                    873:                printf(" unit %d: unknown error, format 0x%x:",
                    874:                        mp->mscp_unit, mp->mscp_format);
                    875:        }
                    876:        mscp_printevent(mp);
                    877:        return 0;
                    878: #undef BADCODE
                    879: #undef BADLBN
                    880: }

CVSweb