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

Annotation of sys/arch/hp300/stand/common/ct.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: ct.c,v 1.5 2006/08/17 06:31:10 miod Exp $     */
        !             2: /*     $NetBSD: ct.c,v 1.9 1996/10/14 07:29:57 thorpej Exp $   */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1982, 1990, 1993
        !             6:  *     The Regents of the University of California.  All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  * 3. Neither the name of the University nor the names of its contributors
        !            17:  *    may be used to endorse or promote products derived from this software
        !            18:  *    without specific prior written permission.
        !            19:  *
        !            20:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            30:  * SUCH DAMAGE.
        !            31:  *
        !            32:  *     @(#)ct.c        8.1 (Berkeley) 7/15/93
        !            33:  */
        !            34:
        !            35: /*
        !            36:  * CS80 tape driver
        !            37:  */
        !            38: #include <sys/param.h>
        !            39:
        !            40: #include <hp300/dev/ctreg.h>
        !            41:
        !            42: #include <lib/libsa/stand.h>
        !            43:
        !            44: #include "samachdep.h"
        !            45: #include "hpibvar.h"
        !            46:
        !            47: struct ct_iocmd ct_ioc;
        !            48: struct ct_rscmd ct_rsc;
        !            49: struct ct_stat ct_stat;
        !            50: struct ct_ssmcmd ct_ssmc;
        !            51:
        !            52: struct ct_softc {
        !            53:        int     sc_ctlr;
        !            54:        int     sc_unit;
        !            55:        char    sc_retry;
        !            56:        char    sc_alive;
        !            57:        short   sc_punit;
        !            58:        int     sc_blkno;
        !            59: } ct_softc[NHPIB][NCT];
        !            60:
        !            61: #define        CTRETRY         5
        !            62: #define        MTFSF           10
        !            63: #define        MTREW           11
        !            64:
        !            65: int    ctclose(struct open_file *);
        !            66: int    cterror(int, int);
        !            67: int    ctident(int, int);
        !            68: int    ctinit(int, int);
        !            69: int    ctopen(struct open_file *, int, int, int);
        !            70: int    ctpunit(int, int, int *);
        !            71: int    ctstrategy(void *, int, daddr_t, size_t, void *, size_t *);
        !            72:
        !            73: char ctio_buf[MAXBSIZE];
        !            74:
        !            75: struct ctinfo {
        !            76:        short   hwid;
        !            77:        short   punit;
        !            78: } ctinfo[] = {
        !            79:        { CT7946ID,     1 },
        !            80:        { CT7912PID,    1 },
        !            81:        { CT7914PID,    1 },
        !            82:        { CT9144ID,     0 },
        !            83:        { CT9145ID,     0 }
        !            84: };
        !            85: int    nctinfo = sizeof(ctinfo) / sizeof(ctinfo[0]);
        !            86:
        !            87: int
        !            88: ctinit(int ctlr, int unit)
        !            89: {
        !            90:        struct ct_softc *rs = &ct_softc[ctlr][unit];
        !            91:        u_char stat;
        !            92:
        !            93:        if (hpibrecv(ctlr, unit, C_QSTAT, &stat, 1) != 1 || stat)
        !            94:                return (0);
        !            95:        if (ctident(ctlr, unit) < 0)
        !            96:                return (0);
        !            97:        bzero(&ct_ssmc, sizeof(ct_ssmc));
        !            98:        ct_ssmc.unit = C_SUNIT(rs->sc_punit);
        !            99:        ct_ssmc.cmd = C_SSM;
        !           100:        ct_ssmc.fefm = FEF_MASK;
        !           101:        ct_ssmc.refm = REF_MASK;
        !           102:        ct_ssmc.aefm = AEF_MASK;
        !           103:        ct_ssmc.iefm = IEF_MASK;
        !           104:        hpibsend(ctlr, unit, C_CMD, &ct_ssmc, sizeof(ct_ssmc));
        !           105:        hpibswait(ctlr, unit);
        !           106:        hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
        !           107:        rs->sc_alive = 1;
        !           108:        return (1);
        !           109: }
        !           110:
        !           111: int
        !           112: ctident(int ctlr, int unit)
        !           113: {
        !           114:        struct cs80_describe desc;
        !           115:        u_char stat, cmd[3];
        !           116:        char name[7];
        !           117:        int id, i;
        !           118:
        !           119:        id = hpibid(ctlr, unit);
        !           120:        if ((id & 0x200) == 0)
        !           121:                return(-1);
        !           122:        for (i = 0; i < nctinfo; i++)
        !           123:                if (id == ctinfo[i].hwid)
        !           124:                        break;
        !           125:        if (i == nctinfo)
        !           126:                return(-1);
        !           127:        ct_softc[ctlr][unit].sc_punit = ctinfo[i].punit;
        !           128:        id = i;
        !           129:
        !           130:        /*
        !           131:         * Collect device description.
        !           132:         * Right now we only need this to differentiate 7945 from 7946.
        !           133:         * Note that we always issue the describe command to unit 0.
        !           134:         */
        !           135:        cmd[0] = C_SUNIT(0);
        !           136:        cmd[1] = C_SVOL(0);
        !           137:        cmd[2] = C_DESC;
        !           138:        hpibsend(ctlr, unit, C_CMD, cmd, sizeof(cmd));
        !           139:        hpibrecv(ctlr, unit, C_EXEC, &desc, sizeof(desc));
        !           140:        hpibrecv(ctlr, unit, C_QSTAT, &stat, sizeof(stat));
        !           141:        bzero(name, sizeof(name));
        !           142:        if (!stat) {
        !           143:                int n = desc.d_name;
        !           144:                for (i = 5; i >= 0; i--) {
        !           145:                        name[i] = (n & 0xf) + '0';
        !           146:                        n >>= 4;
        !           147:                }
        !           148:        }
        !           149:        switch (ctinfo[id].hwid) {
        !           150:        case CT7946ID:
        !           151:                if (bcmp(name, "079450", 6) == 0)
        !           152:                        id = -1;                /* not really a 7946 */
        !           153:                break;
        !           154:        default:
        !           155:                break;
        !           156:        }
        !           157:        return(id);
        !           158: }
        !           159:
        !           160: int
        !           161: ctpunit(int ctlr, int slave, int *punit)
        !           162: {
        !           163:        struct ct_softc *rs;
        !           164:
        !           165:        if (ctlr >= NHPIB || hpibalive(ctlr) == 0)
        !           166:                return(EADAPT);
        !           167:        if (slave >= NCT)
        !           168:                return(ECTLR);
        !           169:        rs = &ct_softc[ctlr][slave];
        !           170:
        !           171:        if (rs->sc_alive == 0)
        !           172:                return(ENXIO);
        !           173:
        !           174:        *punit = rs->sc_punit;
        !           175:        return (0);
        !           176: }
        !           177:
        !           178: int
        !           179: ctopen(struct open_file *f, int ctlr, int unit, int part)
        !           180: {
        !           181:        struct ct_softc *rs;
        !           182:        int skip;
        !           183:        size_t resid;
        !           184:
        !           185:        if (ctlr >= NHPIB || hpibalive(ctlr) == 0)
        !           186:                return(EADAPT);
        !           187:        if (unit >= NCT)
        !           188:                return(ECTLR);
        !           189:        rs = &ct_softc[ctlr][unit];
        !           190:        rs->sc_blkno = 0;
        !           191:        rs->sc_unit = unit;
        !           192:        rs->sc_ctlr = ctlr;
        !           193:        if (rs->sc_alive == 0)
        !           194:                if (ctinit(ctlr, unit) == 0)
        !           195:                        return(ENXIO);
        !           196:        f->f_devdata = (void *)rs;
        !           197:        ctstrategy(f->f_devdata, MTREW, 0, 0, ctio_buf, &resid);
        !           198:        skip = part;
        !           199:        while (skip--)
        !           200:                ctstrategy(f->f_devdata, MTFSF, 0, 0, ctio_buf, &resid);
        !           201:        return(0);
        !           202: }
        !           203:
        !           204: int
        !           205: ctclose(struct open_file *f)
        !           206: {
        !           207:        size_t resid;
        !           208:
        !           209:        ctstrategy(f->f_devdata, MTREW, 0, 0, ctio_buf, &resid);
        !           210:        return (0);
        !           211: }
        !           212:
        !           213: int
        !           214: ctstrategy(void *devdata, int func, daddr_t dblk, size_t size, void *v_buf,
        !           215:     size_t *rsize)
        !           216: {
        !           217:        struct ct_softc *rs = devdata;
        !           218:        char *buf = v_buf;
        !           219:        int ctlr = rs->sc_ctlr;
        !           220:        int unit = rs->sc_unit;
        !           221:        char stat;
        !           222:
        !           223:        if (size == 0 && (func == F_READ || func == F_WRITE))
        !           224:                return(0);
        !           225:
        !           226:        rs->sc_retry = 0;
        !           227:        bzero(&ct_ioc, sizeof(ct_ioc));
        !           228:        ct_ioc.unit = C_SUNIT(rs->sc_punit);
        !           229:        ct_ioc.saddr = C_SADDR;
        !           230:        ct_ioc.nop2 = C_NOP;
        !           231:        ct_ioc.slen = C_SLEN;
        !           232:        ct_ioc.nop3 = C_NOP;
        !           233: top:
        !           234:        if (func == F_READ) {
        !           235:                ct_ioc.cmd = C_READ;
        !           236:                ct_ioc.addr = rs->sc_blkno;
        !           237:                ct_ioc.len = size;
        !           238:        }
        !           239:        else if (func == F_WRITE) {
        !           240:                ct_ioc.cmd = C_WRITE;
        !           241:                ct_ioc.addr = rs->sc_blkno;
        !           242:                ct_ioc.len = size;
        !           243:        }
        !           244:        else if (func == MTFSF) {
        !           245:                ct_ioc.cmd = C_READ;
        !           246:                ct_ioc.addr = rs->sc_blkno;
        !           247:                ct_ioc.len = size = MAXBSIZE;
        !           248:        }
        !           249:        else {
        !           250:                ct_ioc.cmd = C_READ;
        !           251:                ct_ioc.addr = 0;
        !           252:                ct_ioc.len = 0;
        !           253:                rs->sc_blkno = 0;
        !           254:                size = 0;
        !           255:        }
        !           256: retry:
        !           257:        hpibsend(ctlr, unit, C_CMD, &ct_ioc, sizeof(ct_ioc));
        !           258:        if (func != MTREW) {
        !           259:                hpibswait(ctlr, unit);
        !           260:                hpibgo(ctlr, unit, C_EXEC, buf, size,
        !           261:                        func != F_WRITE ? F_READ : F_WRITE);
        !           262:                hpibswait(ctlr, unit);
        !           263:        } else {
        !           264:                while (hpibswait(ctlr, unit) < 0)
        !           265:                        ;
        !           266:        }
        !           267:        hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
        !           268:        if (stat) {
        !           269:                stat = cterror(ctlr, unit);
        !           270:                if (stat == 0)
        !           271:                        return (-1);
        !           272:                if (stat == 2)
        !           273:                        return (0);
        !           274:                if (++rs->sc_retry > CTRETRY)
        !           275:                        return (-1);
        !           276:                goto retry;
        !           277:        }
        !           278:        rs->sc_blkno += CTBTOK(size);
        !           279:        if (func == MTFSF)
        !           280:                goto top;
        !           281:        *rsize = size;
        !           282:
        !           283:        return(0);
        !           284: }
        !           285:
        !           286: int
        !           287: cterror(int ctlr, int unit)
        !           288: {
        !           289:        struct ct_softc *rs = &ct_softc[ctlr][unit];
        !           290:        char stat;
        !           291:
        !           292:        bzero(&ct_rsc, sizeof(ct_rsc));
        !           293:        bzero(&ct_stat, sizeof(ct_stat));
        !           294:        ct_rsc.unit = C_SUNIT(rs->sc_punit);
        !           295:        ct_rsc.cmd = C_STATUS;
        !           296:        hpibsend(ctlr, unit, C_CMD, &ct_rsc, sizeof(ct_rsc));
        !           297:        hpibrecv(ctlr, unit, C_EXEC, &ct_stat, sizeof(ct_stat));
        !           298:        hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
        !           299:        if (stat) {
        !           300:                printf("ct%d: request status fail %d\n", unit, stat);
        !           301:                return(0);
        !           302:        }
        !           303:        if (ct_stat.c_aef & AEF_EOF) {
        !           304:                /* 9145 drives don't increment block number at EOF */
        !           305:                if ((ct_stat.c_blk - rs->sc_blkno) == 0)
        !           306:                        rs->sc_blkno++;
        !           307:                else
        !           308:                        rs->sc_blkno = ct_stat.c_blk;
        !           309:                return (2);
        !           310:        }
        !           311:        printf("ct%d err: vu 0x%x, pend 0x%x, bn%ld", unit,
        !           312:                ct_stat.c_vu, ct_stat.c_pend, ct_stat.c_blk);
        !           313:        printf(", R 0x%x F 0x%x A 0x%x I 0x%x\n", ct_stat.c_ref,
        !           314:                ct_stat.c_fef, ct_stat.c_aef, ct_stat.c_ief);
        !           315:        return (1);
        !           316: }

CVSweb