[BACK]Return to ts.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / qbus

Annotation of src/sys/dev/qbus/ts.c, Revision 1.20.6.2

1.20.6.2! matt        1: /*     $NetBSD: ts.c,v 1.20.6.1 2007/11/06 23:30:01 matt Exp $ */
1.1       ragge       2:
                      3: /*-
                      4:  * Copyright (c) 1991 The Regents of the University of California.
                      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.
1.11      agc        15:  * 3. Neither the name of the University nor the names of its contributors
1.1       ragge      16:  *    may be used to endorse or promote products derived from this software
                     17:  *    without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  *
                     31:  *     @(#)tmscp.c     7.16 (Berkeley) 5/9/91
                     32:  */
                     33:
                     34: /*
                     35:  * sccsid = "@(#)tmscp.c       1.24    (ULTRIX)        1/21/86";
                     36:  */
                     37:
                     38: /************************************************************************
                     39:  *                                                                     *
                     40:  *       Licensed from Digital Equipment Corporation                   *
                     41:  *                      Copyright (c)                                  *
                     42:  *              Digital Equipment Corporation                          *
                     43:  *                  Maynard, Massachusetts                             *
                     44:  *                        1985, 1986                                   *
                     45:  *                   All rights reserved.                              *
                     46:  *                                                                     *
                     47:  *       The Information in this software is subject to change         *
                     48:  *   without notice and should not be construed as a commitment                *
                     49:  *   by         Digital  Equipment  Corporation.   Digital   makes  no         *
                     50:  *   representations about the suitability of this software for                *
                     51:  *   any purpose.  It is supplied "As Is" without expressed  or                *
                     52:  *   implied  warranty.                                                        *
                     53:  *                                                                     *
                     54:  *       If the Regents of the University of California or its         *
                     55:  *   licensees modify the software in a manner creating                        *
                     56:  *   derivative copyright rights, appropriate copyright                        *
                     57:  *   legends may be placed on  the derivative work in addition         *
                     58:  *   to that set forth above.                                          *
                     59:  *                                                                     *
                     60:  ************************************************************************/
                     61:
                     62: /*
                     63:  * TSV05/TS05 device driver, written by Bertram Barth.
                     64:  *
                     65:  * should be TS11 compatible (untested)
                     66:  */
1.3       lukem      67:
                     68: #include <sys/cdefs.h>
1.20.6.2! matt       69: __KERNEL_RCSID(0, "$NetBSD: ts.c,v 1.20.6.1 2007/11/06 23:30:01 matt Exp $");
1.1       ragge      70:
1.2       ragge      71: #undef TSDEBUG
1.1       ragge      72:
                     73: /*
1.2       ragge      74:  * TODO:
1.1       ragge      75:  *
1.2       ragge      76:  * Keep track of tape position so that lseek et al works.
                     77:  * Use tprintf to inform the user, not the system console.
1.1       ragge      78:  */
                     79:
                     80:
                     81: #include <sys/param.h>
                     82: #include <sys/systm.h>
                     83: #include <sys/kernel.h>
                     84: #include <sys/buf.h>
1.12      yamt       85: #include <sys/bufq.h>
1.1       ragge      86: #include <sys/conf.h>
                     87: #include <sys/errno.h>
                     88: #include <sys/file.h>
                     89: #include <sys/syslog.h>
                     90: #include <sys/ioctl.h>
                     91: #include <sys/mtio.h>
                     92: #include <sys/uio.h>
                     93: #include <sys/proc.h>
                     94:
1.20.6.1  matt       95: #include <sys/bus.h>
1.1       ragge      96:
                     97: #include <dev/qbus/ubareg.h>
                     98: #include <dev/qbus/ubavar.h>
                     99:
1.2       ragge     100: #include <dev/qbus/tsreg.h>
1.1       ragge     101:
1.2       ragge     102: #include "ioconf.h"
1.1       ragge     103:
                    104: struct ts {
1.2       ragge     105:        struct  cmd cmd;        /* command packet */
                    106:        struct  chr chr;        /* characteristics packet */
                    107:        struct  status status;  /* status packet */
                    108: };
1.1       ragge     109:
                    110: /*
                    111:  * Software status, per controller.
                    112:  * also status per tape-unit, since only one unit per controller
                    113:  * (thus we have no struct ts_info)
                    114:  */
                    115: struct ts_softc {
                    116:        struct  device sc_dev;          /* Autoconf ... */
                    117:        struct  uba_unit sc_unit;       /* Struct common for UBA to talk */
1.2       ragge     118:        struct  evcnt sc_intrcnt;       /* Interrupt counting */
                    119:        struct  ubinfo sc_ui;           /* mapping info for struct ts */
                    120:        struct  uba_unit sc_uu;         /* Struct for UBA to communicate */
                    121:        bus_space_tag_t sc_iot;
                    122:        bus_addr_t sc_ioh;
                    123:        bus_dma_tag_t sc_dmat;
                    124:        bus_dmamap_t sc_dmam;
                    125:        volatile struct ts *sc_vts;     /* Memory address of ts struct */
                    126:        struct  ts *sc_bts;             /* Unibus address of ts struct */
                    127:        int     sc_type;                /* TS11 or TS05? */
                    128:        short   sc_waddr;               /* Value to write to TSDB */
1.14      yamt      129:        struct  bufq_state *sc_bufq;    /* pending I/O requests */
1.2       ragge     130:
1.1       ragge     131:        short   sc_mapped;              /* Unibus map allocated ? */
                    132:        short   sc_state;               /* see below: ST_xxx */
                    133:        short   sc_rtc;                 /* retry count for lcmd */
                    134:        short   sc_openf;               /* lock against multiple opens */
                    135:        short   sc_liowf;               /* last operation was write */
1.2       ragge     136:        struct  buf ts_cbuf;            /* internal cmd buffer (for ioctls) */
1.1       ragge     137: };
                    138:
