[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

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