Annotation of Gnu-Mach/scsi/rz_tape.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1991,1990 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  * 
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            24:  * the rights to redistribute these changes.
        !            25:  */
        !            26: /*
        !            27:  *     File: rz_tape.c
        !            28:  *     Author: Alessandro Forin, Carnegie Mellon University
        !            29:  *     Date:   10/90
        !            30:  *
        !            31:  *     Top layer of the SCSI driver: interface with the MI.
        !            32:  *     This file contains operations specific to TAPE-like devices.
        !            33:  */
        !            34: 
        !            35: #include <mach/std_types.h>
        !            36: #include <scsi/compat_30.h>
        !            37: 
        !            38: #include <sys/ioctl.h>
        !            39: #ifdef MACH_KERNEL
        !            40: #include <device/tape_status.h>
        !            41: #else  /*MACH_KERNEL*/
        !            42: #include <mips/PMAX/tape_status.h>
        !            43: #endif /*MACH_KERNEL*/
        !            44: 
        !            45: #include <scsi/scsi.h>
        !            46: #include <scsi/scsi_defs.h>
        !            47: #include <scsi/rz.h>
        !            48: 
        !            49: #if  (NSCSI > 0)
        !            50: 
        !            51: 
        !            52: void sctape_start(); /* forward */
        !            53: 
        !            54: int scsi_tape_timeout = 5*60;  /* secs, tk50 is slow when positioning far apart */
        !            55: 
        !            56: int sctape_open(tgt, req)
        !            57:        target_info_t   *tgt;
        !            58:        io_req_t        req;
        !            59: {
        !            60:        io_return_t     ret;
        !            61:        io_req_t        ior;
        !            62:        int             i;
        !            63:        scsi_mode_sense_data_t *mod;
        !            64: 
        !            65: #ifdef MACH_KERNEL
        !            66:        req->io_device->flag |= D_EXCL_OPEN;
        !            67: #endif /*MACH_KERNEL*/
        !            68: 
        !            69:        /* Preferably allow tapes to disconnect */
        !            70:        if (BGET(scsi_might_disconnect,(unsigned char)tgt->masterno,tgt->target_id))
        !            71:                BSET(scsi_should_disconnect,(unsigned char)tgt->masterno,tgt->target_id);
        !            72: 
        !            73:        /*
        !            74:         * Dummy ior for proper sync purposes
        !            75:         */
        !            76:        io_req_alloc(ior,0);
        !            77:        ior->io_count = 0;
        !            78: 
        !            79:        /*
        !            80:         * Do a mode sense first, some drives might be picky
        !            81:         * about changing params [even if the standard might
        !            82:         * say otherwise, sigh.]
        !            83:         */
        !            84:        do {
        !            85:                ior->io_op = IO_INTERNAL;
        !            86:                ior->io_next = 0;
        !            87:                ior->io_error = 0;
        !            88:                ret = scsi_mode_sense(tgt, 0, 32, ior);
        !            89:        } while (ret == SCSI_RET_RETRY);
        !            90: 
        !            91:        mod = (scsi_mode_sense_data_t *)tgt->cmd_ptr;
        !            92:        if (scsi_debug) {
        !            93:                int     p[5];
        !            94:                bcopy((char*)mod, (char*)p, sizeof(p));
        !            95:                printf("[modsns(%x): x%x x%x x%x x%x x%x]", ret,
        !            96:                        p[0], p[1], p[2], p[3], p[4]);
        !            97:        }
        !            98:        if (ret == SCSI_RET_DEVICE_DOWN)
        !            99:                goto out;
        !           100:        if (ret == SCSI_RET_SUCCESS) {
        !           101:                tgt->dev_info.tape.read_only = mod->wp;
        !           102:                tgt->dev_info.tape.speed = mod->speed;
        !           103:                tgt->dev_info.tape.density = mod->bdesc[0].density_code;
        !           104:        } /* else they all default sensibly, using zeroes */
        !           105: 
        !           106:        /* Some tapes have limits on record-length */
        !           107: again:
        !           108:        ior->io_op = IO_INTERNAL;
        !           109:        ior->io_next = 0;
        !           110:        ior->io_error = 0;
        !           111:        ret = scsi_read_block_limits( tgt, ior);
        !           112:        if (ret == SCSI_RET_RETRY) goto again;
        !           113:        if (!ior->io_error && (ret == SCSI_RET_SUCCESS)) {
        !           114:                scsi_blimits_data_t     *lim;
        !           115:                int                     maxl;
        !           116: 
        !           117:                lim = (scsi_blimits_data_t *) tgt->cmd_ptr;
        !           118: 
        !           119:                tgt->block_size = (lim->minlen_msb << 8) |
        !           120:                                   lim->minlen_lsb;
        !           121: 
        !           122:                maxl =  (lim->maxlen_msb << 16) |
        !           123:                        (lim->maxlen_sb  <<  8) |
        !           124:                         lim->maxlen_lsb;
        !           125:                if (maxl == 0)
        !           126:                        maxl = (unsigned)-1;
        !           127:                tgt->dev_info.tape.maxreclen = maxl;
        !           128:                tgt->dev_info.tape.fixed_size = (maxl == tgt->block_size);
        !           129:        } else {
        !           130:                /* let the user worry about it */
        !           131:                /* default: tgt->block_size = 1; */
        !           132:                tgt->dev_info.tape.maxreclen = (unsigned)-1;
        !           133:                tgt->dev_info.tape.fixed_size = FALSE;
        !           134:        }
        !           135: 
        !           136:        /* Try hard to do a mode select */
        !           137:        for (i = 0; i < 5; i++) {
        !           138:                ior->io_op = IO_INTERNAL;
        !           139:                ior->io_error = 0;
        !           140:                ret = sctape_mode_select(tgt, 0, 0, FALSE, ior);
        !           141:                if (ret == SCSI_RET_SUCCESS)
        !           142:                        break;
        !           143:        }
        !           144:        if (scsi_watchdog_period < scsi_tape_timeout)
        !           145:                scsi_watchdog_period += scsi_tape_timeout;
        !           146: 
        !           147: #if 0  /* this might imply rewind, which we do not want, although yes, .. */
        !           148:        /* we want the tape loaded */
        !           149:        ior->io_op = IO_INTERNAL;
        !           150:        ior->io_next = 0;
        !           151:        ior->io_error = 0;
        !           152:        ret = scsi_start_unit(tgt, SCSI_CMD_SS_START, ior);
        !           153: #endif
        !           154:        req->io_device->bsize = tgt->block_size;
        !           155: out:
        !           156:        io_req_free(ior);
        !           157:        return ret;
        !           158: }
        !           159: 
        !           160: 
        !           161: io_return_t sctape_close(tgt)
        !           162:        target_info_t   *tgt;
        !           163: {
        !           164:        io_return_t     ret = SCSI_RET_SUCCESS;
        !           165:        io_req_t        ior;
        !           166: 
        !           167:        /*
        !           168:         * Dummy ior for proper sync purposes
        !           169:         */
        !           170:        io_req_alloc(ior,0);
        !           171:        ior->io_op = IO_INTERNAL;
        !           172:        ior->io_next = 0;
        !           173:        ior->io_count = 0;
        !           174: 
        !           175:        if (tgt->ior) printf("TAPE: Close with pending requests ?? \n");
        !           176: 
        !           177:        /* write a filemark if we xtnded/truncated the tape */
        !           178:        if (tgt->flags & TGT_WRITTEN_TO) {
        !           179:                tgt->ior = ior;
        !           180:                ior->io_error = 0;
        !           181:                ret = scsi_write_filemarks(tgt, 2, ior);
        !           182:                if (ret != SCSI_RET_SUCCESS)
        !           183:                         printf("%s%d: wfmark failed x%x\n",
        !           184:                         (*tgt->dev_ops->driver_name)(TRUE), tgt->target_id, ret);
        !           185:                /*
        !           186:                 * Don't bother repositioning if we'll rewind it
        !           187:                 */
        !           188:                if (tgt->flags & TGT_REWIND_ON_CLOSE)
        !           189:                        goto rew;
        !           190: retry:
        !           191:                tgt->ior = ior;
        !           192:                ior->io_op = IO_INTERNAL;
        !           193:                ior->io_error = 0;
        !           194:                ior->io_next = 0;
        !           195:                ret = scsi_space(tgt, SCSI_CMD_SP_FIL, -1, ior);
        !           196:                if (ret != SCSI_RET_SUCCESS) {
        !           197:                        if (ret == SCSI_RET_RETRY) {
        !           198:                                timeout(wakeup, tgt, hz);
        !           199:                                await(tgt);
        !           200:                                goto retry;
        !           201:                        }
        !           202:                        printf("%s%d: bspfile failed x%x\n",
        !           203:                         (*tgt->dev_ops->driver_name)(TRUE), tgt->target_id, ret);
        !           204:                }
        !           205:        }
        !           206: rew:
        !           207:        if (tgt->flags & TGT_REWIND_ON_CLOSE) {
        !           208:                /* Rewind tape */
        !           209:                ior->io_error = 0;
        !           210:                ior->io_op = IO_INTERNAL;
        !           211:                ior->io_error = 0;
        !           212:                tgt->ior = ior;
        !           213:                (void) scsi_rewind(tgt, ior, FALSE);
        !           214:                iowait(ior);
        !           215:                if (tgt->done == SCSI_RET_RETRY) {
        !           216:                        timeout(wakeup, tgt, 5*hz);
        !           217:                        await(tgt);
        !           218:                        goto rew;
        !           219:                }
        !           220:        }
        !           221:                io_req_free(ior);
        !           222: 
        !           223:        tgt->flags &= ~(TGT_ONLINE|TGT_WRITTEN_TO|TGT_REWIND_ON_CLOSE);
        !           224:        return ret;
        !           225: }
        !           226: 
        !           227: int sctape_strategy(ior)
        !           228:        register io_req_t       ior;
        !           229: {
        !           230:        target_info_t  *tgt;
        !           231:        register int    i = ior->io_unit;
        !           232: 
        !           233:        tgt = scsi_softc[rzcontroller(i)]->target[rzslave(i)];
        !           234: 
        !           235:        if (((ior->io_op & IO_READ) == 0) &&
        !           236:            tgt->dev_info.tape.read_only) {
        !           237:                ior->io_error = D_INVALID_OPERATION;
        !           238:                ior->io_op |= IO_ERROR;
        !           239:                ior->io_residual = ior->io_count;
        !           240:                iodone(ior);
        !           241:                return ior->io_error;
        !           242:        }
        !           243: 
        !           244:        return rz_simpleq_strategy( ior, sctape_start);
        !           245: }
        !           246: 
        !           247: static void
        !           248: do_residue(ior, sns, bsize)
        !           249:        io_req_t          ior;
        !           250:        scsi_sense_data_t *sns;
        !           251:        int               bsize;
        !           252: {
        !           253:        int residue;
        !           254: 
        !           255:        /* Not an error situation */
        !           256:        ior->io_error = 0;
        !           257:        ior->io_op &= ~IO_ERROR;
        !           258: 
        !           259:        if (!sns->addr_valid) {
        !           260:                ior->io_residual = ior->io_count;
        !           261:                return;
        !           262:        }
        !           263: 
        !           264:        residue = sns->u.xtended.info0 << 24 |
        !           265:                  sns->u.xtended.info1 << 16 |
        !           266:                  sns->u.xtended.info2 <<  8 |
        !           267:                  sns->u.xtended.info3;
        !           268:        /* fixed ? */
        !           269:        residue *= bsize;
        !           270:        /*
        !           271:         * NOTE: residue == requested - actual
        !           272:         * We only care if > 0
        !           273:         */
        !           274:        if (residue < 0) residue = 0;/* sanity */
        !           275:        ior->io_residual += residue;
        !           276: }
        !           277: 
        !           278: void sctape_start( tgt, done)
        !           279:        target_info_t   *tgt;
        !           280:        boolean_t       done;
        !           281: {
        !           282:        io_req_t                head, ior = tgt->ior;
        !           283: 
        !           284:        if (ior == 0)
        !           285:                return;
        !           286: 
        !           287:        if (done) {
        !           288: 
        !           289:                /* see if we must retry */
        !           290:                if ((tgt->done == SCSI_RET_RETRY) &&
        !           291:                    ((ior->io_op & IO_INTERNAL) == 0)) {
        !           292:                        delay(1000000);/*XXX*/
        !           293:                        goto start;
        !           294:                } else
        !           295:                /* got a bus reset ? ouch, that hurts */
        !           296:                if (tgt->done == (SCSI_RET_ABORTED|SCSI_RET_RETRY)) {
        !           297:                        /*
        !           298:                         * we really cannot retry because the tape position
        !           299:                         * is lost.
        !           300:                         */
        !           301:                        printf("Lost tape position\n");
        !           302:                        ior->io_error = D_IO_ERROR;
        !           303:                        ior->io_op |= IO_ERROR;
        !           304:                } else
        !           305: 
        !           306:                /* check completion status */
        !           307: 
        !           308:                if (tgt->cur_cmd == SCSI_CMD_REQUEST_SENSE) {
        !           309:                        scsi_sense_data_t *sns;
        !           310: 
        !           311:                        ior->io_op = ior->io_temporary;
        !           312:                        ior->io_error = D_IO_ERROR;
        !           313:                        ior->io_op |= IO_ERROR;
        !           314: 
        !           315:                        sns = (scsi_sense_data_t *)tgt->cmd_ptr;
        !           316: 
        !           317:                        if (scsi_debug)
        !           318:                                scsi_print_sense_data(sns);
        !           319: 
        !           320:                        if (scsi_check_sense_data(tgt, sns)) {
        !           321:                            if (sns->u.xtended.ili) {
        !           322:                                if (ior->io_op & IO_READ) {
        !           323:                                    do_residue(ior, sns, tgt->block_size);
        !           324:                                    if (scsi_debug)
        !           325:                                        printf("Tape Short Read (%d)\n",
        !           326:                                                ior->io_residual);
        !           327:                                }
        !           328:                            } else if (sns->u.xtended.eom) {
        !           329:                                do_residue(ior, sns, tgt->block_size);
        !           330:                                if (scsi_debug)
        !           331:                                        printf("End of Physical Tape!\n");
        !           332:                            } else if (sns->u.xtended.fm) {
        !           333:                                do_residue(ior, sns, tgt->block_size);
        !           334:                                if (scsi_debug)
        !           335:                                        printf("File Mark\n");
        !           336:                            }
        !           337:                        }
        !           338:                }
        !           339: 
        !           340:                else if (tgt->done != SCSI_RET_SUCCESS) {
        !           341: 
        !           342:                    if (tgt->done == SCSI_RET_NEED_SENSE) {
        !           343: 
        !           344:                        ior->io_temporary = ior->io_op;
        !           345:                        ior->io_op = IO_INTERNAL;
        !           346:                        if (scsi_debug)
        !           347:                                printf("[NeedSns x%x x%x]", ior->io_residual, ior->io_count);
        !           348:                        scsi_request_sense(tgt, ior, 0);
        !           349:                        return;
        !           350: 
        !           351:                    } else if (tgt->done == SCSI_RET_RETRY) {
        !           352:                        /* only retry here READs and WRITEs */
        !           353:                        if ((ior->io_op & IO_INTERNAL) == 0) {
        !           354:                                ior->io_residual = 0;
        !           355:                                goto start;
        !           356:                        } else{
        !           357:                                ior->io_error = D_WOULD_BLOCK;
        !           358:                                ior->io_op |= IO_ERROR;
        !           359:                        }
        !           360:                    } else {
        !           361:                        ior->io_error = D_IO_ERROR;
        !           362:                        ior->io_op |= IO_ERROR;
        !           363:                    }
        !           364:                }
        !           365: 
        !           366:                if (scsi_debug)
        !           367:                        printf("[Resid x%x]", ior->io_residual);
        !           368: 
        !           369:                /* dequeue next one */
        !           370:                head = ior;
        !           371: 
        !           372:                simple_lock(&tgt->target_lock);
        !           373:                ior = head->io_next;
        !           374:                tgt->ior = ior;
        !           375:                if (ior)
        !           376:                        ior->io_prev = head->io_prev;
        !           377:                simple_unlock(&tgt->target_lock);
        !           378: 
        !           379:                iodone(head);
        !           380: 
        !           381:                if (ior == 0)
        !           382:                        return;
        !           383:        }
        !           384:        ior->io_residual = 0;
        !           385: start:
        !           386:        if (ior->io_op & IO_READ) {
        !           387:                tgt->flags &= ~TGT_WRITTEN_TO;
        !           388:                sctape_read( tgt, ior );
        !           389:        } else if ((ior->io_op & IO_INTERNAL) == 0) {
        !           390:                tgt->flags |= TGT_WRITTEN_TO;
        !           391:                sctape_write( tgt, ior );
        !           392:        }
        !           393: }
        !           394: 
        !           395: io_return_t
        !           396: sctape_get_status( dev, tgt, flavor, status, status_count)
        !           397:        int             dev;
        !           398:        target_info_t   *tgt;
        !           399:        dev_flavor_t    flavor;
        !           400:        dev_status_t    status;
        !           401:        natural_t       *status_count;
        !           402: {
        !           403:        switch (flavor) {
        !           404:        case DEV_GET_SIZE:
        !           405:                
        !           406:                status[DEV_GET_SIZE_DEVICE_SIZE] = 0;
        !           407:                status[DEV_GET_SIZE_RECORD_SIZE] = tgt->block_size;
        !           408:                *status_count = DEV_GET_SIZE_COUNT;
        !           409:                break;
        !           410:        case TAPE_STATUS: {
        !           411:                struct tape_status *ts = (struct tape_status *) status;
        !           412: 
        !           413:                ts->mt_type             = MT_ISSCSI;
        !           414:                ts->speed               = tgt->dev_info.tape.speed;
        !           415:                ts->density             = tgt->dev_info.tape.density;
        !           416:                ts->flags               = (tgt->flags & TGT_REWIND_ON_CLOSE) ?
        !           417:                                                TAPE_FLG_REWIND : 0;
        !           418:                if (tgt->dev_info.tape.read_only)
        !           419:                        ts->flags |= TAPE_FLG_WP;
        !           420: #ifdef MACH_KERNEL
        !           421:                *status_count = TAPE_STATUS_COUNT;
        !           422: #endif
        !           423: 
        !           424:                break;
        !           425:            }
        !           426:        /* U*x compat */
        !           427:        case MTIOCGET: {
        !           428:                struct mtget *g = (struct mtget *) status;
        !           429: 
        !           430:                bzero(g, sizeof(struct mtget));
        !           431:                g->mt_type = 0x7;       /* Ultrix compat */
        !           432: #ifdef MACH_KERNEL
        !           433:                *status_count = sizeof(struct mtget)/sizeof(int);
        !           434: #endif
        !           435:                break;
        !           436:            }
        !           437:        default:
        !           438:                return D_INVALID_OPERATION;
        !           439:        }
        !           440:        return D_SUCCESS;
        !           441: }
        !           442: 
        !           443: io_return_t
        !           444: sctape_set_status( dev, tgt, flavor, status, status_count)
        !           445:        int             dev;
        !           446:        target_info_t   *tgt;
        !           447:        dev_flavor_t    flavor;
        !           448:        dev_status_t    status;
        !           449:        natural_t       status_count;
        !           450: {
        !           451:        scsi_ret_t              ret;
        !           452: 
        !           453:        switch (flavor) {
        !           454:        case TAPE_STATUS: {
        !           455:                struct tape_status *ts = (struct tape_status *) status;
        !           456:                if (ts->flags & TAPE_FLG_REWIND)
        !           457:                        tgt->flags |= TGT_REWIND_ON_CLOSE;
        !           458:                else
        !           459:                        tgt->flags &= ~TGT_REWIND_ON_CLOSE;
        !           460: 
        !           461:                if (ts->speed || ts->density) {
        !           462:                        unsigned int ospeed, odensity;
        !           463:                        io_req_t        ior;
        !           464: 
        !           465:                        io_req_alloc(ior,0);
        !           466:                        ior->io_op = IO_INTERNAL;
        !           467:                        ior->io_error = 0;
        !           468:                        ior->io_next = 0;
        !           469:                        ior->io_count = 0;
        !           470: 
        !           471:                        ospeed = tgt->dev_info.tape.speed;
        !           472:                        odensity = tgt->dev_info.tape.density;
        !           473:                        tgt->dev_info.tape.speed = ts->speed;
        !           474:                        tgt->dev_info.tape.density = ts->density;
        !           475: 
        !           476:                        ret = sctape_mode_select(tgt, 0, 0, (ospeed == ts->speed), ior);
        !           477:                        if (ret != SCSI_RET_SUCCESS) {
        !           478:                                tgt->dev_info.tape.speed = ospeed;
        !           479:                                tgt->dev_info.tape.density = odensity;
        !           480:                        }
        !           481: 
        !           482:                        io_req_free(ior);
        !           483:                }
        !           484: 
        !           485:                break;
        !           486:            }
        !           487:        /* U*x compat */
        !           488:        case MTIOCTOP: {
        !           489:                struct tape_params *mt = (struct tape_params *) status;
        !           490:                io_req_t        ior;
        !           491: 
        !           492:                if (scsi_debug)
        !           493:                        printf("[sctape_sstatus: %x %x %x]\n",
        !           494:                                flavor, mt->mt_operation, mt->mt_repeat_count);
        !           495: 
        !           496:                io_req_alloc(ior,0);
        !           497: retry:
        !           498:                ior->io_count = 0;
        !           499:                ior->io_op = IO_INTERNAL;
        !           500:                ior->io_error = 0;
        !           501:                ior->io_next = 0;
        !           502:                tgt->ior = ior;
        !           503: 
        !           504:                /* compat: in U*x it is a short */
        !           505:                switch ((short)(mt->mt_operation)) {
        !           506:                case MTWEOF:    /* write an end-of-file record */
        !           507:                        ret = scsi_write_filemarks(tgt, mt->mt_repeat_count, ior);
        !           508:                        break;
        !           509:                case MTFSF:     /* forward space file */
        !           510:                        ret = scsi_space(tgt, SCSI_CMD_SP_FIL, mt->mt_repeat_count, ior);
        !           511:                        break;
        !           512:                case MTBSF:     /* backward space file */
        !           513:                        ret = scsi_space(tgt, SCSI_CMD_SP_FIL, -mt->mt_repeat_count,ior);
        !           514:                        break;
        !           515:                case MTFSR:     /* forward space record */
        !           516:                        ret = scsi_space(tgt, SCSI_CMD_SP_BLOCKS, mt->mt_repeat_count, ior);
        !           517:                        break;
        !           518:                case MTBSR:     /* backward space record */
        !           519:                        ret = scsi_space(tgt, SCSI_CMD_SP_BLOCKS, -mt->mt_repeat_count, ior);
        !           520:                        break;
        !           521:                case MTREW:     /* rewind */
        !           522:                case MTOFFL:    /* rewind and put the drive offline */
        !           523:                        ret = scsi_rewind(tgt, ior, TRUE);
        !           524:                        iowait(ior);
        !           525:                        if ((short)(mt->mt_operation) == MTREW) break;
        !           526:                        ior->io_op = 0;
        !           527:                        ior->io_next = 0;
        !           528:                        ior->io_error = 0;
        !           529:                        (void) scsi_start_unit(tgt, 0, ior);
        !           530:                        break;
        !           531:                case MTNOP:     /* no operation, sets status only */
        !           532:                case MTCACHE:   /* enable controller cache */
        !           533:                case MTNOCACHE: /* disable controller cache */
        !           534:                        ret = SCSI_RET_SUCCESS;
        !           535:                        break;
        !           536:                default:
        !           537:                        tgt->ior = 0;
        !           538:                        io_req_free(ior);
        !           539:                        return D_INVALID_OPERATION;
        !           540:                }
        !           541: 
        !           542:                if (ret == SCSI_RET_RETRY) {
        !           543:                        timeout(wakeup, ior, 5*hz);
        !           544:                        await(ior);
        !           545:                        goto retry;
        !           546:                }
        !           547: 
        !           548:                io_req_free(ior);
        !           549:                if (ret != SCSI_RET_SUCCESS)
        !           550:                        return D_IO_ERROR;
        !           551:                break;
        !           552:        }
        !           553:        case MTIOCIEOT:
        !           554:        case MTIOCEEOT:
        !           555:        default:
        !           556:                return D_INVALID_OPERATION;
        !           557:        }
        !           558:        return D_SUCCESS;
        !           559: }
        !           560: #endif  /* NSCSI > 0 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.