1.2       ragge     139: #define        XNAME   sc->sc_dev.dv_xname
                    140:
                    141: #define        TS_WCSR(csr, val) \
                    142:        bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val)
                    143: #define TS_RCSR(csr) \
                    144:        bus_space_read_2(sc->sc_iot, sc->sc_ioh, csr)
                    145:
                    146: #define LOWORD(x)      ((int)(x) & 0xffff)
                    147: #define HIWORD(x)      (((int)(x) >> 16) & 0x3f)
                    148:
                    149: #define        TYPE_TS11       0
                    150: #define        TYPE_TS05       1
                    151: #define        TYPE_TU80       2
                    152:
                    153: #define        TS_INVALID      0
                    154: #define        TS_INIT         1
                    155: #define        TS_RUNNING      2
                    156: #define        TS_FASTREPOS    3
                    157:
                    158: static void tsintr(void *);
                    159: static void tsinit(struct ts_softc *);
                    160: static void tscommand(struct ts_softc *, dev_t, int, int);
                    161: static int tsstart(struct ts_softc *, int);
                    162: static void tswchar(struct ts_softc *);
                    163: static int tsreset(struct ts_softc *);
                    164: static int tsmatch(struct device *, struct cfdata *, void *);
                    165: static void tsattach(struct device *, struct device *, void *);
                    166: static int tsready(struct uba_unit *);
                    167:
1.8       thorpej   168: CFATTACH_DECL(ts, sizeof(struct ts_softc),
1.9       thorpej   169:     tsmatch, tsattach, NULL, NULL);
1.5       gehenna   170:
                    171: dev_type_open(tsopen);
                    172: dev_type_close(tsclose);
                    173: dev_type_read(tsread);
                    174: dev_type_write(tswrite);
                    175: dev_type_ioctl(tsioctl);
                    176: dev_type_strategy(tsstrategy);
                    177: dev_type_dump(tsdump);
                    178:
                    179: const struct bdevsw ts_bdevsw = {
                    180:        tsopen, tsclose, tsstrategy, tsioctl, tsdump, nosize, D_TAPE
                    181: };
                    182:
                    183: const struct cdevsw ts_cdevsw = {
                    184:        tsopen, tsclose, tsread, tswrite, tsioctl,
1.10      jdolecek  185:        nostop, notty, nopoll, nommap, nokqfilter, D_TAPE
1.1       ragge     186: };
                    187:
1.13      simonb    188: /* Bits in minor device */
1.1       ragge     189: #define TS_UNIT(dev)   (minor(dev)&03)
                    190: #define TS_HIDENSITY   010
                    191:
                    192: #define TS_PRI LOG_INFO
                    193:
                    194:
                    195: /*
1.2       ragge     196:  * Probe for device. If found, try to raise an interrupt.
1.1       ragge     197:  */
1.2       ragge     198: int
                    199: tsmatch(struct device *parent, struct cfdata *match, void *aux)
                    200: {
                    201:        struct ts_softc ssc;
                    202:        struct ts_softc *sc = &ssc;
                    203:        struct uba_attach_args *ua = aux;
                    204:        int i;
1.1       ragge     205:
1.2       ragge     206:        sc->sc_iot = ua->ua_iot;
                    207:        sc->sc_ioh = ua->ua_ioh;
                    208:        sc->sc_mapped = 0;
                    209:        sc->sc_dev.dv_parent = parent;
                    210:        strcpy(XNAME, "ts");
1.1       ragge     211:
1.2       ragge     212:        /* Try to reset the device */
                    213:        for (i = 0; i < 3; i++)
                    214:                if (tsreset(sc) == 1)
                    215:                        break;
                    216:
                    217:        if (i == 3)
                    218:                return 0;
1.1       ragge     219:
1.2       ragge     220:        tsinit(sc);
                    221:        tswchar(sc);            /* write charact. to enable interrupts */
                    222:                                /* completion of this will raise the intr. */
1.1       ragge     223:
1.2       ragge     224:        DELAY(1000000);         /* Wait for interrupt */
                    225:        ubmemfree((void *)parent, &sc->sc_ui);
                    226:        return 1;
1.1       ragge     227: }
                    228:
                    229: /*
                    230:  */
1.2       ragge     231: void
                    232: tsattach(struct device *parent, struct device *self, void *aux)
1.1       ragge     233: {
1.17      thorpej   234:        struct uba_softc *uh = device_private(parent);
                    235:        struct ts_softc *sc = device_private(self);
1.2       ragge     236:        struct uba_attach_args *ua = aux;
                    237:        int error;
                    238:        char *t;
                    239:
                    240:        sc->sc_iot = ua->ua_iot;
                    241:        sc->sc_ioh = ua->ua_ioh;
                    242:        sc->sc_dmat = ua->ua_dmat;
1.13      simonb    243:
1.2       ragge     244:        sc->sc_uu.uu_softc = sc;
                    245:        sc->sc_uu.uu_ready = tsready;
1.1       ragge     246:
1.2       ragge     247:        tsinit(sc);     /* reset and map */
1.1       ragge     248:
1.2       ragge     249:        if ((error = bus_dmamap_create(sc->sc_dmat, (64*1024), 16, (64*1024),
                    250:            0, BUS_DMA_NOWAIT, &sc->sc_dmam)))
                    251:                return printf(": failed create DMA map %d\n", error);
1.1       ragge     252:
1.14      yamt      253:        bufq_alloc(&sc->sc_bufq, "fcfs", 0);
1.1       ragge     254:
                    255:        /*
1.2       ragge     256:         * write the characteristics (again)
1.1       ragge     257:         */
1.2       ragge     258:        sc->sc_state = TS_INIT;         /* tsintr() checks this ... */
                    259:        tswchar(sc);
                    260:        if (tsleep(sc, PRIBIO, "tsattach", 100))
                    261:                return printf(": failed SET CHARACTERISTICS\n");
                    262:
                    263:        sc->sc_state = TS_RUNNING;
                    264:        if (uh->uh_type == UBA_UBA) {
                    265:                if (sc->sc_vts->status.xst2 & TS_SF_TU80) {
                    266:                        sc->sc_type = TYPE_TU80;
                    267:                        t = "TU80";
                    268:                } else {
                    269:                        sc->sc_type = TYPE_TS11;
                    270:                        t = "TS11";
1.1       ragge     271:                }
1.2       ragge     272:        } else {
                    273:                sc->sc_type = TYPE_TS05;
                    274:                t = "TS05";
1.1       ragge     275:        }
                    276:
1.2       ragge     277:        printf("\n%s: %s\n", XNAME, t);
                    278:        printf("%s: rev %d, extended features %s, transport %s\n",
                    279:                XNAME, (sc->sc_vts->status.xst2 & TS_SF_MCRL) >> 2,
                    280:                (sc->sc_vts->status.xst2 & TS_SF_EFES ? "enabled" : "disabled"),
                    281:                (TS_RCSR(TSSR) & TS_OFL ? "offline" : "online"));
                    282:
                    283:        uba_intr_establish(ua->ua_icookie, ua->ua_cvec, tsintr,
                    284:            sc, &sc->sc_intrcnt);
                    285:        evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
                    286:            sc->sc_dev.dv_xname, "intr");
                    287: }
                    288:
                    289: /*
                    290:  * Initialize a TS device. Set up UBA mapping registers,
                    291:  * initialize data structures, what else ???
                    292:  */
