[BACK]Return to bugdev.c CVS log [TXT][DIR] Up to [local] / sys / arch / mvmeppc / stand / libsa

Annotation of sys/arch/mvmeppc/stand/libsa/bugdev.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: bugdev.c,v 1.4 2006/10/12 12:14:17 krw Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 1993 Paul Kranenburg
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *      This product includes software developed by Paul Kranenburg.
                     18:  * 4. The name of the author may not be used to endorse or promote products
                     19:  *    derived from this software without specific prior written permission
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     31:  */
                     32:
                     33: #include <sys/param.h>
                     34: #include <sys/disklabel.h>
                     35: #include <machine/prom.h>
                     36:
                     37: #include <stand.h>
                     38: #include <ufs.h>
                     39: #include "rawfs.h"
                     40: #include "tftpfs.h"
                     41:
                     42: #include "libsa.h"
                     43:
                     44: int errno;
                     45: int bootdev_type = BUGDEV_DISK;
                     46:
                     47: #if 1
                     48: #define md_swap_long(x) ( (((x) >> 24) & 0xff) | (((x) >> 8 ) & 0xff00) | \
                     49:                        (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000))
                     50: #else
                     51: #define md_swap_long(x) (x)
                     52: #endif
                     53:
                     54: struct bugdev_softc {
                     55:        int     fd;     /* Prom file descriptor */
                     56:        u_int   pnum;   /* Partition number */
                     57:        u_int   poff;   /* Partition offset */
                     58:        u_int   psize;  /* Partition size */
                     59:        short   clun;
                     60:        short   dlun;
                     61: } bugdev_softc[1];
                     62:
                     63: extern struct fs_ops ufs_file_system;
                     64: extern struct fs_ops tftp_file_system;
                     65: extern struct fs_ops raw_file_system;
                     66:
                     67: struct fs_ops file_system[1];
                     68:
                     69: struct mvmeprom_dskio tape_ioreq;
                     70:
                     71: #ifdef BUG_DEBUG
                     72: unsigned io = 0, mem = 0;
                     73: #define PCI_BASE 0x80000000
                     74: #define CFC *(unsigned *)(PCI_BASE + 0xcfc)
                     75: #define CF8 *(unsigned *)(PCI_BASE + 0xcf8)
                     76: #define BUS_SHIFT 16
                     77: #define DEVICE_SHIFT 11
                     78: #define FNC_SHIFT 8
                     79:
                     80: unsigned
                     81: bugpci_make_tag(bus, dev, fnc)
                     82:        int bus, dev, fnc;
                     83: {
                     84:        return (bus << BUS_SHIFT) | (dev << DEVICE_SHIFT) | (fnc << FNC_SHIFT);
                     85: }
                     86:
                     87: static unsigned
                     88: bugpci_gen_config_reg(tag, offset)
                     89:        unsigned tag;
                     90:        int offset;
                     91: {
                     92:        unsigned reg;
                     93:
                     94:        /* config mechanism #2, type 0
                     95:        /* standard cf8/cfc config */
                     96:        reg =  0x80000000 | tag  | offset;
                     97:
                     98:        return reg;
                     99: }
                    100:
                    101: /*#define DEBUG_CONFIG */
                    102: unsigned
                    103: bugpci_conf_read(bus, dev, func, offset)
                    104:        int bus, dev, func, offset;
                    105: {
                    106:
                    107:        unsigned data;
                    108:        unsigned reg, tag, xx;
                    109:
                    110:        if(offset & 3 || offset < 0 || offset >= 0x100) {
                    111:                printf ("bugpci_conf_read: bad reg %x\n", offset);
                    112:                return(~0);
                    113:        }
                    114:
                    115:         tag = bugpci_make_tag(bus, dev, func);
                    116:        reg = bugpci_gen_config_reg(tag, offset);
                    117:        reg = md_swap_long(reg);
                    118:        /* if invalid tag, return -1 */
                    119:        if (reg == 0xffffffff) {
                    120:                return 0xffffffff;
                    121:        }
                    122:
                    123:        CF8 = reg;
                    124:        xx = CF8;
                    125:        data = CFC;
                    126:        data = md_swap_long(data);
                    127:
                    128:        CF8 = 0;
                    129:
                    130:        return(data);
                    131: }
                    132:
                    133: void
                    134: bugpci_conf_write(bus, dev, func, offset, data)
                    135:        int bus, dev, func, offset;
                    136:        unsigned data;
                    137: {
                    138:        unsigned reg, tag, xx;
                    139:
                    140:         tag = bugpci_make_tag(bus, dev, func);
                    141:        reg = bugpci_gen_config_reg(tag, offset);
                    142:        reg = md_swap_long(reg);
                    143:
                    144:        /* if invalid tag, return ??? */
                    145:        if (reg == 0xffffffff) {
                    146:                return;
                    147:        }
                    148:
                    149:        CF8 = reg;
                    150:        xx = CF8;
                    151:        data = md_swap_long(data);
                    152:        CFC = data;
                    153:        CF8 = 0;
                    154:        xx = CF8;
                    155: }
                    156: #endif
                    157:
                    158: static u_long
                    159: get_long(p)
                    160:        const void *p;
                    161: {
                    162:        const unsigned char *cp = p;
                    163:
                    164:        return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
                    165: }
                    166:
                    167: /*
                    168:  * Find a valid disklabel.
                    169:  */
                    170: static int
                    171: search_label(devp, off, buf, lp, off0)
                    172:        void *devp;
                    173:        u_long off;
                    174:        char *buf;
                    175:        struct disklabel *lp;
                    176:        u_long off0;
                    177: {
                    178:        size_t read;
                    179:        struct dos_partition *p;
                    180:        int i;
                    181:        u_long poff;
                    182:        static int recursion;
                    183:
                    184:        if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
                    185:            || read != DEV_BSIZE)
                    186:                return ERDLAB;
                    187:
                    188:        if (buf[510] != 0x55 || buf[511] != 0xaa)
                    189:                return ERDLAB;
                    190:
                    191:        if (recursion++ <= 1)
                    192:                off0 += off;
                    193:        for (p = (struct dos_partition *)(buf + DOSPARTOFF), i = 4;
                    194:             --i >= 0; p++) {
                    195:                if (p->dp_typ == DOSPTYP_OPENBSD) {
                    196:                        poff = get_long(&p->dp_start) + off0;
                    197:                        if (dsk_strategy(devp, F_READ, poff + LABELSECTOR,
                    198:                                     DEV_BSIZE, buf, &read) == 0
                    199:                            && read == DEV_BSIZE) {
                    200:                                if (!getdisklabel(buf, lp)) {
                    201:                                        recursion--;
                    202:                                        return 0;
                    203:                                }
                    204:                        }
                    205:                        if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
                    206:                            || read != DEV_BSIZE) {
                    207:                                recursion--;
                    208:                                return ERDLAB;
                    209:                        }
                    210:                } else if (p->dp_typ == DOSPTYP_EXTEND) {
                    211:                        poff = get_long(&p->dp_start);
                    212:                        if (!search_label(devp, poff, buf, lp, off0)) {
                    213:                                recursion--;
                    214:                                return 0;
                    215:                        }
                    216:                        if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
                    217:                            || read != DEV_BSIZE) {
                    218:                                recursion--;
                    219:                                return ERDLAB;
                    220:                        }
                    221:                }
                    222:        }
                    223:        recursion--;
                    224:        return ERDLAB;
                    225: }
                    226:
                    227: int dsk_read_disklabel(devp)
                    228:        void *devp;
                    229: {
                    230:        static  char iobuf[MAXBSIZE];
                    231:        struct disklabel label;
                    232:        int error = 0;
                    233:        int i;
                    234:
                    235:        register struct bugdev_softc *pp = (struct bugdev_softc *)devp;
                    236:
                    237: #ifdef DEBUG
                    238:        printf("dsk_open:\n");
                    239: #endif
                    240:        /* First try to find a disklabel without MBR partitions */
                    241:        if (dsk_strategy(pp, F_READ, LABELSECTOR, DEV_BSIZE, iobuf, &i) != 0
                    242:            || i != DEV_BSIZE
                    243:            || getdisklabel(iobuf, &label)) {
                    244:                /* Else try MBR partitions */
                    245:                error = search_label(pp, 0, iobuf, &label, 0);
                    246:                if (error && error != ERDLAB)
                    247:                        return (error);
                    248:        }
                    249:        if (error == ERDLAB) {
                    250:                if (pp->pnum)
                    251:                        /* User specified a partition, but there is none */
                    252:                        return (error);
                    253:                /* No, label, just use complete disk */
                    254:                pp->poff = 0;
                    255:        } else {
                    256:                pp->poff = label.d_partitions[pp->pnum].p_offset;
                    257:                 pp->psize = label.d_partitions[pp->pnum].p_size;
                    258:        }
                    259:        return(0);
                    260: }
                    261:
                    262:
                    263: int
                    264: devopen(f, fname, file)
                    265:        struct open_file *f;
                    266:        const char *fname;
                    267:        char **file;
                    268: {
                    269:        register struct bugdev_softc *pp = &bugdev_softc[0];
                    270:        int     error;
                    271:        char    *dev, *cp;
                    272:
                    273:        pp->clun = (short)bugargs.ctrl_lun;
                    274:        pp->dlun =  (short)bugargs.dev_lun;
                    275:        pp->poff = 0;
                    276:        pp->psize = 0;
                    277:        pp->fd = 0;
                    278:        pp->pnum = 0;
                    279:
                    280:        f->f_devdata = (void *)pp;
                    281:
                    282:        switch (bootdev_type) {
                    283:        case BUGDEV_DISK:
                    284:                dev = bugargs.arg_start;
                    285:                /*
                    286:                 * Extract partition # from boot device string.
                    287:                 */
                    288:                for (cp = dev; *cp; cp++) /* void */;
                    289:                while (*cp != '/' && cp > dev) {
                    290:                        if (*cp == ':')
                    291:                                pp->pnum = *(cp+1) - 'a';
                    292:                        --cp;
                    293:                }
                    294:
                    295:                error = dsk_read_disklabel(pp);
                    296:                if (error)
                    297:                        return(error);
                    298:
                    299:                bcopy(&ufs_file_system, file_system, sizeof file_system[0]);
                    300:                break;
                    301:
                    302:        case BUGDEV_NET:
                    303:                bcopy(&tftp_file_system, file_system, sizeof file_system[0]);
                    304:                break;
                    305:
                    306:        case BUGDEV_TAPE:
                    307:                bcopy(&raw_file_system, file_system, sizeof file_system[0]);
                    308:                break;
                    309:        }
                    310:
                    311:        f->f_dev = &devsw[bootdev_type];
                    312:        nfsys = 1;
                    313:        *file = (char *)fname;
                    314:        return (0);
                    315: }
                    316:
                    317: /* silly block scale factor */
                    318: #define BUG_BLOCK_SIZE 256
                    319: #define BUG_SCALE (512/BUG_BLOCK_SIZE)
                    320: int
                    321: dsk_strategy(devdata, func, dblk, size, buf, rsize)
                    322:        void *devdata;
                    323:        int func;
                    324:        daddr_t dblk;
                    325:        size_t size;
                    326:        void *buf;
                    327:        size_t *rsize;
                    328: {
                    329:        struct mvmeprom_dskio dio;
                    330:        register struct bugdev_softc *pp = (struct bugdev_softc *)devdata;
                    331:        daddr_t blk = dblk + pp->poff;
                    332:
                    333:        twiddle();
                    334:
                    335:        dio.ctrl_lun = pp->clun;
                    336:        dio.dev_lun = pp->dlun;
                    337:        dio.status = 0;
                    338:        dio.pbuffer = buf;
                    339:        dio.blk_num = blk * BUG_SCALE;
                    340:        dio.blk_cnt = size / BUG_BLOCK_SIZE; /* assumed size in bytes */
                    341:        dio.flag = 0;
                    342:        dio.addr_mod = 0;
                    343: #ifdef DEBUG
                    344:        printf("dsk_strategy: size=%d blk=%d buf=%x\n", size, blk, buf);
                    345:        printf("ctrl %d dev %d\n", dio.ctrl_lun, dio.dev_lun);
                    346: #endif
                    347:        mvmeprom_diskrd(&dio);
                    348:
                    349:        *rsize = dio.blk_cnt * BUG_BLOCK_SIZE;
                    350: #ifdef DEBUG
                    351: printf("rsize %d status %x\n", *rsize, dio.status);
                    352: #endif
                    353:
                    354:        if (dio.status)
                    355:                return (EIO);
                    356:        return (0);
                    357: }
                    358:
                    359: int
                    360: dsk_open(f)
                    361:        struct open_file *f;
                    362: {
                    363: #ifdef DEBUG
                    364:        register struct bugdev_softc *pp = (struct bugdev_softc *)f->f_devdata;
                    365:        printf("dsk_open:\n");
                    366:        printf("using mvmebug ctrl %d dev %d\n",
                    367:                pp->clun, pp->dlun);
                    368: #endif
                    369:        return (0);
                    370: }
                    371:
                    372: int
                    373: dsk_close(f)
                    374:        struct open_file *f;
                    375: {
                    376:        return (EIO);
                    377: }
                    378:
                    379: int
                    380: dsk_ioctl(f, cmd, data)
                    381:        struct open_file *f;
                    382:        u_long cmd;
                    383:        void *data;
                    384: {
                    385:        return (EIO);
                    386: }
                    387:
                    388: #define NFR_TIMEOUT    5
                    389: /* netboot stuff */
                    390: int
                    391: net_strategy(devdata, func, nblk, size, buf, rsize)
                    392:        void *devdata;
                    393:        int func;
                    394:        daddr_t nblk;
                    395:        size_t size;
                    396:        void *buf;
                    397:        size_t *rsize;
                    398: {
                    399:        int attempts = 0;
                    400:    struct mvmeprom_netfread nfr;
                    401:        register struct bugdev_softc *pp = (struct bugdev_softc *)devdata;
                    402:
                    403: retry:
                    404:
                    405:    attempts+=1;
                    406:
                    407:    nfr.clun = pp->clun;
                    408:        nfr.dlun = pp->dlun;
                    409:        nfr.status = 0;
                    410:        nfr.addr = buf;
                    411:        nfr.bytes = 0;
                    412:        nfr.blk = nblk;
                    413:        nfr.timeout = NFR_TIMEOUT;
                    414: #ifdef DEBUG
                    415:        printf("net_strategy: size=%d blk=%d buf=%x\n", size, nblk, buf);
                    416:        printf("ctrl %d dev %d\n", nfr.clun, nfr.dlun);
                    417: #endif
                    418:        mvmeprom_netfread(&nfr);
                    419:
                    420: #ifdef BUG_DEBUG
                    421:        io = bugpci_conf_read(0, 14, 0, 0x10) & ~0xf;
                    422:        mem = bugpci_conf_read(0, 14, 0, 0x14) & ~0xf;
                    423:
                    424:        printf(" IO @ %x\n", io);
                    425:        printf("MEM @ %x\n", mem);
                    426:
                    427: #define PRINT_REG(regname, x) printf("%s = 0x%x\n", regname, \
                    428:            md_swap_long(*(unsigned *)(io + x)))
                    429:
                    430:         PRINT_REG("CSR0", 0x00);
                    431:         PRINT_REG("CSR1", 0x08);
                    432:         PRINT_REG("CSR2", 0x10);
                    433:         PRINT_REG("CSR3", 0x18);
                    434:         PRINT_REG("CSR4", 0x20);
                    435:         PRINT_REG("CSR5", 0x28);
                    436:         PRINT_REG("CSR6", 0x30);
                    437:         PRINT_REG("CSR7", 0x38);
                    438:         PRINT_REG("CSR8", 0x40);
                    439:         PRINT_REG("CSR9", 0x48);
                    440:         PRINT_REG("CSR10", 0x50);
                    441:         PRINT_REG("CSR11", 0x58);
                    442:         PRINT_REG("CSR12", 0x60);
                    443:         PRINT_REG("CSR13", 0x68);
                    444:         PRINT_REG("CSR14", 0x70);
                    445:         PRINT_REG("CSR15", 0x78);
                    446: #endif
                    447:        if (rsize) {
                    448:                *rsize = nfr.bytes;
                    449:        }
                    450: #ifdef DEBUG
                    451:        printf("rsize %d status %x\n", *rsize, nfr.status);
                    452: #endif
                    453:
                    454:        if (nfr.status)
                    455:       if (attempts < 10)
                    456:          goto retry;
                    457:       else
                    458:                   return (EIO);
                    459:        return (0);
                    460: }
                    461:
                    462: int
                    463: net_open(struct open_file *f, ...)
                    464: {
                    465:        va_list ap;
                    466:        struct mvmeprom_netfopen nfo;
                    467:         register struct bugdev_softc *pp = (struct bugdev_softc *)f->f_devdata;
                    468:        char *filename;
                    469:        short nfoerr = 0;
                    470:        va_start(ap, f);
                    471:        filename = va_arg(ap, char *);
                    472:        va_end(ap);
                    473:
                    474: #ifdef DEBUG
                    475:        printf("net_open: using mvmebug ctrl %d dev %d, filename: %s\n",
                    476:            pp->clun, pp->dlun, filename);
                    477: #endif
                    478:        nfo.clun = pp->clun;
                    479:        nfo.dlun = pp->dlun;
                    480:        nfo.status = 0;
                    481:        strlcpy(nfo.filename, filename, sizeof nfo.filename);
                    482:        /* .NETFOPN syscall */
                    483:        mvmeprom_netfopen(&nfo);
                    484:
                    485: #ifdef DEBUG
                    486:        if (nfo.status) {
                    487:                nfoerr = nfo.status;
                    488:                printf("net_open: ci err = 0x%x, cd err = 0x%x\n",
                    489:                    ((nfoerr >> 8) & 0x0F), (nfoerr & 0x0F));
                    490:        }
                    491: #endif
                    492:        return (nfo.status);
                    493: }
                    494:
                    495: int
                    496: net_close(f)
                    497:        struct open_file *f;
                    498: {
                    499:        return (EIO);
                    500: }
                    501:
                    502: int
                    503: net_ioctl(f, cmd, data)
                    504:        struct open_file *f;
                    505:        u_long cmd;
                    506:        void *data;
                    507: {
                    508:        return (EIO);
                    509: }
                    510:
                    511: int
                    512: tape_open(struct open_file *f, ...)
                    513: {
                    514:        va_list ap;
                    515:        int     error = 0;
                    516:        int     part;
                    517:        struct mvmeprom_dskio *ti;
                    518:        char *fname;            /* partition number, i.e. "1" */
                    519:
                    520:        va_start(ap, f);
                    521:        fname = va_arg(ap, char *);
                    522:        va_end(ap);
                    523:
                    524:        /*
                    525:         * Set the tape segment number to the one indicated
                    526:         * by the single digit fname passed in above.
                    527:         */
                    528:        if ((fname[0] < '0') && (fname[0] > '9')) {
                    529:                return ENOENT;
                    530:        }
                    531:        part = fname[0] - '0';
                    532:        fname = NULL;
                    533:
                    534:        /*
                    535:         * Setup our part of the saioreq.
                    536:         * (determines what gets opened)
                    537:         */
                    538:        ti = &tape_ioreq;
                    539:        bzero((caddr_t)ti, sizeof(*ti));
                    540:
                    541:        ti->ctrl_lun = bugargs.ctrl_lun;
                    542:        ti->dev_lun = bugargs.dev_lun;
                    543:        ti->status = 0;
                    544:        ti->pbuffer = NULL;
                    545:        ti->blk_num = part;
                    546:        ti->blk_cnt = 0;
                    547:        ti->flag = 0;
                    548:        ti->addr_mod = 0;
                    549:
                    550:        f->f_devdata = ti;
                    551:
                    552:        return (0);
                    553: }
                    554:
                    555: int
                    556: tape_close(f)
                    557:        struct open_file *f;
                    558: {
                    559:        struct mvmeprom_dskio *ti;
                    560:
                    561:
                    562:        ti = f->f_devdata;
                    563:        f->f_devdata = NULL;
                    564:        return 0;
                    565: }
                    566:
                    567: #define MVMEPROM_SCALE (512/MVMEPROM_BLOCK_SIZE)
                    568:
                    569: int
                    570: tape_strategy(devdata, flag, dblk, size, buf, rsize)
                    571:        void    *devdata;
                    572:        int     flag;
                    573:        daddr_t dblk;
                    574:        size_t  size;
                    575:        void    *buf;
                    576:        size_t  *rsize;
                    577: {
                    578:        struct mvmeprom_dskio *ti;
                    579:        int ret;
                    580:
                    581:        ti = devdata;
                    582:
                    583:        if (flag != F_READ)
                    584:                return(EROFS);
                    585:
                    586:        ti->status = 0;
                    587:        ti->pbuffer = buf;
                    588:        /* don't change block #, set in open */
                    589:        ti->blk_cnt = size / (512 / MVMEPROM_SCALE);
                    590:
                    591:        ret = mvmeprom_diskrd(ti);
                    592:
                    593:        if (ret != 0)
                    594:                return (EIO);
                    595:
                    596:        *rsize = (ti->blk_cnt / MVMEPROM_SCALE) * 512;
                    597:        ti->flag |= IGNORE_FILENUM; /* ignore next time */
                    598:
                    599:        return (0);
                    600: }
                    601:
                    602: int
                    603: tape_ioctl(f, cmd, data)
                    604:        struct open_file *f;
                    605:        u_long cmd;
                    606:        void *data;
                    607: {
                    608:        return EIO;
                    609: }
                    610:
                    611:

CVSweb