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

Annotation of src/sys/dev/mscp/mscp_subr.c, Revision 1.23.2.5

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

CVSweb <webmaster@jp.NetBSD.org>