1.13      simonb    293: void
1.2       ragge     294: tsinit(struct ts_softc *sc)
                    295: {
                    296:        if (sc->sc_mapped == 0) {
                    297:
                    298:                /*
                    299:                 * Map the communications area and command and message
                    300:                 * buffer into Unibus address space.
                    301:                 */
                    302:                sc->sc_ui.ui_size = sizeof(struct ts);
1.16      thorpej   303:                if ((ubmemalloc((void *)device_parent(&sc->sc_dev),
1.2       ragge     304:                    &sc->sc_ui, UBA_CANTWAIT)))
                    305:                        return;
                    306:                sc->sc_vts = (void *)sc->sc_ui.ui_vaddr;
                    307:                sc->sc_bts = (void *)sc->sc_ui.ui_baddr;
                    308:                sc->sc_waddr = sc->sc_ui.ui_baddr |
                    309:                    ((sc->sc_ui.ui_baddr >> 16) & 3);
                    310:                sc->sc_mapped = 1;
                    311:        }
                    312:        tsreset(sc);
1.1       ragge     313: }
                    314:
1.13      simonb    315: /*
1.1       ragge     316:  * Execute a (ioctl) command on the tape drive a specified number of times.
                    317:  * This routine sets up a buffer and calls the strategy routine which
                    318:  * issues the command to the controller.
                    319:  */
                    320: void
1.2       ragge     321: tscommand(struct ts_softc *sc, dev_t dev, int cmd, int count)
1.1       ragge     322: {
1.2       ragge     323:        struct buf *bp;
1.1       ragge     324:
1.2       ragge     325: #ifdef TSDEBUG
                    326:        printf("tscommand (%x, %d)\n", cmd, count);
                    327: #endif
                    328:
                    329:        bp = &sc->ts_cbuf;
1.1       ragge     330:
1.20.6.2! matt      331:        mutex_enter(&bufcache_lock);
        !           332:        while (bp->b_cflags & BC_BUSY) {
1.1       ragge     333:                /*
1.20.6.2! matt      334:                 * This special check is because BC_BUSY never
1.1       ragge     335:                 * gets cleared in the non-waiting rewind case. ???
                    336:                 */
1.20.6.2! matt      337:                if (bp->b_bcount == 0 && (bp->b_oflags & BO_DONE))
1.1       ragge     338:                        break;
1.20.6.2! matt      339:                (void )bbusy(bp, false, 0);
1.1       ragge     340:                /* check MOT-flag !!! */
                    341:        }
1.20.6.2! matt      342:        bp->b_flags = B_READ;
        !           343:        mutex_exit(&bufcache_lock);
1.1       ragge     344:
                    345:        /*
                    346:         * Load the buffer.  The b_count field gets used to hold the command
                    347:         * count.  the b_resid field gets used to hold the command mneumonic.
                    348:         * These 2 fields are "known" to be "safe" to use for this purpose.
                    349:         * (Most other drivers also use these fields in this way.)
                    350:         */
                    351:        bp->b_dev = dev;
                    352:        bp->b_bcount = count;
                    353:        bp->b_resid = cmd;
                    354:        bp->b_blkno = 0;
1.20.6.2! matt      355:        bp->b_oflags = 0;
        !           356:        bp->b_objlock = &buffer_lock;
1.2       ragge     357:        tsstrategy(bp);
1.1       ragge     358:        /*
                    359:         * In case of rewind from close, don't wait.
                    360:         * This is the only case where count can be 0.
                    361:         */
1.2       ragge     362:        if (count == 0)
1.1       ragge     363:                return;
1.2       ragge     364:        biowait(bp);
1.20.6.2! matt      365:        mutex_enter(&bufcache_lock);
        !           366:        cv_broadcast(&bp->b_busy);
        !           367:        bp->b_cflags = 0;
        !           368:        mutex_exit(&bufcache_lock);
1.1       ragge     369: }
                    370:
                    371: /*
                    372:  * Start an I/O operation on TS05 controller
                    373:  */
                    374: int
