Annotation of Gnu-Mach/scsi/scsi_tape.c, revision 1.1.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.