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

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

1.1       nbrk        1: /*     $OpenBSD: mscp_disk.c,v 1.24 2007/06/20 18:15:46 deraadt Exp $  */
                      2: /*     $NetBSD: mscp_disk.c,v 1.30 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:  *     @(#)uda.c       7.32 (Berkeley) 2/13/91
                     36:  */
                     37:
                     38: /*
                     39:  * RA disk device driver
                     40:  * RX MSCP floppy disk device driver
                     41:  */
                     42:
                     43: /*
                     44:  * TODO
                     45:  *     write bad block forwarding code
                     46:  */
                     47:
                     48: #include <sys/cdefs.h>
                     49:
                     50: #include <sys/param.h>
                     51: #include <sys/buf.h>
                     52: #include <sys/device.h>
                     53: #include <sys/disk.h>
                     54: #include <sys/disklabel.h>
                     55: #include <sys/ioctl.h>
                     56: #include <sys/stat.h>
                     57: #include <sys/fcntl.h>
                     58: #include <sys/reboot.h>
                     59: #include <sys/proc.h>
                     60: #include <sys/systm.h>
                     61:
                     62: #include <ufs/ufs/dinode.h>
                     63: #include <ufs/ffs/fs.h>
                     64:
                     65: #include <machine/bus.h>
                     66: #include <machine/cpu.h>
                     67:
                     68: #include <arch/vax/mscp/mscp.h>
                     69: #include <arch/vax/mscp/mscpreg.h>
                     70: #include <arch/vax/mscp/mscpvar.h>
                     71:
                     72: #include "ra.h"
                     73:
                     74: struct cfdriver ra_cd = {
                     75:        NULL, "ra", DV_DISK
                     76: };
                     77:
                     78: struct cfdriver rx_cd = {
                     79:        NULL, "rx", DV_DISK
                     80: };
                     81:
                     82: #define RAMAJOR 9      /* RA major device number XXX */
                     83:
                     84: /*
                     85:  * Drive status, per drive
                     86:  */
                     87: struct ra_softc {
                     88:        struct  device ra_dev;  /* Autoconf struct */
                     89:        struct  disk ra_disk;
                     90:        int     ra_state;       /* open/closed state */
                     91:        u_long  ra_mediaid;     /* media id */
                     92:        int     ra_hwunit;      /* Hardware unit number */
                     93:        int     ra_havelabel;   /* true if we have a label */
                     94:        int     ra_wlabel;      /* label sector is currently writable */
                     95: };
                     96:
                     97: #define rx_softc ra_softc
                     98:
                     99: void   rxattach(struct device *, struct device *, void *);
                    100: int    rx_putonline(struct rx_softc *);
                    101: void   rrmakelabel(struct disklabel *, long);
                    102:
                    103: #if NRA
                    104:
                    105: int    ramatch(struct device *, struct cfdata *, void *);
                    106: void   raattach(struct device *, struct device *, void *);
                    107: int    raopen(dev_t, int, int, struct proc *);
                    108: int    raclose(dev_t, int, int, struct proc *);
                    109: void   rastrategy(struct buf *);
                    110: int    raread(dev_t, struct uio *);
                    111: int    rawrite(dev_t, struct uio *);
                    112: int    raioctl(dev_t, int, caddr_t, int, struct proc *);
                    113: int    radump(dev_t, daddr64_t, caddr_t, size_t);
                    114: daddr64_t      rasize(dev_t);
                    115: int    ra_putonline(struct ra_softc *);
                    116:
                    117: struct cfattach ra_ca = {
                    118:        sizeof(struct ra_softc), (cfmatch_t)ramatch, rxattach
                    119: };
                    120:
                    121: /*
                    122:  * More driver definitions, for generic MSCP code.
                    123:  */
                    124:
                    125: int
                    126: ramatch(parent, cf, aux)
                    127:        struct  device *parent;
                    128:        struct  cfdata *cf;
                    129:        void    *aux;
                    130: {
                    131:        struct  drive_attach_args *da = aux;
                    132:        struct  mscp *mp = da->da_mp;
                    133:
                    134:        if ((da->da_typ & MSCPBUS_DISK) == 0)
                    135:                return 0;
                    136:        if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != mp->mscp_unit)
                    137:                return 0;
                    138:        /*
                    139:         * Check if this disk is a floppy; then don't configure it.
                    140:         * Seems to be a safe way to test it per Chris Torek.
                    141:         */
                    142:        if (MSCP_MID_ECH(1, mp->mscp_guse.guse_mediaid) == 'X' - '@')
                    143:                return 0;
                    144:        return 1;
                    145: }
                    146:
                    147: /*
                    148:  * (Try to) put the drive online. This is done the first time the
                    149:  * drive is opened, or if it har fallen offline.
                    150:  */
                    151: int
                    152: ra_putonline(ra)
                    153:        struct ra_softc *ra;
                    154: {
                    155:        struct  disklabel *dl;
                    156:        char *msg;
                    157:
                    158:        if (rx_putonline(ra) != MSCP_DONE)
                    159:                return MSCP_FAILED;
                    160:
                    161:        dl = ra->ra_disk.dk_label;
                    162:
                    163:        ra->ra_state = DK_RDLABEL;
                    164:        printf("%s", ra->ra_dev.dv_xname);
                    165:        if ((msg = readdisklabel(MAKEDISKDEV(RAMAJOR, ra->ra_dev.dv_unit,
                    166:            RAW_PART), rastrategy, dl, 0)) != NULL) {
                    167:                /*printf(": %s", msg);*/
                    168:        } else {
                    169:                ra->ra_havelabel = 1;
                    170:                ra->ra_state = DK_OPEN;
                    171:        }
                    172:
                    173:        printf(": size %lld sectors\n", DL_GETDSIZE(dl));
                    174:
                    175:        return MSCP_DONE;
                    176: }
                    177:
                    178: /*
                    179:  * Open a drive.
                    180:  */
                    181: /*ARGSUSED*/
                    182: int
                    183: raopen(dev, flag, fmt, p)
                    184:        dev_t dev;
                    185:        int flag, fmt;
                    186:        struct  proc *p;
                    187: {
                    188:        struct ra_softc *ra;
                    189:        int part, unit, mask;
                    190:        /*
                    191:         * Make sure this is a reasonable open request.
                    192:         */
                    193:        unit = DISKUNIT(dev);
                    194:        if (unit >= ra_cd.cd_ndevs)
                    195:                return ENXIO;
                    196:        ra = ra_cd.cd_devs[unit];
                    197:        if (ra == 0)
                    198:                return ENXIO;
                    199:
                    200:        /*
                    201:         * If this is the first open; we must first try to put
                    202:         * the disk online (and read the label).
                    203:         */
                    204:        if (ra->ra_state == DK_CLOSED)
                    205:                if (ra_putonline(ra) == MSCP_FAILED)
                    206:                        return ENXIO;
                    207:
                    208:        /* If the disk has no label; allow writing everywhere */
                    209:        if (ra->ra_havelabel == 0)
                    210:                ra->ra_wlabel = 1;
                    211:
                    212:        part = DISKPART(dev);
                    213:        if (part >= ra->ra_disk.dk_label->d_npartitions)
                    214:                return ENXIO;
                    215:
                    216:        /*
                    217:         * Wait for the state to settle
                    218:         */
                    219: #if notyet
                    220:        while (ra->ra_state != DK_OPEN)
                    221:                if ((error = tsleep((caddr_t)ra, (PZERO + 1) | PCATCH,
                    222:                    "devopen", 0))) {
                    223:                        splx(s);
                    224:                        return (error);
                    225:                }
                    226: #endif
                    227:
                    228:        mask = 1 << part;
                    229:
                    230:        switch (fmt) {
                    231:        case S_IFCHR:
                    232:                ra->ra_disk.dk_copenmask |= mask;
                    233:                break;
                    234:        case S_IFBLK:
                    235:                ra->ra_disk.dk_bopenmask |= mask;
                    236:                break;
                    237:        }
                    238:        ra->ra_disk.dk_openmask |= mask;
                    239:        return 0;
                    240: }
                    241:
                    242: /* ARGSUSED */
                    243: int
                    244: raclose(dev, flags, fmt, p)
                    245:        dev_t dev;
                    246:        int flags, fmt;
                    247:        struct  proc *p;
                    248: {
                    249:        int unit = DISKUNIT(dev);
                    250:        struct ra_softc *ra = ra_cd.cd_devs[unit];
                    251:        int mask = (1 << DISKPART(dev));
                    252:
                    253:        switch (fmt) {
                    254:        case S_IFCHR:
                    255:                ra->ra_disk.dk_copenmask &= ~mask;
                    256:                break;
                    257:        case S_IFBLK:
                    258:                ra->ra_disk.dk_bopenmask &= ~mask;
                    259:                break;
                    260:        }
                    261:        ra->ra_disk.dk_openmask =
                    262:            ra->ra_disk.dk_copenmask | ra->ra_disk.dk_bopenmask;
                    263:
                    264:        /*
                    265:         * Should wait for I/O to complete on this partition even if
                    266:         * others are open, but wait for work on blkflush().
                    267:         */
                    268: #if notyet
                    269:        if (ra->ra_openpart == 0) {
                    270:                s = spluba();
                    271:                while (BUFQ_FIRST(&udautab[unit]) != NULL)
                    272:                        (void) tsleep(&udautab[unit], PZERO - 1,
                    273:                            "raclose", 0);
                    274:                splx(s);
                    275:                ra->ra_state = CLOSED;
                    276:                ra->ra_wlabel = 0;
                    277:        }
                    278: #endif
                    279:        return (0);
                    280: }
                    281:
                    282: /*
                    283:  * Queue a transfer request, and if possible, hand it to the controller.
                    284:  */
                    285: void
                    286: rastrategy(bp)
                    287:        struct buf *bp;
                    288: {
                    289:        int unit;
                    290:        struct ra_softc *ra;
                    291:        int s;
                    292:
                    293:        /*
                    294:         * Make sure this is a reasonable drive to use.
                    295:         */
                    296:        unit = DISKUNIT(bp->b_dev);
                    297:        if (unit >= ra_cd.cd_ndevs || (ra = ra_cd.cd_devs[unit]) == NULL) {
                    298:                bp->b_error = ENXIO;
                    299:                bp->b_flags |= B_ERROR;
                    300:                goto done;
                    301:        }
                    302:        /*
                    303:         * If drive is open `raw' or reading label, let it at it.
                    304:         */
                    305:        if (ra->ra_state == DK_RDLABEL) {
                    306:                mscp_strategy(bp, ra->ra_dev.dv_parent);
                    307:                return;
                    308:        }
                    309:
                    310:        /* If disk is not online, try to put it online */
                    311:        if (ra->ra_state == DK_CLOSED)
                    312:                if (ra_putonline(ra) == MSCP_FAILED) {
                    313:                        bp->b_flags |= B_ERROR;
                    314:                        bp->b_error = EIO;
                    315:                        goto done;
                    316:                }
                    317:
                    318:        /*
                    319:         * Determine the size of the transfer, and make sure it is
                    320:         * within the boundaries of the partition.
                    321:         */
                    322:        if (bounds_check_with_label(bp, ra->ra_disk.dk_label,
                    323:            ra->ra_wlabel) <= 0)
                    324:                goto done;
                    325:
                    326:        /* Make some statistics... /bqt */
                    327:        s = splbio();
                    328:        disk_busy(&ra->ra_disk);
                    329:        splx(s);
                    330:        mscp_strategy(bp, ra->ra_dev.dv_parent);
                    331:        return;
                    332:
                    333: done:
                    334:        s = splbio();
                    335:        biodone(bp);
                    336:        splx(s);
                    337: }
                    338:
                    339: int
                    340: raread(dev, uio)
                    341:        dev_t dev;
                    342:        struct uio *uio;
                    343: {
                    344:
                    345:        return (physio(rastrategy, NULL, dev, B_READ, minphys, uio));
                    346: }
                    347:
                    348: int
                    349: rawrite(dev, uio)
                    350:        dev_t dev;
                    351:        struct uio *uio;
                    352: {
                    353:
                    354:        return (physio(rastrategy, NULL, dev, B_WRITE, minphys, uio));
                    355: }
                    356:
                    357: /*
                    358:  * I/O controls.
                    359:  */
                    360: int
                    361: raioctl(dev, cmd, data, flag, p)
                    362:        dev_t dev;
                    363:        int cmd;
                    364:        caddr_t data;
                    365:        int flag;
                    366:        struct proc *p;
                    367: {
                    368:        int unit = DISKUNIT(dev);
                    369:        struct disklabel *lp, *tp;
                    370:        struct ra_softc *ra = ra_cd.cd_devs[unit];
                    371:        int error = 0;
                    372:
                    373:        lp = ra->ra_disk.dk_label;
                    374:
                    375:        switch (cmd) {
                    376:
                    377:        case DIOCGDINFO:
                    378:                bcopy(lp, data, sizeof (struct disklabel));
                    379:                break;
                    380:
                    381:        case DIOCGPART:
                    382:                ((struct partinfo *)data)->disklab = lp;
                    383:                ((struct partinfo *)data)->part =
                    384:                    &lp->d_partitions[DISKPART(dev)];
                    385:                break;
                    386:
                    387:        case DIOCWDINFO:
                    388:        case DIOCSDINFO:
                    389:                tp = (struct disklabel *)data;
                    390:
                    391:                if ((flag & FWRITE) == 0)
                    392:                        error = EBADF;
                    393:                else {
                    394:                        error = setdisklabel(lp, tp, 0);
                    395:                        if (error == 0 && cmd == DIOCWDINFO) {
                    396:                                ra->ra_wlabel = 1;
                    397:                                error = writedisklabel(dev, rastrategy, lp);
                    398:                                ra->ra_wlabel = 0;
                    399:                        }
                    400:                }
                    401:                break;
                    402:
                    403:        case DIOCWLABEL:
                    404:                if ((flag & FWRITE) == 0)
                    405:                        error = EBADF;
                    406:                else
                    407:                        ra->ra_wlabel = 1;
                    408:                break;
                    409:
                    410:        default:
                    411:                error = ENOTTY;
                    412:                break;
                    413:        }
                    414:        return (error);
                    415: }
                    416:
                    417:
                    418: int
                    419: radump(dev, blkno, va, size)
                    420:        dev_t   dev;
                    421:        daddr64_t blkno;
                    422:        caddr_t va;
                    423:        size_t  size;
                    424: {
                    425:        return ENXIO;
                    426: }
                    427:
                    428: /*
                    429:  * Return the size of a partition, if known, or -1 if not.
                    430:  */
                    431: daddr64_t
                    432: rasize(dev)
                    433:        dev_t dev;
                    434: {
                    435:        int unit = DISKUNIT(dev);
                    436:        struct ra_softc *ra;
                    437:
                    438:        if (unit >= ra_cd.cd_ndevs || ra_cd.cd_devs[unit] == 0)
                    439:                return -1;
                    440:
                    441:        ra = ra_cd.cd_devs[unit];
                    442:
                    443:        if (ra->ra_state == DK_CLOSED)
                    444:                if (ra_putonline(ra) == MSCP_FAILED)
                    445:                        return -1;
                    446:
                    447:        return DL_GETPSIZE(&ra->ra_disk.dk_label->d_partitions[DISKPART(dev)]) *
                    448:            (ra->ra_disk.dk_label->d_secsize / DEV_BSIZE);
                    449: }
                    450:
                    451: #endif /* NRA */
                    452:
                    453: #if NRX
                    454:
                    455: int    rxmatch(struct device *, struct cfdata *, void *);
                    456: int    rxopen(dev_t, int, int, struct proc *);
                    457: int    rxclose(dev_t, int, int, struct proc *);
                    458: void   rxstrategy(struct buf *);
                    459: int    rxread(dev_t, struct uio *);
                    460: int    rxwrite(dev_t, struct uio *);
                    461: int    rxioctl(dev_t, int, caddr_t, int, struct proc *);
                    462: int    rxdump(dev_t, daddr64_t, caddr_t, size_t);
                    463: daddr64_t      rxsize(dev_t);
                    464:
                    465: struct cfattach rx_ca = {
                    466:        sizeof(struct rx_softc), (cfmatch_t)rxmatch, rxattach
                    467: };
                    468:
                    469: /*
                    470:  * More driver definitions, for generic MSCP code.
                    471:  */
                    472:
                    473: int
                    474: rxmatch(parent, cf, aux)
                    475:        struct  device *parent;
                    476:        struct  cfdata *cf;
                    477:        void    *aux;
                    478: {
                    479:        struct  drive_attach_args *da = aux;
                    480:        struct  mscp *mp = da->da_mp;
                    481:
                    482:        if ((da->da_typ & MSCPBUS_DISK) == 0)
                    483:                return 0;
                    484:        if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != mp->mscp_unit)
                    485:                return 0;
                    486:        /*
                    487:         * Check if this disk is a floppy; then configure it.
                    488:         * Seems to be a safe way to test it per Chris Torek.
                    489:         */
                    490:        if (MSCP_MID_ECH(1, mp->mscp_guse.guse_mediaid) == 'X' - '@')
                    491:                return 1;
                    492:        return 0;
                    493: }
                    494:
                    495: #endif /* NRX */
                    496:
                    497: /*
                    498:  * The attach routine only checks and prints drive type.
                    499:  * Bringing the disk online is done when the disk is accessed
                    500:  * the first time.
                    501:  */
                    502: void
                    503: rxattach(parent, self, aux)
                    504:        struct  device *parent, *self;
                    505:        void    *aux;
                    506: {
                    507:        struct  rx_softc *rx = (void *)self;
                    508:        struct  drive_attach_args *da = aux;
                    509:        struct  mscp *mp = da->da_mp;
                    510:        struct  mscp_softc *mi = (void *)parent;
                    511:        struct  disklabel *dl;
                    512:
                    513:        rx->ra_mediaid = mp->mscp_guse.guse_mediaid;
                    514:        rx->ra_state = DK_CLOSED;
                    515:        rx->ra_hwunit = mp->mscp_unit;
                    516:        mi->mi_dp[mp->mscp_unit] = self;
                    517:
                    518:        rx->ra_disk.dk_name = rx->ra_dev.dv_xname;
                    519:        disk_attach((struct disk *)&rx->ra_disk);
                    520:
                    521:        /* Fill in what we know. The actual size is gotten later */
                    522:        dl = rx->ra_disk.dk_label;
                    523:
                    524:        dl->d_secsize = DEV_BSIZE;
                    525:        dl->d_nsectors = mp->mscp_guse.guse_nspt;
                    526:        dl->d_ntracks = mp->mscp_guse.guse_ngpc * mp->mscp_guse.guse_group;
                    527:        dl->d_secpercyl = dl->d_nsectors * dl->d_ntracks;
                    528:        disk_printtype(mp->mscp_unit, mp->mscp_guse.guse_mediaid);
                    529: #ifdef DEBUG
                    530:        printf("%s: nspt %d group %d ngpc %d rct %d nrpt %d nrct %d\n",
                    531:            self->dv_xname, mp->mscp_guse.guse_nspt, mp->mscp_guse.guse_group,
                    532:            mp->mscp_guse.guse_ngpc, mp->mscp_guse.guse_rctsize,
                    533:            mp->mscp_guse.guse_nrpt, mp->mscp_guse.guse_nrct);
                    534: #endif
                    535: }
                    536:
                    537: /*
                    538:  * (Try to) put the drive online. This is done the first time the
                    539:  * drive is opened, or if it har fallen offline.
                    540:  */
                    541: int
                    542: rx_putonline(rx)
                    543:        struct rx_softc *rx;
                    544: {
                    545:        struct  mscp *mp;
                    546:        struct  mscp_softc *mi = (struct mscp_softc *)rx->ra_dev.dv_parent;
                    547:        volatile int i;
                    548:
                    549:        rx->ra_state = DK_CLOSED;
                    550:        mp = mscp_getcp(mi, MSCP_WAIT);
                    551:        mp->mscp_opcode = M_OP_ONLINE;
                    552:        mp->mscp_unit = rx->ra_hwunit;
                    553:        mp->mscp_cmdref = 1;
                    554:        *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
                    555:        DELAY(10000);           /* XXX SIMH needs this. */
                    556:
                    557:        /* Poll away */
                    558:        i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
                    559:        if (tsleep(&rx->ra_dev.dv_unit, PRIBIO, "rxonline", 100*100))
                    560:                rx->ra_state = DK_CLOSED;
                    561:
                    562:        if (rx->ra_state == DK_CLOSED)
                    563:                return MSCP_FAILED;
                    564:
                    565:        return MSCP_DONE;
                    566: }
                    567:
                    568: #if NRX
                    569:
                    570: /*
                    571:  * Open a drive.
                    572:  */
                    573: /*ARGSUSED*/
                    574: int
                    575: rxopen(dev, flag, fmt, p)
                    576:        dev_t dev;
                    577:        int flag, fmt;
                    578:        struct  proc *p;
                    579: {
                    580:        struct rx_softc *rx;
                    581:        int unit;
                    582:
                    583:        /*
                    584:         * Make sure this is a reasonable open request.
                    585:         */
                    586:        unit = DISKUNIT(dev);
                    587:        if (unit >= rx_cd.cd_ndevs)
                    588:                return ENXIO;
                    589:        rx = rx_cd.cd_devs[unit];
                    590:        if (rx == 0)
                    591:                return ENXIO;
                    592:
                    593:        /*
                    594:         * If this is the first open; we must first try to put
                    595:         * the disk online (and read the label).
                    596:         */
                    597:        if (rx->ra_state == DK_CLOSED)
                    598:                if (rx_putonline(rx) == MSCP_FAILED)
                    599:                        return ENXIO;
                    600:
                    601:        return 0;
                    602: }
                    603:
                    604: /* ARGSUSED */
                    605: int
                    606: rxclose(dev, flags, fmt, p)
                    607:        dev_t dev;
                    608:        int flags, fmt;
                    609:        struct  proc *p;
                    610: {
                    611:        return (0);
                    612: }
                    613:
                    614: /*
                    615:  * Queue a transfer request, and if possible, hand it to the controller.
                    616:  *
                    617:  * This routine is broken into two so that the internal version
                    618:  * udastrat1() can be called by the (nonexistent, as yet) bad block
                    619:  * revectoring routine.
                    620:  */
                    621: void
                    622: rxstrategy(bp)
                    623:        struct buf *bp;
                    624: {
                    625:        int unit;
                    626:        struct rx_softc *rx;
                    627:        int s;
                    628:
                    629:        /*
                    630:         * Make sure this is a reasonable drive to use.
                    631:         */
                    632:        unit = DISKUNIT(bp->b_dev);
                    633:        if (unit >= rx_cd.cd_ndevs || (rx = rx_cd.cd_devs[unit]) == NULL) {
                    634:                bp->b_error = ENXIO;
                    635:                bp->b_flags |= B_ERROR;
                    636:                goto done;
                    637:        }
                    638:
                    639:        /* If disk is not online, try to put it online */
                    640:        if (rx->ra_state == DK_CLOSED)
                    641:                if (rx_putonline(rx) == MSCP_FAILED) {
                    642:                        bp->b_flags |= B_ERROR;
                    643:                        bp->b_error = EIO;
                    644:                        goto done;
                    645:                }
                    646:
                    647:        /*
                    648:         * Determine the size of the transfer, and make sure it is
                    649:         * within the boundaries of the partition.
                    650:         */
                    651:        if (bp->b_blkno >= DL_GETDSIZE(rx->ra_disk.dk_label)) {
                    652:                bp->b_resid = bp->b_bcount;
                    653:                goto done;
                    654:        }
                    655:
                    656:        /* Make some statistics... /bqt */
                    657:        s = splbio();
                    658:        disk_busy(&rx->ra_disk);
                    659:        splx(s);
                    660:        mscp_strategy(bp, rx->ra_dev.dv_parent);
                    661:        return;
                    662:
                    663: done:
                    664:        s = splbio();
                    665:        biodone(bp);
                    666:        splx(s);
                    667: }
                    668:
                    669: int
                    670: rxread(dev, uio)
                    671:        dev_t dev;
                    672:        struct uio *uio;
                    673: {
                    674:
                    675:        return (physio(rxstrategy, NULL, dev, B_READ, minphys, uio));
                    676: }
                    677:
                    678: int
                    679: rxwrite(dev, uio)
                    680:        dev_t dev;
                    681:        struct uio *uio;
                    682: {
                    683:
                    684:        return (physio(rxstrategy, NULL, dev, B_WRITE, minphys, uio));
                    685: }
                    686:
                    687: /*
                    688:  * I/O controls.
                    689:  */
                    690: int
                    691: rxioctl(dev, cmd, data, flag, p)
                    692:        dev_t dev;
                    693:        int cmd;
                    694:        caddr_t data;
                    695:        int flag;
                    696:        struct proc *p;
                    697: {
                    698:        int unit = DISKUNIT(dev);
                    699:        struct disklabel *lp;
                    700:        struct rx_softc *rx = rx_cd.cd_devs[unit];
                    701:        int error = 0;
                    702:
                    703:        lp = rx->ra_disk.dk_label;
                    704:
                    705:        switch (cmd) {
                    706:
                    707:        case DIOCGDINFO:
                    708:                bcopy(lp, data, sizeof (struct disklabel));
                    709:                break;
                    710:
                    711:        case DIOCGPART:
                    712:                ((struct partinfo *)data)->disklab = lp;
                    713:                ((struct partinfo *)data)->part =
                    714:                    &lp->d_partitions[DISKPART(dev)];
                    715:                break;
                    716:
                    717:
                    718:        case DIOCWDINFO:
                    719:        case DIOCSDINFO:
                    720:        case DIOCWLABEL:
                    721:                break;
                    722:
                    723:        default:
                    724:                error = ENOTTY;
                    725:                break;
                    726:        }
                    727:        return (error);
                    728: }
                    729:
                    730: int
                    731: rxdump(dev, blkno, va, size)
                    732:        dev_t dev;
                    733:        daddr64_t blkno;
                    734:        caddr_t va;
                    735:        size_t size;
                    736: {
                    737:
                    738:        /* Not likely. */
                    739:        return ENXIO;
                    740: }
                    741:
                    742: daddr64_t
                    743: rxsize(dev)
                    744:        dev_t dev;
                    745: {
                    746:
                    747:        return -1;
                    748: }
                    749:
                    750: #endif /* NRX */
                    751:
                    752: void   rrdgram(struct device *, struct mscp *, struct mscp_softc *);
                    753: void   rriodone(struct device *, struct buf *);
                    754: int    rronline(struct device *, struct mscp *);
                    755: int    rrgotstatus(struct device *, struct mscp *);
                    756: void   rrreplace(struct device *, struct mscp *);
                    757: int    rrioerror(struct device *, struct mscp *, struct buf *);
                    758: void   rrfillin(struct buf *, struct mscp *);
                    759: void   rrbb(struct device *, struct mscp *, struct buf *);
                    760:
                    761:
                    762: struct mscp_device ra_device = {
                    763:        rrdgram,
                    764:        rriodone,
                    765:        rronline,
                    766:        rrgotstatus,
                    767:        rrreplace,
                    768:        rrioerror,
                    769:        rrbb,
                    770:        rrfillin,
                    771: };
                    772:
                    773: /*
                    774:  * Handle an error datagram.
                    775:  * This can come from an unconfigured drive as well.
                    776:  */
                    777: void
                    778: rrdgram(usc, mp, mi)
                    779:        struct device *usc;
                    780:        struct mscp *mp;
                    781:        struct mscp_softc *mi;
                    782: {
                    783:        if (mscp_decodeerror(usc == NULL?"unconf disk" : usc->dv_xname, mp, mi))
                    784:                return;
                    785:        /*
                    786:         * SDI status information bytes 10 and 11 are the microprocessor
                    787:         * error code and front panel code respectively.  These vary per
                    788:         * drive type and are printed purely for field service information.
                    789:         */
                    790:        if (mp->mscp_format == M_FM_SDI)
                    791:                printf("\tsdi uproc error code 0x%x, front panel code 0x%x\n",
                    792:                        mp->mscp_erd.erd_sdistat[10],
                    793:                        mp->mscp_erd.erd_sdistat[11]);
                    794: }
                    795:
                    796: void
                    797: rriodone(usc, bp)
                    798:        struct device *usc;
                    799:        struct buf *bp;
                    800: {
                    801:        int s;
                    802:
                    803:        s = splbio();
                    804:        biodone(bp);
                    805:        splx(s);
                    806: }
                    807:
                    808: /*
                    809:  * A drive came on line.  Check its type and size.  Return DONE if
                    810:  * we think the drive is truly on line.         In any case, awaken anyone
                    811:  * sleeping on the drive on-line-ness.
                    812:  */
                    813: int
                    814: rronline(usc, mp)
                    815:        struct device *usc;
                    816:        struct mscp *mp;
                    817: {
                    818:        struct rx_softc *rx = (struct rx_softc *)usc;
                    819:        struct disklabel *dl;
                    820:
                    821:        wakeup((caddr_t)&usc->dv_unit);
                    822:        if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
                    823:                printf("%s: attempt to bring on line failed: ", usc->dv_xname);
                    824:                mscp_printevent(mp);
                    825:                return (MSCP_FAILED);
                    826:        }
                    827:
                    828:        rx->ra_state = DK_OPEN;
                    829:
                    830:        dl = rx->ra_disk.dk_label;
                    831:        DL_SETDSIZE(dl, mp->mscp_onle.onle_unitsize);
                    832:
                    833:        if (dl->d_secpercyl) {
                    834:                dl->d_ncylinders = DL_GETDSIZE(dl) / dl->d_secpercyl;
                    835:                dl->d_type = DTYPE_MSCP;
                    836:                dl->d_rpm = 3600;
                    837:        } else {
                    838:                dl->d_type = DTYPE_FLOPPY;
                    839:                dl->d_rpm = 300;
                    840:        }
                    841:        rrmakelabel(dl, rx->ra_mediaid);
                    842:
                    843:        return (MSCP_DONE);
                    844: }
                    845:
                    846: void
                    847: rrmakelabel(dl, type)
                    848:        struct disklabel *dl;
                    849:        long type;
                    850: {
                    851:        int n, p = 0;
                    852:
                    853:        dl->d_bbsize = BBSIZE;
                    854:        dl->d_sbsize = SBSIZE;
                    855:
                    856:        /* Create the disk name for disklabel. Phew... */
                    857:        dl->d_typename[p++] = MSCP_MID_CHAR(2, type);
                    858:        dl->d_typename[p++] = MSCP_MID_CHAR(1, type);
                    859:        if (MSCP_MID_ECH(0, type))
                    860:                dl->d_typename[p++] = MSCP_MID_CHAR(0, type);
                    861:        n = MSCP_MID_NUM(type);
                    862:        if (n > 99) {
                    863:                dl->d_typename[p++] = '1';
                    864:                n -= 100;
                    865:        }
                    866:        if (n > 9) {
                    867:                dl->d_typename[p++] = (n / 10) + '0';
                    868:                n %= 10;
                    869:        }
                    870:        dl->d_typename[p++] = n + '0';
                    871:        dl->d_typename[p] = 0;
                    872:        dl->d_npartitions = MAXPARTITIONS;
                    873:        DL_SETPSIZE(&dl->d_partitions[0], DL_GETDSIZE(dl));
                    874:        DL_SETPSIZE(&dl->d_partitions[2], DL_GETDSIZE(dl));
                    875:        DL_SETPOFFSET(&dl->d_partitions[0], 0);
                    876:        DL_SETPOFFSET(&dl->d_partitions[2], 0);
                    877:        dl->d_interleave = dl->d_headswitch = 1;
                    878:        dl->d_version = 1;
                    879:        dl->d_magic = dl->d_magic2 = DISKMAGIC;
                    880:        dl->d_checksum = dkcksum(dl);
                    881: }
                    882:
                    883: /*
                    884:  * We got some (configured) unit's status.  Return DONE if it succeeded.
                    885:  */
                    886: int
                    887: rrgotstatus(usc, mp)
                    888:        struct device *usc;
                    889:        struct mscp *mp;
                    890: {
                    891:        if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
                    892:                printf("%s: attempt to get status failed: ", usc->dv_xname);
                    893:                mscp_printevent(mp);
                    894:                return (MSCP_FAILED);
                    895:        }
                    896:        /* record for (future) bad block forwarding and whatever else */
                    897: #ifdef notyet
                    898:        uda_rasave(ui->ui_unit, mp, 1);
                    899: #endif
                    900:        return (MSCP_DONE);
                    901: }
                    902:
                    903: /*
                    904:  * A replace operation finished.
                    905:  */
                    906: /*ARGSUSED*/
                    907: void
                    908: rrreplace(usc, mp)
                    909:        struct device *usc;
                    910:        struct mscp *mp;
                    911: {
                    912:
                    913:        panic("udareplace");
                    914: }
                    915:
                    916: /*
                    917:  * A transfer failed.  We get a chance to fix or restart it.
                    918:  * Need to write the bad block forwaring code first....
                    919:  */
                    920: /*ARGSUSED*/
                    921: int
                    922: rrioerror(usc, mp, bp)
                    923:        struct device *usc;
                    924:        struct mscp *mp;
                    925:        struct buf *bp;
                    926: {
                    927:        struct ra_softc *ra = (void *)usc;
                    928:        int code = mp->mscp_event;
                    929:
                    930:        switch (code & M_ST_MASK) {
                    931:        /* The unit has fallen offline. Try to figure out why. */
                    932:        case M_ST_OFFLINE:
                    933:                bp->b_flags |= B_ERROR;
                    934:                bp->b_error = EIO;
                    935:                ra->ra_state = DK_CLOSED;
                    936:                if (code & M_OFFLINE_UNMOUNTED)
                    937:                        printf("%s: not mounted/spun down\n", usc->dv_xname);
                    938:                if (code & M_OFFLINE_DUPLICATE)
                    939:                        printf("%s: duplicate unit number!!!\n", usc->dv_xname);
                    940:                return MSCP_DONE;
                    941:
                    942:        case M_ST_AVAILABLE:
                    943:                ra->ra_state = DK_CLOSED; /* Force another online */
                    944:                return MSCP_DONE;
                    945:
                    946:        default:
                    947:                printf("%s:", usc->dv_xname);
                    948:                break;
                    949:        }
                    950:        return (MSCP_FAILED);
                    951: }
                    952:
                    953: /*
                    954:  * Fill in disk addresses in a mscp packet waiting for transfer.
                    955:  */
                    956: void
                    957: rrfillin(bp, mp)
                    958:        struct buf *bp;
                    959:        struct mscp *mp;
                    960: {
                    961:        struct rx_softc *rx = 0; /* Wall */
                    962:        struct disklabel *lp;
                    963:        int unit = DISKUNIT(bp->b_dev);
                    964:        int part = DISKPART(bp->b_dev);
                    965:
                    966: #if NRA
                    967:        if (major(bp->b_dev) == RAMAJOR)
                    968:                rx = ra_cd.cd_devs[unit];
                    969: #endif
                    970: #if NRX
                    971:        if (major(bp->b_dev) != RAMAJOR)
                    972:                rx = rx_cd.cd_devs[unit];
                    973: #endif
                    974:        lp = rx->ra_disk.dk_label;
                    975:
                    976:        mp->mscp_seq.seq_lbn = DL_GETPOFFSET(&lp->d_partitions[part]) + bp->b_blkno;
                    977:        mp->mscp_unit = rx->ra_hwunit;
                    978:        mp->mscp_seq.seq_bytecount = bp->b_bcount;
                    979: }
                    980:
                    981: /*
                    982:  * A bad block related operation finished.
                    983:  */
                    984: /*ARGSUSED*/
                    985: void
                    986: rrbb(usc, mp, bp)
                    987:        struct device *usc;
                    988:        struct mscp *mp;
                    989:        struct buf *bp;
                    990: {
                    991:
                    992:        panic("udabb");
                    993: }

CVSweb