1.2       ragge     375: tsstart(struct ts_softc *sc, int isloaded)
1.1       ragge     376: {
1.2       ragge     377:        struct buf *bp;
1.1       ragge     378:        int cmd;
                    379:
1.14      yamt      380:        bp = BUFQ_PEEK(sc->sc_bufq);
                    381:        if (bp == NULL) {
1.2       ragge     382:                return 0;
1.14      yamt      383:        }
1.2       ragge     384: #ifdef TSDEBUG
                    385:        printf("buf: %p bcount %ld blkno %d\n", bp, bp->b_bcount, bp->b_blkno);
                    386: #endif
1.1       ragge     387:        /*
                    388:         * Check if command is an ioctl or not (ie. read or write).
                    389:         * If it's an ioctl then just set the flags for later use;
                    390:         * For other commands attempt to setup a buffer pointer.
                    391:         */
1.2       ragge     392:        if (bp == &sc->ts_cbuf) {
1.1       ragge     393:                switch ((int)bp->b_resid) {
                    394:                case MTWEOF:
                    395:                        cmd = TS_CMD_WTM;
                    396:                        break;
                    397:                case MTFSF:
                    398:                        cmd = TS_CMD_STMF;
1.2       ragge     399:                        sc->sc_vts->cmd.cw1 = bp->b_bcount;
1.1       ragge     400:                        break;
                    401:                case MTBSF:
1.13      simonb    402:                        cmd = TS_CMD_STMR;
1.2       ragge     403:                        sc->sc_vts->cmd.cw1 = bp->b_bcount;
1.1       ragge     404:                        break;
                    405:                case MTFSR:
                    406:                        cmd = TS_CMD_SRF;
1.2       ragge     407:                        sc->sc_vts->cmd.cw1 = bp->b_bcount;
1.1       ragge     408:                        break;
                    409:                case MTBSR:
                    410:                        cmd = TS_CMD_SRR;
1.2       ragge     411:                        sc->sc_vts->cmd.cw1 = bp->b_bcount;
1.1       ragge     412:                        break;
                    413:                case MTREW:
                    414:                        cmd = TS_CMD_RWND;
                    415:                        break;
                    416:                case MTOFFL:
                    417:                        cmd = TS_CMD_RWUL;
                    418:                        break;
                    419:                case MTNOP:
                    420:                        cmd = TS_CMD_STAT;
                    421:                        break;
                    422:                default:
                    423:                        printf ("%s: bad ioctl %d\n", sc->sc_dev.dv_xname,
                    424:                                (int)bp->b_resid);
                    425:                        /* Need a no-op. get status */
                    426:                        cmd = TS_CMD_STAT;
                    427:                } /* end switch (bp->b_resid) */
1.2       ragge     428:        } else {
                    429:                if (isloaded == 0) {
                    430:                        /*
                    431:                         * now we try to map the buffer into uba map space (???)
                    432:                         */
                    433:                        if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmam,
                    434:                            bp->b_data,
                    435:                            bp->b_bcount, bp->b_proc, BUS_DMA_NOWAIT)) {
                    436:                                uba_enqueue(&sc->sc_uu);
                    437:                                return 0;
                    438:                        }
                    439:                        sc->sc_rtc = 0;
                    440:                }
                    441:                sc->sc_vts->cmd.cw1 = LOWORD(sc->sc_dmam->dm_segs[0].ds_addr);
                    442:                sc->sc_vts->cmd.cw2 = HIWORD(sc->sc_dmam->dm_segs[0].ds_addr);
                    443:                sc->sc_vts->cmd.cw3 = bp->b_bcount;
                    444:                bp->b_error = 0; /* Used for error count */
                    445: #ifdef TSDEBUG
                    446:                printf("tsstart-1: err %d\n", bp->b_error);
                    447: #endif
                    448:                if (bp->b_flags & B_READ)
1.1       ragge     449:                        cmd = TS_CMD_RNF;
1.2       ragge     450:                else
1.1       ragge     451:                        cmd = TS_CMD_WD;
                    452:        }
                    453:
                    454:        /*
                    455:         * Now that the command-buffer is setup, give it to the controller
                    456:         */
1.2       ragge     457:        sc->sc_vts->cmd.cmdr = TS_CF_ACK | TS_CF_IE | cmd;
                    458: #ifdef TSDEBUG
                    459:        printf("tsstart: sending cmdr %x\n", sc->sc_vts->cmd.cmdr);
                    460: #endif
                    461:        TS_WCSR(TSDB, sc->sc_waddr);
1.1       ragge     462: }
                    463:
                    464: /*
1.2       ragge     465:  * Called when there are free uba resources.
1.1       ragge     466:  */
1.2       ragge     467: int
                    468: tsready(struct uba_unit *uu)
1.1       ragge     469: {
1.2       ragge     470:        struct ts_softc *sc = uu->uu_softc;
1.14      yamt      471:        struct buf *bp = BUFQ_PEEK(sc->sc_bufq);
1.1       ragge     472:
1.2       ragge     473:        if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmam, bp->b_data,
                    474:            bp->b_bcount, bp->b_proc, BUS_DMA_NOWAIT))
                    475:                return 0;
1.1       ragge     476:
1.2       ragge     477:        tsstart(sc, 1);
                    478:        return 1;
1.1       ragge     479: }
                    480:
                    481: /*
1.2       ragge     482:  * initialize the controller by sending WRITE CHARACTERISTICS command.
                    483:  * contents of command- and message-buffer are assembled during this
1.13      simonb    484:  * function.
1.1       ragge     485:  */
1.13      simonb    486: void
1.2       ragge     487: tswchar(struct ts_softc *sc)
1.1       ragge     488: {
                    489:        /*
1.2       ragge     490:         * assemble and send "WRITE CHARACTERISTICS" command
1.1       ragge     491:         */
                    492:
1.2       ragge     493:        sc->sc_vts->cmd.cmdr = TS_CF_ACK | TS_CF_IE | TS_CMD_WCHAR;
                    494:        sc->sc_vts->cmd.cw1  = LOWORD(&sc->sc_bts->chr);
                    495:        sc->sc_vts->cmd.cw2  = HIWORD(&sc->sc_bts->chr);
                    496:        sc->sc_vts->cmd.cw3  = 010;                /* size of charact.-data */
                    497:
                    498:        sc->sc_vts->chr.sadrl = LOWORD(&sc->sc_bts->status);
                    499:        sc->sc_vts->chr.sadrh = HIWORD(&sc->sc_bts->status);
                    500:        sc->sc_vts->chr.onesix = (sc->sc_type == TYPE_TS05 ? 020 : 016);
                    501:        sc->sc_vts->chr.chrw = TS_WC_ESS;
                    502:        sc->sc_vts->chr.xchrw = TS_WCX_HSP|TS_WCX_RBUF|TS_WCX_WBUF;
                    503:
                    504:        TS_WCSR(TSDB, sc->sc_waddr);
1.1       ragge     505: }
                    506:
                    507: /*
1.2       ragge     508:  * Reset the TS11. Return 1 if failed, 0 if succeeded.
1.1       ragge     509:  */
                    510: int
1.2       ragge     511: tsreset(struct ts_softc *sc)
1.1       ragge     512: {
1.2       ragge     513:        int timeout;
1.1       ragge     514:
                    515:        /*
1.2       ragge     516:         * reset ctlr by writing into TSSR, then write characteristics
1.1       ragge     517:         */
1.13      simonb    518:        timeout = 0;            /* timeout in 10 seconds */
1.2       ragge     519:        TS_WCSR(TSSR, 0);       /* start initialization */
                    520:        while ((TS_RCSR(TSSR) & TS_SSR) == 0) {
1.1       ragge     521:                DELAY(10000);
1.2       ragge     522:                if (timeout++ > 1000)
                    523:                        return 0;
                    524:        }
                    525:        return 1;
1.1       ragge     526: }
                    527:
