[BACK]Return to hd.c CVS log [TXT][DIR] Up to [local] / sys / arch / hp300 / stand / common

Annotation of sys/arch/hp300/stand/common/hd.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: hd.c,v 1.6 2006/08/17 06:31:10 miod Exp $     */
                      2: /*     $NetBSD: rd.c,v 1.11 1996/12/21 21:34:40 thorpej Exp $  */
                      3:
                      4: /*
                      5:  * Copyright (c) 1988 University of Utah.
                      6:  * Copyright (c) 1982, 1990, 1993
                      7:  *     The Regents of the University of California.  All rights reserved.
                      8:  *
                      9:  * This code is derived from software contributed to Berkeley by
                     10:  * the Systems Programming Group of the University of Utah Computer
                     11:  * Science Department.
                     12:  *
                     13:  * Redistribution and use in source and binary forms, with or without
                     14:  * modification, are permitted provided that the following conditions
                     15:  * are met:
                     16:  * 1. Redistributions of source code must retain the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer.
                     18:  * 2. Redistributions in binary form must reproduce the above copyright
                     19:  *    notice, this list of conditions and the following disclaimer in the
                     20:  *    documentation and/or other materials provided with the distribution.
                     21:  * 3. Neither the name of the University nor the names of its contributors
                     22:  *    may be used to endorse or promote products derived from this software
                     23:  *    without specific prior written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     35:  * SUCH DAMAGE.
                     36:  *
                     37:  * from: Utah Hdr: rd.c 1.20 92/12/21
                     38:  *
                     39:  *     @(#)rd.c        8.1 (Berkeley) 7/15/93
                     40:  */
                     41:
                     42: /*
                     43:  * CS80/SS80 disk driver
                     44:  */
                     45: #include <sys/param.h>
                     46: #include <sys/disklabel.h>
                     47:
                     48: #include <lib/libsa/stand.h>
                     49:
                     50: #include "samachdep.h"
                     51:
                     52: #include <hp300/dev/hdreg.h>
                     53: #include "hpibvar.h"
                     54:
                     55: struct hd_iocmd hd_ioc;
                     56: struct hd_rscmd hd_rsc;
                     57: struct hd_stat hd_stat;
                     58: struct hd_ssmcmd hd_ssmc;
                     59:
                     60: struct disklabel hdlabel;
                     61:
                     62: struct hdminilabel {
                     63:        u_short npart;
                     64:        u_long  offset[MAXPARTITIONS];
                     65: };
                     66:
                     67: struct hd_softc {
                     68:        int     sc_ctlr;
                     69:        int     sc_unit;
                     70:        int     sc_part;
                     71:        char    sc_retry;
                     72:        char    sc_alive;
                     73:        short   sc_type;
                     74:        struct  hdminilabel sc_pinfo;
                     75: } hd_softc[NHPIB][NHD];
                     76:
                     77: #define        HDRETRY         5
                     78:
                     79: struct hdidentinfo {
                     80:        short   ri_hwid;
                     81:        short   ri_maxunum;
                     82:        int     ri_nblocks;
                     83: } hdidentinfo[] = {
                     84:        { HD7946AID,    0,       108416 },
                     85:        { HD9134DID,    1,        29088 },
                     86:        { HD9134LID,    1,         1232 },
                     87:        { HD7912PID,    0,       128128 },
                     88:        { HD7914PID,    0,       258048 },
                     89:        { HD7958AID,    0,       255276 },
                     90:        { HD7957AID,    0,       159544 },
                     91:        { HD7933HID,    0,       789958 },
                     92:        { HD9134LID,    1,        77840 },
                     93:        { HD7936HID,    0,       600978 },
                     94:        { HD7937HID,    0,      1116102 },
                     95:        { HD7914CTID,   0,       258048 },
                     96:        { HD7946AID,    0,       108416 },
                     97:        { HD9134LID,    1,         1232 },
                     98:        { HD7957BID,    0,       159894 },
                     99:        { HD7958BID,    0,       297108 },
                    100:        { HD7959BID,    0,       594216 },
                    101:        { HD2200AID,    0,       654948 },
                    102:        { HD2203AID,    0,      1309896 }
                    103: };
                    104: int numhdidentinfo = sizeof(hdidentinfo) / sizeof(hdidentinfo[0]);
                    105:
                    106: int    hdclose(struct open_file *);
                    107: int    hderror(int, int, int);
                    108: int    hdgetinfo(struct hd_softc *);
                    109: int    hdident(int, int);
                    110: int    hdinit(int, int);
                    111: int    hdopen(struct open_file *, int, int, int);
                    112: void   hdreset(int, int);
                    113: int    hdstrategy(void *, int, daddr_t, size_t, void *, size_t *);
                    114:
                    115: int
                    116: hdinit(int ctlr, int unit)
                    117: {
                    118:        struct hd_softc *rs = &hd_softc[ctlr][unit];
                    119:
                    120:        rs->sc_type = hdident(ctlr, unit);
                    121:        if (rs->sc_type < 0)
                    122:                return (0);
                    123:        rs->sc_alive = 1;
                    124:        return (1);
                    125: }
                    126:
                    127: void
                    128: hdreset(int ctlr, int unit)
                    129: {
                    130:        u_char stat;
                    131:
                    132:        hd_ssmc.c_unit = C_SUNIT(0);
                    133:        hd_ssmc.c_cmd = C_SSM;
                    134:        hd_ssmc.c_refm = REF_MASK;
                    135:        hd_ssmc.c_fefm = FEF_MASK;
                    136:        hd_ssmc.c_aefm = AEF_MASK;
                    137:        hd_ssmc.c_iefm = IEF_MASK;
                    138:        hpibsend(ctlr, unit, C_CMD, &hd_ssmc, sizeof(hd_ssmc));
                    139:        hpibswait(ctlr, unit);
                    140:        hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
                    141: }
                    142:
                    143: int
                    144: hdident(int ctlr, int unit)
                    145: {
                    146:        struct cs80_describe desc;
                    147:        u_char stat, cmd[3];
                    148:        char name[7];
                    149:        int id, i;
                    150:
                    151:        id = hpibid(ctlr, unit);
                    152:        if ((id & 0x200) == 0)
                    153:                return(-1);
                    154:        for (i = 0; i < numhdidentinfo; i++)
                    155:                if (id == hdidentinfo[i].ri_hwid)
                    156:                        break;
                    157:        if (i == numhdidentinfo)
                    158:                return(-1);
                    159:        id = i;
                    160:        hdreset(ctlr, unit);
                    161:        cmd[0] = C_SUNIT(0);
                    162:        cmd[1] = C_SVOL(0);
                    163:        cmd[2] = C_DESC;
                    164:        hpibsend(ctlr, unit, C_CMD, cmd, sizeof(cmd));
                    165:        hpibrecv(ctlr, unit, C_EXEC, &desc, sizeof(desc));
                    166:        hpibrecv(ctlr, unit, C_QSTAT, &stat, sizeof(stat));
                    167:        bzero(name, sizeof(name));
                    168:        if (!stat) {
                    169:                int n = desc.d_name;
                    170:                for (i = 5; i >= 0; i--) {
                    171:                        name[i] = (n & 0xf) + '0';
                    172:                        n >>= 4;
                    173:                }
                    174:        }
                    175:        /*
                    176:         * Take care of a couple of anomalies:
                    177:         * 1. 7945A and 7946A both return same HW id
                    178:         * 2. 9122S and 9134D both return same HW id
                    179:         * 3. 9122D and 9134L both return same HW id
                    180:         */
                    181:        switch (hdidentinfo[id].ri_hwid) {
                    182:        case HD7946AID:
                    183:                if (bcmp(name, "079450", 6) == 0)
                    184:                        id = HD7945A;
                    185:                else
                    186:                        id = HD7946A;
                    187:                break;
                    188:
                    189:        case HD9134LID:
                    190:                if (bcmp(name, "091340", 6) == 0)
                    191:                        id = HD9134L;
                    192:                else
                    193:                        id = HD9122D;
                    194:                break;
                    195:
                    196:        case HD9134DID:
                    197:                if (bcmp(name, "091220", 6) == 0)
                    198:                        id = HD9122S;
                    199:                else
                    200:                        id = HD9134D;
                    201:                break;
                    202:        }
                    203:        return(id);
                    204: }
                    205:
                    206: char io_buf[MAXBSIZE];
                    207:
                    208: int
                    209: hdgetinfo(struct hd_softc *rs)
                    210: {
                    211:        struct hdminilabel *pi = &rs->sc_pinfo;
                    212:        struct disklabel *lp = &hdlabel;
                    213:        char *msg;
                    214:        int err, savepart;
                    215:        size_t i;
                    216:
                    217:        bzero((caddr_t)lp, sizeof *lp);
                    218:        lp->d_secsize = DEV_BSIZE;
                    219:
                    220:        /* Disklabel is always from RAW_PART. */
                    221:        savepart = rs->sc_part;
                    222:        rs->sc_part = RAW_PART;
                    223:        err = hdstrategy(rs, F_READ, LABELSECTOR,
                    224:            lp->d_secsize ? lp->d_secsize : DEV_BSIZE, io_buf, &i);
                    225:        rs->sc_part = savepart;
                    226:
                    227:        if (err) {
                    228:                printf("hdgetinfo: hdstrategy error %d\n", err);
                    229:                return(0);
                    230:        }
                    231:
                    232:        msg = getdisklabel(io_buf, lp);
                    233:        if (msg) {
                    234:                printf("hd(%d,%d,%d): WARNING: %s, ",
                    235:                       rs->sc_ctlr, rs->sc_unit, rs->sc_part, msg);
                    236:                printf("defining `c' partition as entire disk\n");
                    237:                pi->npart = 3;
                    238:                pi->offset[0] = pi->offset[1] = -1;
                    239:                pi->offset[2] = 0;
                    240:        } else {
                    241:                pi->npart = lp->d_npartitions;
                    242:                for (i = 0; i < pi->npart; i++)
                    243:                        pi->offset[i] = lp->d_partitions[i].p_size == 0 ?
                    244:                                -1 : lp->d_partitions[i].p_offset;
                    245:        }
                    246:        return(1);
                    247: }
                    248:
                    249: int
                    250: hdopen(struct open_file *f, int ctlr, int unit, int part)
                    251: {
                    252:        struct hd_softc *rs;
                    253:
                    254:        if (ctlr >= NHPIB || hpibalive(ctlr) == 0)
                    255:                return (EADAPT);
                    256:        if (unit >= NHD)
                    257:                return (ECTLR);
                    258:        rs = &hd_softc[ctlr][unit];
                    259:        rs->sc_part = part;
                    260:        rs->sc_unit = unit;
                    261:        rs->sc_ctlr = ctlr;
                    262:        if (rs->sc_alive == 0) {
                    263:                if (hdinit(ctlr, unit) == 0)
                    264:                        return (ENXIO);
                    265:                if (hdgetinfo(rs) == 0)
                    266:                        return (ERDLAB);
                    267:        }
                    268:        if (part != RAW_PART &&     /* always allow RAW_PART to be opened */
                    269:            (part >= rs->sc_pinfo.npart || rs->sc_pinfo.offset[part] == -1))
                    270:                return (EPART);
                    271:        f->f_devdata = (void *)rs;
                    272:        return (0);
                    273: }
                    274:
                    275: int
                    276: hdclose(struct open_file *f)
                    277: {
                    278:        struct hd_softc *rs = f->f_devdata;
                    279:
                    280:        /*
                    281:         * Mark the disk `not alive' so that the disklabel
                    282:         * will be re-loaded at next open.
                    283:         */
                    284:        bzero(rs, sizeof(struct hd_softc));
                    285:        f->f_devdata = NULL;
                    286:        return (0);
                    287: }
                    288:
                    289: int
                    290: hdstrategy(void *devdata, int func, daddr_t dblk, size_t size, void *v_buf,
                    291:     size_t *rsize)
                    292: {
                    293:        char *buf = v_buf;
                    294:        struct hd_softc *rs = devdata;
                    295:        int ctlr = rs->sc_ctlr;
                    296:        int unit = rs->sc_unit;
                    297:        daddr_t blk;
                    298:        char stat;
                    299:
                    300:        if (size == 0)
                    301:                return(0);
                    302:
                    303:        /*
                    304:         * Don't do partition translation on the `raw partition'.
                    305:         */
                    306:        blk = (dblk + ((rs->sc_part == RAW_PART) ? 0 :
                    307:            rs->sc_pinfo.offset[rs->sc_part]));
                    308:
                    309:        rs->sc_retry = 0;
                    310:        hd_ioc.c_unit = C_SUNIT(0);
                    311:        hd_ioc.c_volume = C_SVOL(0);
                    312:        hd_ioc.c_saddr = C_SADDR;
                    313:        hd_ioc.c_hiaddr = 0;
                    314:        hd_ioc.c_addr = HDBTOS(blk);
                    315:        hd_ioc.c_nop2 = C_NOP;
                    316:        hd_ioc.c_slen = C_SLEN;
                    317:        hd_ioc.c_len = size;
                    318:        hd_ioc.c_cmd = func == F_READ ? C_READ : C_WRITE;
                    319: retry:
                    320:        hpibsend(ctlr, unit, C_CMD, &hd_ioc.c_unit, sizeof(hd_ioc)-2);
                    321:        hpibswait(ctlr, unit);
                    322:        hpibgo(ctlr, unit, C_EXEC, buf, size, func);
                    323:        hpibswait(ctlr, unit);
                    324:        hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
                    325:        if (stat) {
                    326:                if (hderror(ctlr, unit, rs->sc_part) == 0)
                    327:                        return(EIO);
                    328:                if (++rs->sc_retry > HDRETRY)
                    329:                        return(EIO);
                    330:                goto retry;
                    331:        }
                    332:        *rsize = size;
                    333:
                    334:        return(0);
                    335: }
                    336:
                    337: int
                    338: hderror(int ctlr, int unit, int part)
                    339: {
                    340:        char stat;
                    341:
                    342:        hd_rsc.c_unit = C_SUNIT(0);
                    343:        hd_rsc.c_sram = C_SRAM;
                    344:        hd_rsc.c_ram = C_RAM;
                    345:        hd_rsc.c_cmd = C_STATUS;
                    346:        hpibsend(ctlr, unit, C_CMD, &hd_rsc, sizeof(hd_rsc));
                    347:        hpibrecv(ctlr, unit, C_EXEC, &hd_stat, sizeof(hd_stat));
                    348:        hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
                    349:        if (stat) {
                    350:                printf("hd(%d,%d,0,%d): request status fail %d\n",
                    351:                       ctlr, unit, part, stat);
                    352:                return(0);
                    353:        }
                    354:        printf("hd(%d,%d,0,%d) err: vu 0x%x",
                    355:               ctlr, unit, part, hd_stat.c_vu);
                    356:        if ((hd_stat.c_aef & AEF_UD) || (hd_stat.c_ief & (IEF_MD|IEF_RD)))
                    357:                printf(", block %ld", hd_stat.c_blk);
                    358:        printf(", R0x%x F0x%x A0x%x I0x%x\n",
                    359:               hd_stat.c_ref, hd_stat.c_fef, hd_stat.c_aef, hd_stat.c_ief);
                    360:        return(1);
                    361: }

CVSweb