[BACK]Return to uha.c CVS log [TXT][DIR] Up to [local] / sys / dev / ic

Annotation of sys/dev/ic/uha.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: uha.c,v 1.9 2006/11/28 23:59:45 dlg Exp $     */
        !             2: /*     $NetBSD: uha.c,v 1.3 1996/10/13 01:37:29 christos Exp $ */
        !             3:
        !             4: #undef UHADEBUG
        !             5: #ifdef DDB
        !             6: #define        integrate
        !             7: #else
        !             8: #define        integrate       static inline
        !             9: #endif
        !            10:
        !            11: /*
        !            12:  * Copyright (c) 1994, 1996 Charles M. Hannum.  All rights reserved.
        !            13:  *
        !            14:  * Redistribution and use in source and binary forms, with or without
        !            15:  * modification, are permitted provided that the following conditions
        !            16:  * are met:
        !            17:  * 1. Redistributions of source code must retain the above copyright
        !            18:  *    notice, this list of conditions and the following disclaimer.
        !            19:  * 2. Redistributions in binary form must reproduce the above copyright
        !            20:  *    notice, this list of conditions and the following disclaimer in the
        !            21:  *    documentation and/or other materials provided with the distribution.
        !            22:  * 3. All advertising materials mentioning features or use of this software
        !            23:  *    must display the following acknowledgement:
        !            24:  *     This product includes software developed by Charles M. Hannum.
        !            25:  * 4. The name of the author may not be used to endorse or promote products
        !            26:  *    derived from this software without specific prior written permission.
        !            27:  *
        !            28:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            29:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            30:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            31:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            32:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            33:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            34:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            35:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            36:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            37:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            38:  */
        !            39:
        !            40: /*
        !            41:  * Ported for use with the UltraStor 14f by Gary Close (gclose@wvnvms.wvnet.edu)
        !            42:  * Slight fixes to timeouts to run with the 34F
        !            43:  * Thanks to Julian Elischer for advice and help with this port.
        !            44:  *
        !            45:  * Originally written by Julian Elischer (julian@tfs.com)
        !            46:  * for TRW Financial Systems for use under the MACH(2.5) operating system.
        !            47:  *
        !            48:  * TRW Financial Systems, in accordance with their agreement with Carnegie
        !            49:  * Mellon University, makes this software available to CMU to distribute
        !            50:  * or use in any manner that they see fit as long as this message is kept with
        !            51:  * the software. For this reason TFS also grants any other persons or
        !            52:  * organisations permission to use or modify this software.
        !            53:  *
        !            54:  * TFS supplies this software to be publicly redistributed
        !            55:  * on the understanding that TFS is not responsible for the correct
        !            56:  * functioning of this software in any circumstances.
        !            57:  *
        !            58:  * commenced: Sun Sep 27 18:14:01 PDT 1992
        !            59:  * slight mod to make work with 34F as well: Wed Jun  2 18:05:48 WST 1993
        !            60:  */
        !            61:
        !            62: #include <sys/types.h>
        !            63: #include <sys/param.h>
        !            64: #include <sys/systm.h>
        !            65: #include <sys/kernel.h>
        !            66: #include <sys/errno.h>
        !            67: #include <sys/ioctl.h>
        !            68: #include <sys/device.h>
        !            69: #include <sys/malloc.h>
        !            70: #include <sys/buf.h>
        !            71: #include <sys/proc.h>
        !            72: #include <sys/user.h>
        !            73:
        !            74: #include <machine/bus.h>
        !            75: #include <machine/intr.h>
        !            76:
        !            77: #include <scsi/scsi_all.h>
        !            78: #include <scsi/scsiconf.h>
        !            79:
        !            80: #include <dev/ic/uhareg.h>
        !            81: #include <dev/ic/uhavar.h>
        !            82:
        !            83: #ifndef        DDB
        !            84: #define Debugger() panic("should call debugger here (ultra14f.c)")
        !            85: #endif /* ! DDB */
        !            86:
        !            87: #define KVTOPHYS(x)    vtophys((vaddr_t)x)
        !            88:
        !            89: integrate void uha_reset_mscp(struct uha_softc *, struct uha_mscp *);
        !            90: void uha_free_mscp(struct uha_softc *, struct uha_mscp *);
        !            91: integrate void uha_init_mscp(struct uha_softc *, struct uha_mscp *);
        !            92: struct uha_mscp *uha_get_mscp(struct uha_softc *, int);
        !            93: void uhaminphys(struct buf *);
        !            94: int uha_scsi_cmd(struct scsi_xfer *);
        !            95:
        !            96: struct scsi_adapter uha_switch = {
        !            97:        uha_scsi_cmd,
        !            98:        uhaminphys,
        !            99:        0,
        !           100:        0,
        !           101: };
        !           102:
        !           103: /* the below structure is so we have a default dev struct for out link struct */
        !           104: struct scsi_device uha_dev = {
        !           105:        NULL,                   /* Use default error handler */
        !           106:        NULL,                   /* have a queue, served by this */
        !           107:        NULL,                   /* have no async handler */
        !           108:        NULL,                   /* Use default 'done' routine */
        !           109: };
        !           110:
        !           111: struct cfdriver uha_cd = {
        !           112:        NULL, "uha", DV_DULL
        !           113: };
        !           114:
        !           115: #define        UHA_ABORT_TIMEOUT       2000    /* time to wait for abort (mSec) */
        !           116:
        !           117: #ifdef __OpenBSD__
        !           118: int    uhaprint(void *, const char *);
        !           119:
        !           120: int
        !           121: uhaprint(aux, name)
        !           122:        void *aux;
        !           123:        const char *name;
        !           124: {
        !           125:
        !           126:        if (name != NULL)
        !           127:                printf("%s: scsibus ", name);
        !           128:        return UNCONF;
        !           129: }
        !           130: #endif
        !           131:
        !           132: /*
        !           133:  * Attach all the sub-devices we can find
        !           134:  */
        !           135: void
        !           136: uha_attach(sc)
        !           137:        struct uha_softc *sc;
        !           138: {
        !           139:        struct scsibus_attach_args saa;
        !           140:
        !           141:        (sc->init)(sc);
        !           142:        TAILQ_INIT(&sc->sc_free_mscp);
        !           143:
        !           144:        /*
        !           145:         * fill in the prototype scsi_link.
        !           146:         */
        !           147:        sc->sc_link.adapter_softc = sc;
        !           148:        sc->sc_link.adapter_target = sc->sc_scsi_dev;
        !           149:        sc->sc_link.adapter = &uha_switch;
        !           150:        sc->sc_link.device = &uha_dev;
        !           151:        sc->sc_link.openings = 2;
        !           152:
        !           153:        bzero(&saa, sizeof(saa));
        !           154:        saa.saa_sc_link = &sc->sc_link;
        !           155:
        !           156:        /*
        !           157:         * ask the adapter what subunits are present
        !           158:         */
        !           159:        config_found(&sc->sc_dev, &saa, uhaprint);
        !           160: }
        !           161:
        !           162: integrate void
        !           163: uha_reset_mscp(sc, mscp)
        !           164:        struct uha_softc *sc;
        !           165:        struct uha_mscp *mscp;
        !           166: {
        !           167:
        !           168:        mscp->flags = 0;
        !           169: }
        !           170:
        !           171: /*
        !           172:  * A mscp (and hence a mbx-out) is put onto the free list.
        !           173:  */
        !           174: void
        !           175: uha_free_mscp(sc, mscp)
        !           176:        struct uha_softc *sc;
        !           177:        struct uha_mscp *mscp;
        !           178: {
        !           179:        int s;
        !           180:
        !           181:        s = splbio();
        !           182:
        !           183:        uha_reset_mscp(sc, mscp);
        !           184:        TAILQ_INSERT_HEAD(&sc->sc_free_mscp, mscp, chain);
        !           185:
        !           186:        /*
        !           187:         * If there were none, wake anybody waiting for one to come free,
        !           188:         * starting with queued entries.
        !           189:         */
        !           190:        if (TAILQ_NEXT(mscp, chain) == NULL)
        !           191:                wakeup(&sc->sc_free_mscp);
        !           192:
        !           193:        splx(s);
        !           194: }
        !           195:
        !           196: integrate void
        !           197: uha_init_mscp(sc, mscp)
        !           198:        struct uha_softc *sc;
        !           199:        struct uha_mscp *mscp;
        !           200: {
        !           201:        int hashnum;
        !           202:
        !           203:        bzero(mscp, sizeof(struct uha_mscp));
        !           204:        /*
        !           205:         * put in the phystokv hash table
        !           206:         * Never gets taken out.
        !           207:         */
        !           208:        mscp->hashkey = KVTOPHYS(mscp);
        !           209:        hashnum = MSCP_HASH(mscp->hashkey);
        !           210:        mscp->nexthash = sc->sc_mscphash[hashnum];
        !           211:        sc->sc_mscphash[hashnum] = mscp;
        !           212:        uha_reset_mscp(sc, mscp);
        !           213: }
        !           214:
        !           215: /*
        !           216:  * Get a free mscp
        !           217:  *
        !           218:  * If there are none, see if we can allocate a new one.  If so, put it in the
        !           219:  * hash table too otherwise either return an error or sleep.
        !           220:  */
        !           221: struct uha_mscp *
        !           222: uha_get_mscp(sc, flags)
        !           223:        struct uha_softc *sc;
        !           224:        int flags;
        !           225: {
        !           226:        struct uha_mscp *mscp;
        !           227:        int s;
        !           228:
        !           229:        s = splbio();
        !           230:
        !           231:        /*
        !           232:         * If we can and have to, sleep waiting for one to come free
        !           233:         * but only if we can't allocate a new one
        !           234:         */
        !           235:        for (;;) {
        !           236:                mscp = TAILQ_FIRST(&sc->sc_free_mscp);
        !           237:                if (mscp) {
        !           238:                        TAILQ_REMOVE(&sc->sc_free_mscp, mscp, chain);
        !           239:                        break;
        !           240:                }
        !           241:                if (sc->sc_nummscps < UHA_MSCP_MAX) {
        !           242:                        mscp = (struct uha_mscp *) malloc(sizeof(struct uha_mscp),
        !           243:                            M_TEMP, M_NOWAIT);
        !           244:                        if (!mscp) {
        !           245:                                printf("%s: can't malloc mscp\n",
        !           246:                                    sc->sc_dev.dv_xname);
        !           247:                                goto out;
        !           248:                        }
        !           249:                        uha_init_mscp(sc, mscp);
        !           250:                        sc->sc_nummscps++;
        !           251:                        break;
        !           252:                }
        !           253:                if ((flags & SCSI_NOSLEEP) != 0)
        !           254:                        goto out;
        !           255:                tsleep(&sc->sc_free_mscp, PRIBIO, "uhamsc", 0);
        !           256:        }
        !           257:
        !           258:        mscp->flags |= MSCP_ALLOC;
        !           259:
        !           260: out:
        !           261:        splx(s);
        !           262:        return (mscp);
        !           263: }
        !           264:
        !           265: /*
        !           266:  * given a physical address, find the mscp that it corresponds to.
        !           267:  */
        !           268: struct uha_mscp *
        !           269: uha_mscp_phys_kv(sc, mscp_phys)
        !           270:        struct uha_softc *sc;
        !           271:        u_long mscp_phys;
        !           272: {
        !           273:        int hashnum = MSCP_HASH(mscp_phys);
        !           274:        struct uha_mscp *mscp = sc->sc_mscphash[hashnum];
        !           275:
        !           276:        while (mscp) {
        !           277:                if (mscp->hashkey == mscp_phys)
        !           278:                        break;
        !           279:                mscp = mscp->nexthash;
        !           280:        }
        !           281:        return (mscp);
        !           282: }
        !           283:
        !           284: /*
        !           285:  * We have a mscp which has been processed by the adaptor, now we look to see
        !           286:  * how the operation went.
        !           287:  */
        !           288: void
        !           289: uha_done(sc, mscp)
        !           290:        struct uha_softc *sc;
        !           291:        struct uha_mscp *mscp;
        !           292: {
        !           293:        struct scsi_sense_data *s1, *s2;
        !           294:        struct scsi_xfer *xs = mscp->xs;
        !           295:
        !           296:        SC_DEBUG(xs->sc_link, SDEV_DB2, ("uha_done\n"));
        !           297:        /*
        !           298:         * Otherwise, put the results of the operation
        !           299:         * into the xfer and call whoever started it
        !           300:         */
        !           301:        if ((mscp->flags & MSCP_ALLOC) == 0) {
        !           302:                printf("%s: exiting ccb not allocated!\n", sc->sc_dev.dv_xname);
        !           303:                Debugger();
        !           304:                return;
        !           305:        }
        !           306:        if (xs->error == XS_NOERROR) {
        !           307:                if (mscp->host_stat != UHA_NO_ERR) {
        !           308:                        switch (mscp->host_stat) {
        !           309:                        case UHA_SBUS_TIMEOUT:          /* No response */
        !           310:                                xs->error = XS_SELTIMEOUT;
        !           311:                                break;
        !           312:                        default:        /* Other scsi protocol messes */
        !           313:                                printf("%s: host_stat %x\n",
        !           314:                                    sc->sc_dev.dv_xname, mscp->host_stat);
        !           315:                                xs->error = XS_DRIVER_STUFFUP;
        !           316:                        }
        !           317:                } else if (mscp->target_stat != SCSI_OK) {
        !           318:                        switch (mscp->target_stat) {
        !           319:                        case SCSI_CHECK:
        !           320:                                s1 = &mscp->mscp_sense;
        !           321:                                s2 = &xs->sense;
        !           322:                                *s2 = *s1;
        !           323:                                xs->error = XS_SENSE;
        !           324:                                break;
        !           325:                        case SCSI_BUSY:
        !           326:                                xs->error = XS_BUSY;
        !           327:                                break;
        !           328:                        default:
        !           329:                                printf("%s: target_stat %x\n",
        !           330:                                    sc->sc_dev.dv_xname, mscp->target_stat);
        !           331:                                xs->error = XS_DRIVER_STUFFUP;
        !           332:                        }
        !           333:                } else
        !           334:                        xs->resid = 0;
        !           335:        }
        !           336:        uha_free_mscp(sc, mscp);
        !           337:        xs->flags |= ITSDONE;
        !           338:        scsi_done(xs);
        !           339: }
        !           340:
        !           341: void
        !           342: uhaminphys(bp)
        !           343:        struct buf *bp;
        !           344: {
        !           345:
        !           346:        if (bp->b_bcount > ((UHA_NSEG - 1) << PGSHIFT))
        !           347:                bp->b_bcount = ((UHA_NSEG - 1) << PGSHIFT);
        !           348:        minphys(bp);
        !           349: }
        !           350:
        !           351: /*
        !           352:  * start a scsi operation given the command and the data address.  Also
        !           353:  * needs the unit, target and lu.
        !           354:  */
        !           355: int
        !           356: uha_scsi_cmd(xs)
        !           357:        struct scsi_xfer *xs;
        !           358: {
        !           359:        struct scsi_link *sc_link = xs->sc_link;
        !           360:        struct uha_softc *sc = sc_link->adapter_softc;
        !           361:        struct uha_mscp *mscp;
        !           362:        struct uha_dma_seg *sg;
        !           363:        int seg;                /* scatter gather seg being worked on */
        !           364:        u_long thiskv, thisphys, nextphys;
        !           365:        int bytes_this_seg, bytes_this_page, datalen, flags;
        !           366:        int s;
        !           367:
        !           368:        SC_DEBUG(sc_link, SDEV_DB2, ("uha_scsi_cmd\n"));
        !           369:        /*
        !           370:         * get a mscp (mbox-out) to use. If the transfer
        !           371:         * is from a buf (possibly from interrupt time)
        !           372:         * then we can't allow it to sleep
        !           373:         */
        !           374:        flags = xs->flags;
        !           375:        if ((mscp = uha_get_mscp(sc, flags)) == NULL) {
        !           376:                return (TRY_AGAIN_LATER);
        !           377:        }
        !           378:        mscp->xs = xs;
        !           379:        mscp->timeout = xs->timeout;
        !           380:        timeout_set(&xs->stimeout, uha_timeout, xs);
        !           381:
        !           382:        /*
        !           383:         * Put all the arguments for the xfer in the mscp
        !           384:         */
        !           385:        if (flags & SCSI_RESET) {
        !           386:                mscp->opcode = UHA_SDR;
        !           387:                mscp->ca = 0x01;
        !           388:        } else {
        !           389:                mscp->opcode = UHA_TSP;
        !           390:                /* XXX Not for tapes. */
        !           391:                mscp->ca = 0x01;
        !           392:                bcopy(xs->cmd, &mscp->scsi_cmd, mscp->scsi_cmd_length);
        !           393:        }
        !           394:        mscp->xdir = UHA_SDET;
        !           395:        mscp->dcn = 0x00;
        !           396:        mscp->chan = 0x00;
        !           397:        mscp->target = sc_link->target;
        !           398:        mscp->lun = sc_link->lun;
        !           399:        mscp->scsi_cmd_length = xs->cmdlen;
        !           400:        mscp->sense_ptr = KVTOPHYS(&mscp->mscp_sense);
        !           401:        mscp->req_sense_length = sizeof(mscp->mscp_sense);
        !           402:        mscp->host_stat = 0x00;
        !           403:        mscp->target_stat = 0x00;
        !           404:
        !           405:        if (xs->datalen) {
        !           406:                sg = mscp->uha_dma;
        !           407:                seg = 0;
        !           408: #ifdef TFS
        !           409:                if (flags & SCSI_DATA_UIO) {
        !           410:                        struct iovec *iovp;
        !           411:                        iovp = ((struct uio *) xs->data)->uio_iov;
        !           412:                        datalen = ((struct uio *) xs->data)->uio_iovcnt;
        !           413:                        xs->datalen = 0;
        !           414:                        while (datalen && seg < UHA_NSEG) {
        !           415:                                sg->seg_addr = (physaddr)iovp->iov_base;
        !           416:                                sg->seg_len = iovp->iov_len;
        !           417:                                xs->datalen += iovp->iov_len;
        !           418:                                SC_DEBUGN(sc_link, SDEV_DB4, ("(0x%x@0x%x)",
        !           419:                                    iovp->iov_len, iovp->iov_base));
        !           420:                                sg++;
        !           421:                                iovp++;
        !           422:                                seg++;
        !           423:                                datalen--;
        !           424:                        }
        !           425:                } else
        !           426: #endif /*TFS */
        !           427:                {
        !           428:                        /*
        !           429:                         * Set up the scatter gather block
        !           430:                         */
        !           431:                        SC_DEBUG(sc_link, SDEV_DB4,
        !           432:                            ("%d @0x%x:- ", xs->datalen, xs->data));
        !           433:                        datalen = xs->datalen;
        !           434:                        thiskv = (int) xs->data;
        !           435:                        thisphys = KVTOPHYS(thiskv);
        !           436:
        !           437:                        while (datalen && seg < UHA_NSEG) {
        !           438:                                bytes_this_seg = 0;
        !           439:
        !           440:                                /* put in the base address */
        !           441:                                sg->seg_addr = thisphys;
        !           442:
        !           443:                                SC_DEBUGN(sc_link, SDEV_DB4, ("0x%x", thisphys));
        !           444:
        !           445:                                /* do it at least once */
        !           446:                                nextphys = thisphys;
        !           447:                                while (datalen && thisphys == nextphys) {
        !           448:                                        /*
        !           449:                                         * This page is contiguous (physically)
        !           450:                                         * with the last, just extend the
        !           451:                                         * length
        !           452:                                         */
        !           453:                                        /* how far to the end of the page */
        !           454:                                        nextphys = (thisphys & ~PGOFSET) + NBPG;
        !           455:                                        bytes_this_page = nextphys - thisphys;
        !           456:                                        /**** or the data ****/
        !           457:                                        bytes_this_page = min(bytes_this_page,
        !           458:                                                              datalen);
        !           459:                                        bytes_this_seg += bytes_this_page;
        !           460:                                        datalen -= bytes_this_page;
        !           461:
        !           462:                                        /* get more ready for the next page */
        !           463:                                        thiskv = (thiskv & ~PGOFSET) + NBPG;
        !           464:                                        if (datalen)
        !           465:                                                thisphys = KVTOPHYS(thiskv);
        !           466:                                }
        !           467:                                /*
        !           468:                                 * next page isn't contiguous, finish the seg
        !           469:                                 */
        !           470:                                SC_DEBUGN(sc_link, SDEV_DB4,
        !           471:                                    ("(0x%x)", bytes_this_seg));
        !           472:                                sg->seg_len = bytes_this_seg;
        !           473:                                sg++;
        !           474:                                seg++;
        !           475:                        }
        !           476:                }
        !           477:                /* end of iov/kv decision */
        !           478:                SC_DEBUGN(sc_link, SDEV_DB4, ("\n"));
        !           479:                if (datalen) {
        !           480:                        /*
        !           481:                         * there's still data, must have run out of segs!
        !           482:                         */
        !           483:                        printf("%s: uha_scsi_cmd, more than %d dma segs\n",
        !           484:                            sc->sc_dev.dv_xname, UHA_NSEG);
        !           485:                        goto bad;
        !           486:                }
        !           487:                mscp->data_addr = KVTOPHYS(mscp->uha_dma);
        !           488:                mscp->data_length = xs->datalen;
        !           489:                mscp->sgth = 0x01;
        !           490:                mscp->sg_num = seg;
        !           491:        } else {                /* No data xfer, use non S/G values */
        !           492:                mscp->data_addr = (physaddr)0;
        !           493:                mscp->data_length = 0;
        !           494:                mscp->sgth = 0x00;
        !           495:                mscp->sg_num = 0;
        !           496:        }
        !           497:        mscp->link_id = 0;
        !           498:        mscp->link_addr = (physaddr)0;
        !           499:
        !           500:        s = splbio();
        !           501:        (sc->start_mbox)(sc, mscp);
        !           502:        splx(s);
        !           503:
        !           504:        /*
        !           505:         * Usually return SUCCESSFULLY QUEUED
        !           506:         */
        !           507:        if ((flags & SCSI_POLL) == 0)
        !           508:                return (SUCCESSFULLY_QUEUED);
        !           509:
        !           510:        /*
        !           511:         * If we can't use interrupts, poll on completion
        !           512:         */
        !           513:        if ((sc->poll)(sc, xs, mscp->timeout)) {
        !           514:                uha_timeout(mscp);
        !           515:                if ((sc->poll)(sc, xs, mscp->timeout))
        !           516:                        uha_timeout(mscp);
        !           517:        }
        !           518:        return (COMPLETE);
        !           519:
        !           520: bad:
        !           521:        xs->error = XS_DRIVER_STUFFUP;
        !           522:        uha_free_mscp(sc, mscp);
        !           523:        return (COMPLETE);
        !           524: }
        !           525:
        !           526: void
        !           527: uha_timeout(arg)
        !           528:        void *arg;
        !           529: {
        !           530:        struct uha_mscp *mscp = arg;
        !           531:        struct scsi_xfer *xs = mscp->xs;
        !           532:        struct scsi_link *sc_link = xs->sc_link;
        !           533:        struct uha_softc *sc = sc_link->adapter_softc;
        !           534:        int s;
        !           535:
        !           536:        sc_print_addr(sc_link);
        !           537:        printf("timed out");
        !           538:
        !           539:        s = splbio();
        !           540:
        !           541:        if (mscp->flags & MSCP_ABORT) {
        !           542:                /* abort timed out */
        !           543:                printf(" AGAIN\n");
        !           544:                /* XXX Must reset! */
        !           545:        } else {
        !           546:                /* abort the operation that has timed out */
        !           547:                printf("\n");
        !           548:                mscp->xs->error = XS_TIMEOUT;
        !           549:                mscp->timeout = UHA_ABORT_TIMEOUT;
        !           550:                mscp->flags |= MSCP_ABORT;
        !           551:                (sc->start_mbox)(sc, mscp);
        !           552:        }
        !           553:
        !           554:        splx(s);
        !           555: }

CVSweb