1.2       ragge     528: static void
                    529: prtstat(struct ts_softc *sc, int sr)
1.1       ragge     530: {
1.2       ragge     531:        char buf[100];
1.1       ragge     532:
1.2       ragge     533:        bitmask_snprintf(sr, TS_TSSR_BITS, buf, sizeof(buf));
                    534:        printf("%s: TSSR=%s\n", XNAME, buf);
                    535:        bitmask_snprintf(sc->sc_vts->status.xst0,TS_XST0_BITS,buf,sizeof(buf));
                    536:        printf("%s: XST0=%s\n", XNAME, buf);
1.1       ragge     537: }
                    538:
                    539: /*
                    540:  * TSV05/TS05 interrupt routine
                    541:  */
1.2       ragge     542: static void
                    543: tsintr(void *arg)
1.1       ragge     544: {
1.2       ragge     545:        struct ts_softc *sc = arg;
                    546:        struct buf *bp;
1.1       ragge     547:
1.2       ragge     548:        unsigned short sr = TS_RCSR(TSSR);      /* save TSSR */
                    549:        unsigned short mh = sc->sc_vts->status.hdr;     /* and msg-header */
1.1       ragge     550:                /* clear the message header ??? */
                    551:
1.2       ragge     552:        short ccode = sc->sc_vts->cmd.cmdr & TS_CF_CCODE;
1.1       ragge     553:
1.2       ragge     554: #ifdef TSDEBUG
1.1       ragge     555:        {
1.2       ragge     556:                char buf[100];
                    557:                bitmask_snprintf(sr, TS_TSSR_BITS, buf, sizeof(buf));
                    558:                printf("tsintr: sr %x mh %x\n", sr, mh);
                    559:                printf("srbits: %s\n", buf);
1.1       ragge     560:        }
                    561: #endif
                    562:        /*
                    563:         * There are two different things which can (and should) be checked:
                    564:         * the actual (internal) state and the device's result (tssr/msg.hdr)
1.13      simonb    565:         *
1.1       ragge     566:         * For each state there's only one "normal" interrupt. Anything else
                    567:         * has to be checked more intensively. Thus in a first run according
                    568:         * to the internal state the expected interrupt is checked/handled.
                    569:         *
                    570:         * In a second run the remaining (not yet handled) interrupts are
                    571:         * checked according to the drive's result.
                    572:         */
                    573:        switch (sc->sc_state) {
                    574:
1.2       ragge     575:        case TS_INVALID:
1.1       ragge     576:                /*
                    577:                 * Ignore unsolicited interrupts.
                    578:                 */
1.13      simonb    579:                log(LOG_WARNING, "%s: stray intr [%x,%x]\n",
1.1       ragge     580:                        sc->sc_dev.dv_xname, sr, mh);
                    581:                return;
                    582:
1.2       ragge     583:        case TS_INIT:
1.1       ragge     584:                /*
1.2       ragge     585:                 * Init phase ready.
1.1       ragge     586:                 */
1.2       ragge     587:                wakeup(sc);
1.1       ragge     588:                return;
                    589:
1.2       ragge     590:        case TS_RUNNING:
                    591:        case TS_FASTREPOS:
1.1       ragge     592:                /*
                    593:                 * Here we expect interrupts indicating the end of
                    594:                 * commands or indicating problems.
                    595:                 */
                    596:                /*
                    597:                 * Anything else is handled outside this switch ...
                    598:                 */
                    599:                break;
                    600:
                    601:        default:
1.13      simonb    602:                printf ("%s: unexpected interrupt during state %d [%x,%x]\n",
1.1       ragge     603:                        sc->sc_dev.dv_xname, sc->sc_state, sr, mh);
                    604:                return;
                    605:        }
                    606:
                    607:        /*
                    608:         * now we check the termination class.
                    609:         */
                    610:        switch (sr & TS_TC) {
                    611:
                    612:        case TS_TC_NORM:
                    613:                /*
                    614:                 * Normal termination -- The operation is completed
                    615:                 * witout incident.
                    616:                 */
1.2       ragge     617:                if (sc->sc_state == TS_FASTREPOS) {
                    618: #ifdef TSDEBUG
                    619:                        printf("Fast repos interrupt\n");
                    620: #endif
                    621:                        /* Fast repos succeeded, start normal data xfer */
                    622:                        sc->sc_state = TS_RUNNING;
                    623:                        tsstart(sc, 1);
                    624:                        return;
                    625:                }
1.1       ragge     626:                sc->sc_liowf = (ccode == TS_CC_WRITE);
1.2       ragge     627:                break;
1.1       ragge     628:
                    629:        case TS_TC_ATTN:
                    630:                /*
                    631:                 * Attention condition -- this code indicates that the
                    632:                 * drive has undergone a status change, such as going
                    633:                 * off-line or coming on-line.
                    634:                 * (Without EAI enabled, no Attention interrupts occur.
                    635:                 * drive status changes are signaled by the VCK flag.)
                    636:                 */
                    637:                return;
                    638:
                    639:        case TS_TC_TSA:
1.13      simonb    640:                /*
1.1       ragge     641:                 * Tape Status Alert -- A status condition is encountered
                    642:                 * that may have significance to the program. Bits of
                    643:                 * interest in the extended status registers include
                    644:                 * TMK, EOT and RLL.
                    645:                 */
1.2       ragge     646: #ifdef TSDEBUG
                    647:                {
                    648:                        char buf[100];
                    649:                        bitmask_snprintf(sc->sc_vts->status.xst0,
                    650:                            TS_XST0_BITS, buf, sizeof(buf));
                    651:                        printf("TSA: sr %x bits %s\n",
                    652:                            sc->sc_vts->status.xst0, buf);
                    653:                }
                    654: #endif
                    655:                if (sc->sc_vts->status.xst0 & TS_SF_TMK) {
                    656:                        /* Read to end-of-file. No error. */
                    657:                        break;
                    658:                }
                    659:                if (sc->sc_vts->status.xst0 & TS_SF_EOT) {
                    660:                        /* End of tape. Bad. */
                    661: #ifdef TSDEBUG
                    662:                        printf("TS_TC_TSA: EOT\n");
                    663: #endif
                    664:                        bp->b_error = EIO;
                    665:                        break;
                    666:                }
                    667:                if (sc->sc_vts->status.xst0 & TS_SF_RLS)
                    668:                        break;
                    669:                if (sc->sc_vts->status.xst0 & TS_SF_TMK) {
                    670: #ifdef TSDEBUG
                    671:                        printf(("Tape Mark detected"));
                    672: #endif
                    673:                }
                    674:                if (sc->sc_vts->status.xst0 & TS_SF_EOT) {
                    675: #ifdef TSDEBUG
                    676:                        printf(("End of Tape"));
                    677: #endif
1.1       ragge     678:                }
1.2       ragge     679: #ifndef TSDEBUG
                    680:                {
                    681:                        char buf[100];
                    682:                        bitmask_snprintf(sc->sc_vts->status.xst0,
                    683:                            TS_XST0_BITS, buf, sizeof(buf));
                    684:                        printf("TSA: sr %x bits %s\n",
                    685:                            sc->sc_vts->status.xst0, buf);
1.1       ragge     686:                }
1.2       ragge     687: #endif
1.1       ragge     688:                break;
                    689:
1.13      simonb    690:        case TS_TC_FR:
1.1       ragge     691:                /*
                    692:                 * Function Reject -- The specified function was not
                    693:                 * initiated. Bits of interest include OFL, VCK, BOT,
                    694:                 * WLE, ILC and ILA.
                    695:                 */
1.2       ragge     696:                if (sr & TS_OFL)
                    697:                        printf("tape is off-line.\n");
                    698: #ifdef TSDEBUG
                    699:                {
                    700:                        char buf[100];
                    701:                        bitmask_snprintf(sc->sc_vts->status.xst0,
                    702:                            TS_XST0_BITS, buf, sizeof(buf));
                    703:                        printf("FR: sr %x bits %s\n",
                    704:                            sc->sc_vts->status.xst0, buf);
                    705:                }
                    706: #endif
                    707:                if (sc->sc_vts->status.xst0 & TS_SF_VCK)
                    708:                        printf("Volume check\n");
                    709:                if (sc->sc_vts->status.xst0 & TS_SF_BOT)
                    710:                        printf("Start of tape.\n");
                    711:                if (sc->sc_vts->status.xst0 & TS_SF_WLE)
                    712:                        printf("Write Lock Error\n");
                    713:                if (sc->sc_vts->status.xst0 & TS_SF_EOT)
                    714:                        printf("End of tape.\n");
1.1       ragge     715:                break;
                    716:
                    717:        case TS_TC_TPD:
                    718:                /*
                    719:                 * Recoverable Error -- Tape position is a record beyond
                    720:                 * what its position was when the function was initiated.
                    721:                 * Suggested recovery procedure is to log the error and
                    722:                 * issue the appropriate retry command.
1.2       ragge     723:                 *
                    724:                 * Do a fast repositioning one record back.
1.1       ragge     725:                 */
1.2       ragge     726:                sc->sc_state = TS_FASTREPOS;
                    727: #ifdef TSDEBUG
                    728:                printf("TS_TC_TPD: errcnt %d\n", sc->sc_rtc);
                    729: #endif
                    730:                if (sc->sc_rtc++ == 8) {
                    731:                        printf("%s: failed 8 retries\n", XNAME);
                    732:                        prtstat(sc, sr);
                    733:                        bp->b_error = EIO;
                    734:                        break;
1.1       ragge     735:                }
1.2       ragge     736:                sc->sc_vts->cmd.cmdr = TS_CF_ACK | TS_CF_IE | TS_CMD_SRR;
                    737:                sc->sc_vts->cmd.cw1 = 1;
                    738:                TS_WCSR(TSDB, sc->sc_waddr);
                    739:                return;
                    740:
1.1       ragge     741:                break;
                    742:
                    743:        case TS_TC_TNM:
                    744:                /*
                    745:                 * Recoverable Error -- Tape position has not changed.
                    746:                 * Suggested recovery procedure is to log the error and
                    747:                 * reissue the original command.
                    748:                 */
1.2       ragge     749:                if (sc->sc_rtc++ == 8) {
                    750:                        printf("%s: failed 8 retries\n", XNAME);
                    751:                        prtstat(sc, sr);
                    752:                        bp->b_error = EIO;
                    753:                        break;
1.1       ragge     754:                }
1.2       ragge     755:                tsstart(sc, 1);
                    756:                return;
1.1       ragge     757:
                    758:        case TS_TC_TPL:
                    759:                /*
                    760:                 * Unrecoverable Error -- Tape position has been lost.
                    761:                 * No valid recovery procedures exist unless the tape
                    762:                 * has labels or sequence numbers.
                    763:                 */
1.13      simonb    764:                printf("Tape position lost\n");
1.2       ragge     765:                bp->b_error = EIO;
1.1       ragge     766:                break;
                    767:
                    768:        case TS_TC_FCE:
                    769:                /*
                    770:                 * Fatal subsytem Error -- The subsytem is incapable
                    771:                 * of properly performing commands, or at least its
1.13      simonb    772:                 * integrity is seriously questionable. Refer to the
1.1       ragge     773:                 * fatal class code field in the TSSR register for
                    774:                 * additional information on the type of fatal error.
                    775:                 */
1.13      simonb    776:                printf ("Fatal Controller Error\n");
1.2       ragge     777:                prtstat(sc, sr);
                    778:                break;
1.1       ragge     779:
                    780:        default:
1.13      simonb    781:                printf ("%s: error 0x%x, resetting controller\n",
1.1       ragge     782:                        sc->sc_dev.dv_xname, sr & TS_TC);
1.2       ragge     783:                tsreset(sc);
1.1       ragge     784:        }
1.14      yamt      785:        if ((bp = BUFQ_GET(sc->sc_bufq)) != NULL) {
1.2       ragge     786: #ifdef TSDEBUG
1.14      yamt      787:                printf("tsintr2: que %p\n", BUFQ_PEEK(sc->sc_bufq));
1.2       ragge     788: #endif
                    789:                if (bp != &sc->ts_cbuf) {       /* no ioctl */
                    790:                        bus_dmamap_unload(sc->sc_dmat, sc->sc_dmam);
1.16      thorpej   791:                        uba_done((void *)device_parent(&sc->sc_dev));
1.2       ragge     792:                }
                    793:                bp->b_resid = sc->sc_vts->status.rbpcr;
1.1       ragge     794:                biodone (bp);
                    795:        }
1.2       ragge     796:        tsstart(sc, 0);
1.1       ragge     797: }
                    798:
                    799:
                    800: /*
                    801:  * Open a ts device and set the unit online.  If the controller is not
                    802:  * in the run state, call init to initialize the ts controller first.
                    803:  */
                    804: int
