[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     ! 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