|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.