1.2       ragge     805: tsopen(dev_t dev, int flag, int type, struct proc *p)
1.1       ragge     806: {
1.2       ragge     807:        struct ts_softc *sc;
                    808:        int unit = TS_UNIT(dev);
1.1       ragge     809:
                    810:        if (unit >= ts_cd.cd_ndevs)
                    811:                return ENXIO;
                    812:
                    813:        sc = ts_cd.cd_devs[unit];
                    814:        if (sc == 0)
                    815:                return ENXIO;
                    816:
1.2       ragge     817:        if (sc->sc_state < TS_RUNNING)
                    818:                return ENXIO;
                    819:
1.1       ragge     820:        if (sc->sc_openf)
                    821:                return EBUSY;
                    822:        sc->sc_openf = 1;
                    823:
                    824:        /*
                    825:         * check if transport is really online.
                    826:         * (without attention-interrupts enabled, we really don't know
                    827:         * the actual state of the transport. Thus we call get-status
                    828:         * (ie. MTNOP) once and check the actual status.)
                    829:         */
1.2       ragge     830:        if (TS_RCSR(TSSR) & TS_OFL) {
                    831:                uprintf("%s: transport is offline.\n", XNAME);
1.1       ragge     832:                sc->sc_openf = 0;
                    833:                return EIO;             /* transport is offline */
                    834:        }
1.2       ragge     835:        tscommand(sc, dev, MTNOP, 1);
                    836:        if ((flag & FWRITE) && (sc->sc_vts->status.xst0 & TS_SF_WLK)) {
                    837:                uprintf("%s: no write ring.\n", XNAME);
                    838:                sc->sc_openf = 0;
                    839:                return EROFS;
                    840:        }
                    841:        if (sc->sc_vts->status.xst0 & TS_SF_VCK) {
                    842:                sc->sc_vts->cmd.cmdr = TS_CF_CVC|TS_CF_ACK;
                    843:                TS_WCSR(TSDB, sc->sc_waddr);
                    844:        }
                    845:        tscommand(sc, dev, MTNOP, 1);
                    846: #ifdef TSDEBUG
                    847:        {
                    848:                char buf[100];
                    849:                bitmask_snprintf(sc->sc_vts->status.xst0,
                    850:                    TS_XST0_BITS, buf, sizeof(buf));
                    851:                printf("tsopen: xst0 %s\n", buf);
                    852:        }
                    853: #endif
1.1       ragge     854:        sc->sc_liowf = 0;
                    855:        return 0;
                    856: }
                    857:
                    858:
                    859: /*
                    860:  * Close tape device.
                    861:  *
                    862:  * If tape was open for writing or last operation was
                    863:  * a write, then write two EOF's and backspace over the last one.
                    864:  * Unless this is a non-rewinding special file, rewind the tape.
                    865:  *
                    866:  * Make the tape available to others, by clearing openf flag.
                    867:  */
                    868: int
