Annotation of Gnu-Mach/scsi/scsi_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: scsi_tape.c
        !            28:  *     Author: Alessandro Forin, Carnegie Mellon University
        !            29:  *     Date:   10/90
        !            30:  *
        !            31:  *     Middle layer of the SCSI driver: SCSI protocol implementation
        !            32:  *
        !            33:  * This file contains code for SCSI commands for SEQUENTIAL ACCESS devices.
        !            34:  */
        !            35: 
        !            36: #include <mach/std_types.h>
        !            37: #include <scsi/compat_30.h>
        !            38: 
        !            39: #include <scsi/scsi.h>
        !            40: #include <scsi/scsi_defs.h>
        !            41: 
        !            42: #if  (NSCSI > 0)
        !            43: 
        !            44: 
        !            45: char *sctape_name(internal)
        !            46:        boolean_t       internal;
        !            47: {
        !            48:        return internal ? "tz" : "tape";
        !            49: }
        !            50: 
        !            51: void sctape_optimize(tgt)
        !            52:        target_info_t           *tgt;
        !            53: {
        !            54:        register int    i;
        !            55:        char            result[6];
        !            56: 
        !            57:        /* Some (DEC) tapes want to send you the self-test results */
        !            58:        for (i = 0; i < 10; i++) {
        !            59:                if (scsi_receive_diag( tgt, result, sizeof(result), 0)
        !            60:                    == SCSI_RET_SUCCESS)
        !            61:                        break;
        !            62:        }
        !            63:        if (scsi_debug)
        !            64:                printf("[tape_rcvdiag: after %d, x%x x%x x%x x%x x%x x%x]\n", i+1,
        !            65:                result[0], result[1], result[2], result[3], result[4], result[5]);
        !            66: }
        !            67: 
        !            68: /*
        !            69:  * SCSI commands specific to sequential access devices
        !            70:  */
        !            71: int sctape_mode_select( tgt, vuque_data, vuque_data_len, newspeed, ior)
        !            72:        register target_info_t  *tgt;
        !            73:        unsigned char           *vuque_data;
        !            74:        int                     vuque_data_len;
        !            75:        int                     newspeed;
        !            76:        io_req_t                ior;
        !            77: {
        !            78:        scsi_cmd_mode_select_t  *cmd;
        !            79:        scsi_mode_select_param_t        *parm;
        !            80: 
        !            81:        bzero(tgt->cmd_ptr, sizeof(*cmd) + 2 * sizeof(*parm));
        !            82:        cmd = (scsi_cmd_mode_select_t*) (tgt->cmd_ptr);
        !            83:        cmd->scsi_cmd_code = SCSI_CMD_MODE_SELECT;
        !            84:        cmd->scsi_cmd_lun_and_lba1 = 0;
        !            85:        cmd->scsi_cmd_xfer_len = sizeof(scsi_mode_select_param_t) + vuque_data_len;
        !            86: 
        !            87:        parm = (scsi_mode_select_param_t*) (cmd + 1);
        !            88:        if (newspeed) {
        !            89:                parm->speed = tgt->dev_info.tape.speed;
        !            90:        } else {
        !            91:                /* Standard sez 0 -> no change */
        !            92:                parm->speed = 0;
        !            93:        }
        !            94:        /* parm->medium_type = 0; reserved */
        !            95:        parm->descs[0].density_code = tgt->dev_info.tape.density;
        !            96:        parm->buffer_mode = 1;
        !            97:        parm->desc_len = 8;
        !            98:        if (tgt->dev_info.tape.fixed_size) {
        !            99:                register int reclen = tgt->block_size;
        !           100:                parm->descs[0].reclen1 = reclen >> 16;
        !           101:                parm->descs[0].reclen2 = reclen >>  8;
        !           102:                parm->descs[0].reclen3 = reclen;
        !           103:        }
        !           104: 
        !           105:        if (vuque_data_len)
        !           106:                bcopy(vuque_data, (char*)(parm+1), vuque_data_len);
        !           107: 
        !           108:        tgt->cur_cmd = SCSI_CMD_MODE_SELECT;
        !           109: 
        !           110:        scsi_go_and_wait(tgt, sizeof(*cmd) + sizeof(*parm) + vuque_data_len, 0, ior);
        !           111: 
        !           112:        return tgt->done;
        !           113: }
        !           114: 
        !           115: void sctape_read( tgt, ior)
        !           116:        register target_info_t  *tgt;
        !           117:        io_req_t                ior;
        !           118: {
        !           119:        scsi_cmd_read_t         *cmd;
        !           120:        register unsigned       len, max;
        !           121: #      define                  nbytes max
        !           122:        boolean_t               fixed = FALSE;
        !           123: 
        !           124:        max = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
        !           125: 
        !           126:        len = ior->io_count;
        !           127:        if (tgt->dev_info.tape.fixed_size) {
        !           128:                unsigned int bs = tgt->block_size;
        !           129:                fixed = TRUE;
        !           130:                nbytes = len;
        !           131:                ior->io_residual += len % bs;
        !           132:                len = len / bs;
        !           133:        } else {
        !           134:                if (max > tgt->dev_info.tape.maxreclen)
        !           135:                        max = tgt->dev_info.tape.maxreclen;
        !           136:                if (len > max) {
        !           137:                        ior->io_residual = len - max;
        !           138:                        len = max;
        !           139:                }
        !           140:                if (len < tgt->block_size)
        !           141:                        len = tgt->block_size;
        !           142:                nbytes = len;
        !           143:        }
        !           144: 
        !           145:        cmd = (scsi_cmd_read_t*) (tgt->cmd_ptr);
        !           146:        cmd->scsi_cmd_code = SCSI_CMD_READ;
        !           147:        cmd->scsi_cmd_lun_and_lba1 = fixed ? SCSI_CMD_TP_FIXED : 0;
        !           148:        cmd->scsi_cmd_lba2         = len >> 16;
        !           149:        cmd->scsi_cmd_lba3         = len >>  8;
        !           150:        cmd->scsi_cmd_xfer_len     = len;
        !           151:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
        !           152:        
        !           153:        tgt->cur_cmd = SCSI_CMD_READ;
        !           154: 
        !           155:        scsi_go(tgt, sizeof(*cmd), nbytes, FALSE);
        !           156: #undef nbytes
        !           157: }
        !           158: 
        !           159: void sctape_write( tgt, ior)
        !           160:        register target_info_t  *tgt;
        !           161:        io_req_t                ior;
        !           162: {
        !           163:        scsi_cmd_write_t        *cmd;
        !           164:        register unsigned       len, max;
        !           165:        boolean_t               fixed = FALSE;
        !           166: 
        !           167:        len = ior->io_count;
        !           168:        max = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
        !           169: 
        !           170:        if (tgt->dev_info.tape.fixed_size) {
        !           171:                unsigned int bs = tgt->block_size;
        !           172:                fixed = TRUE;
        !           173:                ior->io_residual += len % bs;
        !           174:                len = len / bs;
        !           175:        } else {
        !           176:                if (max > tgt->dev_info.tape.maxreclen)
        !           177:                        max = tgt->dev_info.tape.maxreclen;
        !           178:                if (len > max) {
        !           179:                        ior->io_residual = len - max;
        !           180:                        len = max;
        !           181:                }
        !           182:                if (len < tgt->block_size)
        !           183:                        len = tgt->block_size;
        !           184:        }
        !           185: 
        !           186:        cmd = (scsi_cmd_write_t*) (tgt->cmd_ptr);
        !           187:        cmd->scsi_cmd_code = SCSI_CMD_WRITE;
        !           188:        cmd->scsi_cmd_lun_and_lba1 = fixed ? SCSI_CMD_TP_FIXED : 0;
        !           189:        cmd->scsi_cmd_lba2         = len >> 16;
        !           190:        cmd->scsi_cmd_lba3         = len >>  8;
        !           191:        cmd->scsi_cmd_xfer_len     = len;
        !           192:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
        !           193:        
        !           194:        tgt->cur_cmd = SCSI_CMD_WRITE;
        !           195: 
        !           196:        scsi_go(tgt, sizeof(*cmd), 0, FALSE);
        !           197: }
        !           198: 
        !           199: int scsi_rewind( tgt, ior, wait)
        !           200:        register target_info_t  *tgt;
        !           201:        io_req_t                ior;
        !           202:        boolean_t               wait;
        !           203: {
        !           204:        scsi_cmd_rewind_t       *cmd;
        !           205: 
        !           206: 
        !           207:        cmd = (scsi_cmd_rewind_t*) (tgt->cmd_ptr);
        !           208:        cmd->scsi_cmd_code = SCSI_CMD_REWIND;
        !           209:        cmd->scsi_cmd_lun_and_lba1 = wait ? 0 : SCSI_CMD_REW_IMMED;
        !           210:        cmd->scsi_cmd_lba2         = 0;
        !           211:        cmd->scsi_cmd_lba3         = 0;
        !           212:        cmd->scsi_cmd_xfer_len     = 0;
        !           213:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
        !           214:        
        !           215:        tgt->cur_cmd = SCSI_CMD_REWIND;
        !           216: 
        !           217:        scsi_go( tgt, sizeof(*cmd), 0, FALSE);
        !           218:        return SCSI_RET_SUCCESS;
        !           219: }
        !           220: 
        !           221: int scsi_write_filemarks( tgt, count, ior)
        !           222:        register target_info_t  *tgt;
        !           223:        register unsigned int   count;
        !           224:        io_req_t                ior;
        !           225: {
        !           226:        scsi_cmd_write_fil_t    *cmd;
        !           227: 
        !           228:        cmd = (scsi_cmd_write_fil_t*) (tgt->cmd_ptr);
        !           229:        cmd->scsi_cmd_code = SCSI_CMD_WRITE_FILEMARKS;
        !           230:        cmd->scsi_cmd_lun_and_lba1 = 0;
        !           231:        cmd->scsi_cmd_lba2         = count >> 16;
        !           232:        cmd->scsi_cmd_lba3         = count >>  8;
        !           233:        cmd->scsi_cmd_xfer_len     = count;
        !           234:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
        !           235: 
        !           236: 
        !           237:        tgt->cur_cmd = SCSI_CMD_WRITE_FILEMARKS;
        !           238: 
        !           239:        scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
        !           240: 
        !           241:        return tgt->done;
        !           242: }
        !           243: 
        !           244: int scsi_space( tgt, mode, count, ior)
        !           245:        register target_info_t  *tgt;
        !           246:        int mode;
        !           247:        register int            count;
        !           248:        io_req_t                ior;
        !           249: {
        !           250:        scsi_cmd_space_t        *cmd;
        !           251: 
        !           252:        cmd = (scsi_cmd_space_t*) (tgt->cmd_ptr);
        !           253:        cmd->scsi_cmd_code = SCSI_CMD_SPACE;
        !           254:        cmd->scsi_cmd_lun_and_lba1 = mode & 0x3;
        !           255:        cmd->scsi_cmd_lba2         = count >> 16;
        !           256:        cmd->scsi_cmd_lba3         = count >>  8;
        !           257:        cmd->scsi_cmd_xfer_len     = count;
        !           258:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
        !           259: 
        !           260: 
        !           261:        tgt->cur_cmd = SCSI_CMD_SPACE;
        !           262: 
        !           263:        scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
        !           264: 
        !           265:        return tgt->done;
        !           266: }
        !           267: 
        !           268: 
        !           269: int scsi_read_block_limits( tgt, ior)
        !           270:        register target_info_t  *tgt;
        !           271:        io_req_t                ior;
        !           272: {
        !           273:        scsi_cmd_block_limits_t *cmd;
        !           274: 
        !           275:        cmd = (scsi_cmd_block_limits_t*) (tgt->cmd_ptr);
        !           276:        cmd->scsi_cmd_code = SCSI_CMD_READ_BLOCK_LIMITS;
        !           277:        cmd->scsi_cmd_lun_and_lba1 = 0;
        !           278:        cmd->scsi_cmd_lba2         = 0;
        !           279:        cmd->scsi_cmd_lba3         = 0;
        !           280:        cmd->scsi_cmd_xfer_len     = 0;
        !           281:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
        !           282: 
        !           283: 
        !           284:        tgt->cur_cmd = SCSI_CMD_READ_BLOCK_LIMITS;
        !           285: 
        !           286:        scsi_go_and_wait(tgt, sizeof(*cmd), sizeof(scsi_blimits_data_t), ior);
        !           287:        return tgt->done;
        !           288: }
        !           289: 
        !           290: #if 0 /* unused */
        !           291: 
        !           292: void scsi_track_select( tgt, trackno, ior)
        !           293:        register target_info_t  *tgt;
        !           294:        register unsigned char  trackno;
        !           295:        io_req_t                ior;
        !           296: {
        !           297:        scsi_cmd_seek_t *cmd;
        !           298: 
        !           299:        cmd = (scsi_cmd_seek_t*) (tgt->cmd_ptr);
        !           300:        cmd->scsi_cmd_code = SCSI_CMD_TRACK_SELECT;
        !           301:        cmd->scsi_cmd_lun_and_lba1 = 0;
        !           302:        cmd->scsi_cmd_lba2         = 0;
        !           303:        cmd->scsi_cmd_lba3         = 0;
        !           304:        cmd->scsi_cmd_tp_trackno   = trackno;
        !           305:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
        !           306: 
        !           307: 
        !           308:        tgt->cur_cmd = SCSI_CMD_TRACK_SELECT;
        !           309: 
        !           310:        scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
        !           311: }
        !           312: 
        !           313: void scsi_read_reverse( tgt, ior)
        !           314:        register target_info_t  *tgt;
        !           315:        io_req_t                ior;
        !           316: {
        !           317:        scsi_cmd_rev_read_t     *cmd;
        !           318:        register unsigned       len;
        !           319:        unsigned int            max_dma_data;
        !           320: 
        !           321:        max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
        !           322: 
        !           323:        len = ior->io_count;
        !           324:        if (len > max_dma_data)
        !           325:                len = max_dma_data;
        !           326: 
        !           327:        cmd = (scsi_cmd_rev_read_t*) (tgt->cmd_ptr);
        !           328:        cmd->scsi_cmd_code = SCSI_CMD_READ_REVERSE;
        !           329:        cmd->scsi_cmd_lun_and_lba1 = 0;
        !           330:        cmd->scsi_cmd_lba2         = len >> 16;
        !           331:        cmd->scsi_cmd_lba3         = len >>  8;
        !           332:        cmd->scsi_cmd_xfer_len     = len;
        !           333:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
        !           334:        
        !           335:        tgt->cur_cmd = SCSI_CMD_READ_REVERSE;
        !           336: 
        !           337:        scsi_go(tgt, sizeof(*cmd), len, FALSE);
        !           338: }
        !           339: 
        !           340: void sctape_verify( tgt, len, ior)
        !           341:        register target_info_t  *tgt;
        !           342:        register unsigned int   len;
        !           343:        io_req_t                ior;
        !           344: {
        !           345:        scsi_cmd_verify_t       *cmd;
        !           346: 
        !           347:        cmd = (scsi_cmd_verify_t*) (tgt->cmd_ptr);
        !           348:        cmd->scsi_cmd_code = SCSI_CMD_VERIFY_0;
        !           349:        cmd->scsi_cmd_lun_and_lba1 = 0;/* XXX */
        !           350:        cmd->scsi_cmd_lba2         = len >> 16;
        !           351:        cmd->scsi_cmd_lba3         = len >>  8;
        !           352:        cmd->scsi_cmd_xfer_len     = len;
        !           353:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
        !           354: 
        !           355: 
        !           356:        tgt->cur_cmd = SCSI_CMD_VERIFY_0;
        !           357: 
        !           358:        scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
        !           359: }
        !           360: 
        !           361: 
        !           362: void scsi_recover_buffered_data( tgt, ior)
        !           363:        register target_info_t  *tgt;
        !           364:        io_req_t                ior;
        !           365: {
        !           366:        scsi_cmd_recover_buffer_t       *cmd;
        !           367:        register unsigned               len;
        !           368:        unsigned int            max_dma_data;
        !           369: 
        !           370:        max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
        !           371: 
        !           372:        len = ior->io_count;
        !           373:        if (len > max_dma_data)
        !           374:                len = max_dma_data;
        !           375: 
        !           376:        cmd = (scsi_cmd_recover_buffer_t*) (tgt->cmd_ptr);
        !           377:        cmd->scsi_cmd_code = SCSI_CMD_RECOVER_BUFFERED_DATA;
        !           378:        cmd->scsi_cmd_lun_and_lba1 = 0;
        !           379:        cmd->scsi_cmd_lba2         = len >> 16;
        !           380:        cmd->scsi_cmd_lba3         = len >>  8;
        !           381:        cmd->scsi_cmd_xfer_len     = len;
        !           382:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
        !           383:        
        !           384:        tgt->cur_cmd = SCSI_CMD_RECOVER_BUFFERED_DATA;
        !           385: 
        !           386:        scsi_go(tgt, sizeof(*cmd), len, FALSE);
        !           387: }
        !           388: 
        !           389: void scsi_erase( tgt, mode, ior)
        !           390:        register target_info_t  *tgt;
        !           391:        io_req_t                ior;
        !           392: {
        !           393:        scsi_cmd_erase_t        *cmd;
        !           394: 
        !           395:        cmd = (scsi_cmd_erase_t*) (tgt->cmd_ptr);
        !           396:        cmd->scsi_cmd_code = SCSI_CMD_ERASE;
        !           397:        cmd->scsi_cmd_lun_and_lba1 = mode & SCSI_CMD_ER_LONG;
        !           398:        cmd->scsi_cmd_lba2         = 0;
        !           399:        cmd->scsi_cmd_lba3         = 0;
        !           400:        cmd->scsi_cmd_xfer_len     = 0;
        !           401:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
        !           402: 
        !           403: 
        !           404:        tgt->cur_cmd = SCSI_CMD_ERASE;
        !           405: 
        !           406:        scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
        !           407: }
        !           408: 
        !           409: #endif
        !           410: 
        !           411: #ifdef SCSI2
        !           412: scsi_locate
        !           413: scsi_read_position
        !           414: #endif SCSI2
        !           415: #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.