1.2       ragge     869: tsclose(dev_t dev, int flag, int type, struct proc *p)
1.1       ragge     870: {
1.2       ragge     871:        struct ts_softc *sc = ts_cd.cd_devs[TS_UNIT(dev)];
1.1       ragge     872:
                    873:        if (flag == FWRITE || ((flag & FWRITE) && sc->sc_liowf)) {
1.13      simonb    874:                /*
1.1       ragge     875:                 * We are writing two tape marks (EOT), but place the tape
                    876:                 * before the second one, so that another write operation
                    877:                 * will overwrite the second one and leave and EOF-mark.
                    878:                 */
1.2       ragge     879:                tscommand(sc, dev, MTWEOF, 1);  /* Write Tape Mark */
                    880:                tscommand(sc, dev, MTWEOF, 1);  /* Write Tape Mark */
                    881:                tscommand(sc, dev, MTBSF, 1);   /* Skip Tape Marks Reverse */
1.1       ragge     882:        }
                    883:
                    884:        if ((dev & T_NOREWIND) == 0)
1.2       ragge     885:                tscommand(sc, dev, MTREW, 0);
1.1       ragge     886:
                    887:        sc->sc_openf = 0;
                    888:        sc->sc_liowf = 0;
                    889:        return 0;
                    890: }
                    891:
                    892:
                    893: /*
                    894:  * Manage buffers and perform block mode read and write operations.
                    895:  */
                    896: void
1.2       ragge     897: tsstrategy(struct buf *bp)
1.1       ragge     898: {
                    899:        register int unit = TS_UNIT(bp->b_dev);
                    900:        struct ts_softc *sc = (void *)ts_cd.cd_devs[unit];
1.2       ragge     901:        int s, empty;
1.1       ragge     902:
1.2       ragge     903: #ifdef TSDEBUG
                    904:        printf("buf: %p bcount %ld blkno %d\n", bp, bp->b_bcount, bp->b_blkno);
                    905: #endif
1.1       ragge     906:        s = splbio ();
1.14      yamt      907:        empty = (BUFQ_PEEK(sc->sc_bufq) == NULL);
                    908:        BUFQ_PUT(sc->sc_bufq, bp);
1.2       ragge     909:        if (empty)
                    910:                tsstart(sc, 0);
1.1       ragge     911:        splx(s);
                    912: }
                    913:
                    914:
                    915: /*
                    916:  * Catch ioctl commands, and call the "command" routine to do them.
                    917:  */
                    918: int
1.2       ragge     919: tsioctl(dev, cmd, data, flag, p)
1.1       ragge     920:        dev_t dev;
                    921:        u_long cmd;
1.19      christos  922:        void *data;
1.1       ragge     923:        int flag;
                    924:        struct proc *p;
                    925: {
1.2       ragge     926:        struct buf *bp;
                    927:        struct ts_softc *sc;
                    928:        struct mtop *mtop;      /* mag tape cmd op to perform */
                    929:        struct mtget *mtget;    /* mag tape struct to get info in */
                    930:        int callcount;          /* number of times to call routine */
1.1       ragge     931:        int scount;                     /* number of files/records to space */
                    932:        int spaceop = 0;                /* flag for skip/space operation */
                    933:        int error = 0;
                    934:
1.2       ragge     935: #ifdef TSDEBUG
                    936:        printf("tsioctl (%x, %lx, %p, %d)\n", dev, cmd, data, flag);
                    937: #endif
                    938:
                    939:        sc = ts_cd.cd_devs[TS_UNIT(dev)];
                    940:        bp = &sc->ts_cbuf;
1.1       ragge     941:
                    942:        switch (cmd) {
                    943:        case MTIOCTOP:                  /* do a mag tape op */
                    944:                mtop = (struct mtop *)data;
                    945:                switch (mtop->mt_op) {
                    946:                case MTWEOF:            /* write an end-of-file record */
                    947:                        callcount = mtop->mt_count;
                    948:                        scount = 1;
                    949:                        break;
                    950:                case MTFSR:             /* forward space record */
                    951:                case MTBSR:             /* backward space record */
                    952:                        spaceop = 1;
1.2       ragge     953:                case MTFSF:             /* forward space file */
                    954:                case MTBSF:             /* backward space file */
1.1       ragge     955:                        callcount = 1;
                    956:                        scount = mtop->mt_count;
                    957:                        break;
                    958:                case MTREW:             /* rewind */
                    959:                case MTOFFL:            /* rewind and put the drive offline */
                    960:                case MTNOP:             /* no operation, sets status only */
                    961:                        callcount = 1;
                    962:                        scount = 1;             /* wait for this rewind */
                    963:                        break;
                    964:                case MTRETEN:           /* retension */
                    965:                case MTERASE:           /* erase entire tape */
                    966:                case MTEOM:             /* forward to end of media */
                    967:                case MTNBSF:            /* backward space to begin of file */
                    968:                case MTCACHE:           /* enable controller cache */
                    969:                case MTNOCACHE:         /* disable controller cache */
                    970:                case MTSETBSIZ:         /* set block size; 0 for variable */
                    971:                case MTSETDNSTY:        /* set density code for current mode */
1.2       ragge     972:                        printf("ioctl %d not implemented.\n", mtop->mt_op);
1.1       ragge     973:                        return (ENXIO);
                    974:                default:
1.2       ragge     975: #ifdef TSDEBUG
                    976:                        printf("invalid ioctl %d\n", mtop->mt_op);
                    977: #endif
1.1       ragge     978:                        return (ENXIO);
                    979:                }       /* switch (mtop->mt_op) */
                    980:
                    981:                if (callcount <= 0 || scount <= 0) {
1.2       ragge     982: #ifdef TSDEBUG
                    983:                        printf("invalid values %d/%d\n", callcount, scount);
                    984: #endif
1.1       ragge     985:                        return (EINVAL);
                    986:                }
                    987:                do {
1.2       ragge     988:                        tscommand(sc, dev, mtop->mt_op, scount);
1.1       ragge     989:                        if (spaceop && bp->b_resid) {
1.2       ragge     990: #ifdef TSDEBUG
                    991:                                printf(("spaceop didn't complete\n"));
                    992: #endif
1.1       ragge     993:                                return (EIO);
                    994:                        }
1.20      ad        995:                        if (bp->b_error != 0) {
1.2       ragge     996: #ifdef TSDEBUG
                    997:                                printf("error in ioctl %d\n", mtop->mt_op);
                    998: #endif
1.1       ragge     999:                                break;
                   1000:                        }
                   1001:                } while (--callcount > 0);
1.20      ad       1002:                if (bp->b_error != 0)
                   1003:                        error = bp->b_error;
1.13      simonb   1004:                return (error);
1.1       ragge    1005:
                   1006:        case MTIOCGET:                  /* get tape status */
                   1007:                mtget = (struct mtget *)data;
                   1008:                mtget->mt_type = MT_ISTS;
1.2       ragge    1009:                mtget->mt_dsreg = TS_RCSR(TSSR);
                   1010:                mtget->mt_erreg = sc->sc_vts->status.xst0;
1.1       ragge    1011:                mtget->mt_resid = 0;            /* ??? */
                   1012:                mtget->mt_density = 0;          /* ??? */
                   1013:                break;
                   1014:
                   1015:        case MTIOCIEOT:                 /* ignore EOT error */
1.2       ragge    1016: #ifdef TSDEBUG
                   1017:                printf(("MTIOCIEOT not implemented.\n"));
                   1018: #endif
1.13      simonb   1019:                return (ENXIO);
1.1       ragge    1020:
                   1021:        case MTIOCEEOT:                 /* enable EOT error */
1.2       ragge    1022: #ifdef TSDEBUG
                   1023:                printf(("MTIOCEEOT not implemented.\n"));
                   1024: #endif
1.1       ragge    1025:                return (ENXIO);
                   1026:
                   1027:        default:
1.2       ragge    1028: #ifdef TSDEBUG
                   1029:                printf("invalid ioctl cmd 0x%lx\n", cmd);
                   1030: #endif
1.1       ragge    1031:                return (ENXIO);
                   1032:        }
                   1033:
                   1034:        return (0);
                   1035: }
                   1036:
                   1037:
                   1038: /*
1.13      simonb   1039:  *
1.1       ragge    1040:  */
                   1041: int
1.2       ragge    1042: tsread(dev_t dev, struct uio *uio, int flag)
1.1       ragge    1043: {
                   1044:        return (physio (tsstrategy, NULL, dev, B_READ, minphys, uio));
                   1045: }
                   1046:
                   1047: /*
                   1048:  *
                   1049:  */
                   1050: int
1.2       ragge    1051: tswrite(dev_t dev, struct uio *uio, int flag)
1.1       ragge    1052: {
                   1053:        return (physio (tsstrategy, NULL, dev, B_WRITE, minphys, uio));
                   1054: }
                   1055:
                   1056: /*
                   1057:  *
                   1058:  */
                   1059: int
                   1060: tsdump(dev, blkno, va, size)
                   1061:        dev_t dev;
                   1062:        daddr_t blkno;
1.19      christos 1063:        void *va;
1.1       ragge    1064:        size_t size;
                   1065: {
1.2       ragge    1066:        return EIO;
1.1       ragge    1067: }

CVSweb <webmaster@jp.NetBSD.org>