• source navigation • diff markup • identifier search • freetext search •
Version: 2.6.24 2.6.25 2.6.26 2.6.27 2.6.28 2.6.29 2.6.30 2.6.31 2.6.32 2.6.33 2.6.34-rc1
Architecture: x86 arm avr32 blackfin m68k m68knommu microblaze mips powerpc sh
1 /* 2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying 3 file Documentation/scsi/st.txt for more information. 4 5 History: 6 7 OnStream SCSI Tape support (osst) cloned from st.c by 8 Willem Riede (osst@riede.org) Feb 2000 9 Fixes ... Kurt Garloff <garloff@suse.de> Mar 2000 10 11 Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara. 12 Contribution and ideas from several people including (in alphabetical 13 order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer, 14 Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale. 15 16 Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede 17 email osst@riede.org 18 19 $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $ 20 21 Microscopic alterations - Rik Ling, 2000/12/21 22 Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara 23 Some small formal changes - aeb, 950809 24 */ 25 26 static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $"; 27 static const char * osst_version = "0.99.4"; 28 29 /* The "failure to reconnect" firmware bug */ 30 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/ 31 #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/ 32 #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7) 33 34 #include <linux/module.h> 35 36 #include <linux/fs.h> 37 #include <linux/kernel.h> 38 #include <linux/sched.h> 39 #include <linux/proc_fs.h> 40 #include <linux/mm.h> 41 #include <linux/init.h> 42 #include <linux/string.h> 43 #include <linux/errno.h> 44 #include <linux/mtio.h> 45 #include <linux/ioctl.h> 46 #include <linux/fcntl.h> 47 #include <linux/spinlock.h> 48 #include <linux/vmalloc.h> 49 #include <linux/blkdev.h> 50 #include <linux/moduleparam.h> 51 #include <linux/delay.h> 52 #include <linux/jiffies.h> 53 #include <linux/smp_lock.h> 54 #include <asm/uaccess.h> 55 #include <asm/dma.h> 56 #include <asm/system.h> 57 58 /* The driver prints some debugging information on the console if DEBUG 59 is defined and non-zero. */ 60 #define DEBUG 0 61 62 /* The message level for the debug messages is currently set to KERN_NOTICE 63 so that people can easily see the messages. Later when the debugging messages 64 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */ 65 #define OSST_DEB_MSG KERN_NOTICE 66 67 #include <scsi/scsi.h> 68 #include <scsi/scsi_dbg.h> 69 #include <scsi/scsi_device.h> 70 #include <scsi/scsi_driver.h> 71 #include <scsi/scsi_eh.h> 72 #include <scsi/scsi_host.h> 73 #include <scsi/scsi_ioctl.h> 74 75 #define ST_KILOBYTE 1024 76 77 #include "st.h" 78 #include "osst.h" 79 #include "osst_options.h" 80 #include "osst_detect.h" 81 82 static int max_dev = 0; 83 static int write_threshold_kbs = 0; 84 static int max_sg_segs = 0; 85 86 #ifdef MODULE 87 MODULE_AUTHOR("Willem Riede"); 88 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver"); 89 MODULE_LICENSE("GPL"); 90 MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR); 91 MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE); 92 93 module_param(max_dev, int, 0444); 94 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)"); 95 96 module_param(write_threshold_kbs, int, 0644); 97 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)"); 98 99 module_param(max_sg_segs, int, 0644); 100 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)"); 101 #else 102 static struct osst_dev_parm { 103 char *name; 104 int *val; 105 } parms[] __initdata = { 106 { "max_dev", &max_dev }, 107 { "write_threshold_kbs", &write_threshold_kbs }, 108 { "max_sg_segs", &max_sg_segs } 109 }; 110 #endif 111 112 /* Some default definitions have been moved to osst_options.h */ 113 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE) 114 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE) 115 116 /* The buffer size should fit into the 24 bits for length in the 117 6-byte SCSI read and write commands. */ 118 #if OSST_BUFFER_SIZE >= (2 << 24 - 1) 119 #error "Buffer size should not exceed (2 << 24 - 1) bytes!" 120 #endif 121 122 #if DEBUG 123 static int debugging = 1; 124 /* uncomment define below to test error recovery */ 125 // #define OSST_INJECT_ERRORS 1 126 #endif 127 128 /* Do not retry! The drive firmware already retries when appropriate, 129 and when it tries to tell us something, we had better listen... */ 130 #define MAX_RETRIES 0 131 132 #define NO_TAPE NOT_READY 133 134 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1) 135 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12) 136 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2) 137 138 #define OSST_TIMEOUT (200 * HZ) 139 #define OSST_LONG_TIMEOUT (1800 * HZ) 140 141 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT)) 142 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT) 143 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0) 144 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1)) 145 146 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower 147 24 bits) */ 148 #define SET_DENS_AND_BLK 0x10001 149 150 static int osst_buffer_size = OSST_BUFFER_SIZE; 151 static int osst_write_threshold = OSST_WRITE_THRESHOLD; 152 static int osst_max_sg_segs = OSST_MAX_SG; 153 static int osst_max_dev = OSST_MAX_TAPES; 154 static int osst_nr_dev; 155 156 static struct osst_tape **os_scsi_tapes = NULL; 157 static DEFINE_RWLOCK(os_scsi_tapes_lock); 158 159 static int modes_defined = 0; 160 161 static struct osst_buffer *new_tape_buffer(int, int, int); 162 static int enlarge_buffer(struct osst_buffer *, int); 163 static void normalize_buffer(struct osst_buffer *); 164 static int append_to_buffer(const char __user *, struct osst_buffer *, int); 165 static int from_buffer(struct osst_buffer *, char __user *, int); 166 static int osst_zero_buffer_tail(struct osst_buffer *); 167 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *); 168 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *); 169 170 static int osst_probe(struct device *); 171 static int osst_remove(struct device *); 172 173 static struct scsi_driver osst_template = { 174 .owner = THIS_MODULE, 175 .gendrv = { 176 .name = "osst", 177 .probe = osst_probe, 178 .remove = osst_remove, 179 } 180 }; 181 182 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt, 183 unsigned int cmd_in, unsigned long arg); 184 185 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip); 186 187 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt); 188 189 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt); 190 191 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending); 192 193 static inline char *tape_name(struct osst_tape *tape) 194 { 195 return tape->drive->disk_name; 196 } 197 198 /* Routines that handle the interaction with mid-layer SCSI routines */ 199 200 201 /* Normalize Sense */ 202 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s) 203 { 204 const u8 *ucp; 205 const u8 *sense = SRpnt->sense; 206 207 s->have_sense = scsi_normalize_sense(SRpnt->sense, 208 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr); 209 s->flags = 0; 210 211 if (s->have_sense) { 212 s->deferred = 0; 213 s->remainder_valid = 214 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64); 215 switch (sense[0] & 0x7f) { 216 case 0x71: 217 s->deferred = 1; 218 case 0x70: 219 s->fixed_format = 1; 220 s->flags = sense[2] & 0xe0; 221 break; 222 case 0x73: 223 s->deferred = 1; 224 case 0x72: 225 s->fixed_format = 0; 226 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4); 227 s->flags = ucp ? (ucp[3] & 0xe0) : 0; 228 break; 229 } 230 } 231 } 232 233 /* Convert the result to success code */ 234 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt) 235 { 236 char *name = tape_name(STp); 237 int result = SRpnt->result; 238 u8 * sense = SRpnt->sense, scode; 239 #if DEBUG 240 const char *stp; 241 #endif 242 struct st_cmdstatus *cmdstatp; 243 244 if (!result) 245 return 0; 246 247 cmdstatp = &STp->buffer->cmdstat; 248 osst_analyze_sense(SRpnt, cmdstatp); 249 250 if (cmdstatp->have_sense) 251 scode = STp->buffer->cmdstat.sense_hdr.sense_key; 252 else 253 scode = 0; 254 #if DEBUG 255 if (debugging) { 256 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n", 257 name, result, 258 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2], 259 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]); 260 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n", 261 name, scode, sense[12], sense[13]); 262 if (cmdstatp->have_sense) 263 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); 264 } 265 else 266 #endif 267 if (cmdstatp->have_sense && ( 268 scode != NO_SENSE && 269 scode != RECOVERED_ERROR && 270 /* scode != UNIT_ATTENTION && */ 271 scode != BLANK_CHECK && 272 scode != VOLUME_OVERFLOW && 273 SRpnt->cmd[0] != MODE_SENSE && 274 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */ 275 if (cmdstatp->have_sense) { 276 printk(KERN_WARNING "%s:W: Command with sense data:\n", name); 277 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); 278 } 279 else { 280 static int notyetprinted = 1; 281 282 printk(KERN_WARNING 283 "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n", 284 name, result, driver_byte(result), 285 host_byte(result)); 286 if (notyetprinted) { 287 notyetprinted = 0; 288 printk(KERN_INFO 289 "%s:I: This warning may be caused by your scsi controller,\n", name); 290 printk(KERN_INFO 291 "%s:I: it has been reported with some Buslogic cards.\n", name); 292 } 293 } 294 } 295 STp->pos_unknown |= STp->device->was_reset; 296 297 if (cmdstatp->have_sense && scode == RECOVERED_ERROR) { 298 STp->recover_count++; 299 STp->recover_erreg++; 300 #if DEBUG 301 if (debugging) { 302 if (SRpnt->cmd[0] == READ_6) 303 stp = "read"; 304 else if (SRpnt->cmd[0] == WRITE_6) 305 stp = "write"; 306 else 307 stp = "ioctl"; 308 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp, 309 STp->recover_count); 310 } 311 #endif 312 if ((sense[2] & 0xe0) == 0) 313 return 0; 314 } 315 return (-EIO); 316 } 317 318 319 /* Wakeup from interrupt */ 320 static void osst_end_async(struct request *req, int update) 321 { 322 struct osst_request *SRpnt = req->end_io_data; 323 struct osst_tape *STp = SRpnt->stp; 324 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; 325 326 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors; 327 #if DEBUG 328 STp->write_pending = 0; 329 #endif 330 if (SRpnt->waiting) 331 complete(SRpnt->waiting); 332 333 if (SRpnt->bio) { 334 kfree(mdata->pages); 335 blk_rq_unmap_user(SRpnt->bio); 336 } 337 338 __blk_put_request(req->q, req); 339 } 340 341 /* osst_request memory management */ 342 static struct osst_request *osst_allocate_request(void) 343 { 344 return kzalloc(sizeof(struct osst_request), GFP_KERNEL); 345 } 346 347 static void osst_release_request(struct osst_request *streq) 348 { 349 kfree(streq); 350 } 351 352 static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd, 353 int cmd_len, int data_direction, void *buffer, unsigned bufflen, 354 int use_sg, int timeout, int retries) 355 { 356 struct request *req; 357 struct page **pages = NULL; 358 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; 359 360 int err = 0; 361 int write = (data_direction == DMA_TO_DEVICE); 362 363 req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL); 364 if (!req) 365 return DRIVER_ERROR << 24; 366 367 req->cmd_type = REQ_TYPE_BLOCK_PC; 368 req->cmd_flags |= REQ_QUIET; 369 370 SRpnt->bio = NULL; 371 372 if (use_sg) { 373 struct scatterlist *sg, *sgl = (struct scatterlist *)buffer; 374 int i; 375 376 pages = kzalloc(use_sg * sizeof(struct page *), GFP_KERNEL); 377 if (!pages) 378 goto free_req; 379 380 for_each_sg(sgl, sg, use_sg, i) 381 pages[i] = sg_page(sg); 382 383 mdata->null_mapped = 1; 384 385 mdata->page_order = get_order(sgl[0].length); 386 mdata->nr_entries = 387 DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order); 388 mdata->offset = 0; 389 390 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL); 391 if (err) { 392 kfree(pages); 393 goto free_req; 394 } 395 SRpnt->bio = req->bio; 396 mdata->pages = pages; 397 398 } else if (bufflen) { 399 err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL); 400 if (err) 401 goto free_req; 402 } 403 404 req->cmd_len = cmd_len; 405 memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ 406 memcpy(req->cmd, cmd, req->cmd_len); 407 req->sense = SRpnt->sense; 408 req->sense_len = 0; 409 req->timeout = timeout; 410 req->retries = retries; 411 req->end_io_data = SRpnt; 412 413 blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async); 414 return 0; 415 free_req: 416 blk_put_request(req); 417 return DRIVER_ERROR << 24; 418 } 419 420 /* Do the scsi command. Waits until command performed if do_wait is true. 421 Otherwise osst_write_behind_check() is used to check that the command 422 has finished. */ 423 static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp, 424 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait) 425 { 426 unsigned char *bp; 427 unsigned short use_sg; 428 #ifdef OSST_INJECT_ERRORS 429 static int inject = 0; 430 static int repeat = 0; 431 #endif 432 struct completion *waiting; 433 434 /* if async, make sure there's no command outstanding */ 435 if (!do_wait && ((STp->buffer)->last_SRpnt)) { 436 printk(KERN_ERR "%s: Async command already active.\n", 437 tape_name(STp)); 438 if (signal_pending(current)) 439 (STp->buffer)->syscall_result = (-EINTR); 440 else 441 (STp->buffer)->syscall_result = (-EBUSY); 442 return NULL; 443 } 444 445 if (SRpnt == NULL) { 446 SRpnt = osst_allocate_request(); 447 if (SRpnt == NULL) { 448 printk(KERN_ERR "%s: Can't allocate SCSI request.\n", 449 tape_name(STp)); 450 if (signal_pending(current)) 451 (STp->buffer)->syscall_result = (-EINTR); 452 else 453 (STp->buffer)->syscall_result = (-EBUSY); 454 return NULL; 455 } 456 SRpnt->stp = STp; 457 } 458 459 /* If async IO, set last_SRpnt. This ptr tells write_behind_check 460 which IO is outstanding. It's nulled out when the IO completes. */ 461 if (!do_wait) 462 (STp->buffer)->last_SRpnt = SRpnt; 463 464 waiting = &STp->wait; 465 init_completion(waiting); 466 SRpnt->waiting = waiting; 467 468 use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0; 469 if (use_sg) { 470 bp = (char *)&(STp->buffer->sg[0]); 471 if (STp->buffer->sg_segs < use_sg) 472 use_sg = STp->buffer->sg_segs; 473 } 474 else 475 bp = (STp->buffer)->b_data; 476 477 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd)); 478 STp->buffer->cmdstat.have_sense = 0; 479 STp->buffer->syscall_result = 0; 480 481 if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes, 482 use_sg, timeout, retries)) 483 /* could not allocate the buffer or request was too large */ 484 (STp->buffer)->syscall_result = (-EBUSY); 485 else if (do_wait) { 486 wait_for_completion(waiting); 487 SRpnt->waiting = NULL; 488 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt); 489 #ifdef OSST_INJECT_ERRORS 490 if (STp->buffer->syscall_result == 0 && 491 cmd[0] == READ_6 && 492 cmd[4] && 493 ( (++ inject % 83) == 29 || 494 (STp->first_frame_position == 240 495 /* or STp->read_error_frame to fail again on the block calculated above */ && 496 ++repeat < 3))) { 497 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp)); 498 STp->buffer->last_result_fatal = 1; 499 } 500 #endif 501 } 502 return SRpnt; 503 } 504 505 506 /* Handle the write-behind checking (downs the semaphore) */ 507 static void osst_write_behind_check(struct osst_tape *STp) 508 { 509 struct osst_buffer * STbuffer; 510 511 STbuffer = STp->buffer; 512 513 #if DEBUG 514 if (STp->write_pending) 515 STp->nbr_waits++; 516 else 517 STp->nbr_finished++; 518 #endif 519 wait_for_completion(&(STp->wait)); 520 STp->buffer->last_SRpnt->waiting = NULL; 521 522 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt); 523 524 if (STp->buffer->syscall_result) 525 STp->buffer->syscall_result = 526 osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1); 527 else 528 STp->first_frame_position++; 529 530 osst_release_request(STp->buffer->last_SRpnt); 531 532 if (STbuffer->writing < STbuffer->buffer_bytes) 533 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n"); 534 535 STbuffer->last_SRpnt = NULL; 536 STbuffer->buffer_bytes -= STbuffer->writing; 537 STbuffer->writing = 0; 538 539 return; 540 } 541 542 543 544 /* Onstream specific Routines */ 545 /* 546 * Initialize the OnStream AUX 547 */ 548 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number, 549 int logical_blk_num, int blk_sz, int blk_cnt) 550 { 551 os_aux_t *aux = STp->buffer->aux; 552 os_partition_t *par = &aux->partition; 553 os_dat_t *dat = &aux->dat; 554 555 if (STp->raw) return; 556 557 memset(aux, 0, sizeof(*aux)); 558 aux->format_id = htonl(0); 559 memcpy(aux->application_sig, "LIN4", 4); 560 aux->hdwr = htonl(0); 561 aux->frame_type = frame_type; 562 563 switch (frame_type) { 564 case OS_FRAME_TYPE_HEADER: 565 aux->update_frame_cntr = htonl(STp->update_frame_cntr); 566 par->partition_num = OS_CONFIG_PARTITION; 567 par->par_desc_ver = OS_PARTITION_VERSION; 568 par->wrt_pass_cntr = htons(0xffff); 569 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */ 570 par->first_frame_ppos = htonl(0); 571 par->last_frame_ppos = htonl(0xbb7); 572 aux->frame_seq_num = htonl(0); 573 aux->logical_blk_num_high = htonl(0); 574 aux->logical_blk_num = htonl(0); 575 aux->next_mark_ppos = htonl(STp->first_mark_ppos); 576 break; 577 case OS_FRAME_TYPE_DATA: 578 case OS_FRAME_TYPE_MARKER: 579 dat->dat_sz = 8; 580 dat->reserved1 = 0; 581 dat->entry_cnt = 1; 582 dat->reserved3 = 0; 583 dat->dat_list[0].blk_sz = htonl(blk_sz); 584 dat->dat_list[0].blk_cnt = htons(blk_cnt); 585 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER? 586 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA; 587 dat->dat_list[0].reserved = 0; 588 case OS_FRAME_TYPE_EOD: 589 aux->update_frame_cntr = htonl(0); 590 par->partition_num = OS_DATA_PARTITION; 591 par->par_desc_ver = OS_PARTITION_VERSION; 592 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr); 593 par->first_frame_ppos = htonl(STp->first_data_ppos); 594 par->last_frame_ppos = htonl(STp->capacity); 595 aux->frame_seq_num = htonl(frame_seq_number); 596 aux->logical_blk_num_high = htonl(0); 597 aux->logical_blk_num = htonl(logical_blk_num); 598 break; 599 default: ; /* probably FILL */ 600 } 601 aux->filemark_cnt = htonl(STp->filemark_cnt); 602 aux->phys_fm = htonl(0xffffffff); 603 aux->last_mark_ppos = htonl(STp->last_mark_ppos); 604 aux->last_mark_lbn = htonl(STp->last_mark_lbn); 605 } 606 607 /* 608 * Verify that we have the correct tape frame 609 */ 610 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet) 611 { 612 char * name = tape_name(STp); 613 os_aux_t * aux = STp->buffer->aux; 614 os_partition_t * par = &(aux->partition); 615 struct st_partstat * STps = &(STp->ps[STp->partition]); 616 int blk_cnt, blk_sz, i; 617 618 if (STp->raw) { 619 if (STp->buffer->syscall_result) { 620 for (i=0; i < STp->buffer->sg_segs; i++) 621 memset(page_address(sg_page(&STp->buffer->sg[i])), 622 0, STp->buffer->sg[i].length); 623 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME"); 624 } else 625 STp->buffer->buffer_bytes = OS_FRAME_SIZE; 626 return 1; 627 } 628 if (STp->buffer->syscall_result) { 629 #if DEBUG 630 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name); 631 #endif 632 return 0; 633 } 634 if (ntohl(aux->format_id) != 0) { 635 #if DEBUG 636 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id)); 637 #endif 638 goto err_out; 639 } 640 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 && 641 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) { 642 #if DEBUG 643 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name); 644 #endif 645 goto err_out; 646 } 647 if (par->partition_num != OS_DATA_PARTITION) { 648 if (!STp->linux_media || STp->linux_media_version != 2) { 649 #if DEBUG 650 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n", 651 name, par->partition_num); 652 #endif 653 goto err_out; 654 } 655 } 656 if (par->par_desc_ver != OS_PARTITION_VERSION) { 657 #if DEBUG 658 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver); 659 #endif 660 goto err_out; 661 } 662 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) { 663 #if DEBUG 664 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n", 665 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr); 666 #endif 667 goto err_out; 668 } 669 if (aux->frame_type != OS_FRAME_TYPE_DATA && 670 aux->frame_type != OS_FRAME_TYPE_EOD && 671 aux->frame_type != OS_FRAME_TYPE_MARKER) { 672 if (!quiet) { 673 #if DEBUG 674 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type); 675 #endif 676 } 677 goto err_out; 678 } 679 if (aux->frame_type == OS_FRAME_TYPE_EOD && 680 STp->first_frame_position < STp->eod_frame_ppos) { 681 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name, 682 STp->first_frame_position); 683 goto err_out; 684 } 685 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) { 686 if (!quiet) { 687 #if DEBUG 688 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n", 689 name, ntohl(aux->frame_seq_num), frame_seq_number); 690 #endif 691 } 692 goto err_out; 693 } 694 if (aux->frame_type == OS_FRAME_TYPE_MARKER) { 695 STps->eof = ST_FM_HIT; 696 697 i = ntohl(aux->filemark_cnt); 698 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt || 699 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) { 700 #if DEBUG 701 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name, 702 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected", 703 i, STp->first_frame_position - 1); 704 #endif 705 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1); 706 if (i >= STp->filemark_cnt) 707 STp->filemark_cnt = i+1; 708 } 709 } 710 if (aux->frame_type == OS_FRAME_TYPE_EOD) { 711 STps->eof = ST_EOD_1; 712 STp->frame_in_buffer = 1; 713 } 714 if (aux->frame_type == OS_FRAME_TYPE_DATA) { 715 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt); 716 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz); 717 STp->buffer->buffer_bytes = blk_cnt * blk_sz; 718 STp->buffer->read_pointer = 0; 719 STp->frame_in_buffer = 1; 720 721 /* See what block size was used to write file */ 722 if (STp->block_size != blk_sz && blk_sz > 0) { 723 printk(KERN_INFO 724 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n", 725 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k', 726 STp->block_size<1024?STp->block_size:STp->block_size/1024, 727 STp->block_size<1024?'b':'k'); 728 STp->block_size = blk_sz; 729 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz; 730 } 731 STps->eof = ST_NOEOF; 732 } 733 STp->frame_seq_number = ntohl(aux->frame_seq_num); 734 STp->logical_blk_num = ntohl(aux->logical_blk_num); 735 return 1; 736 737 err_out: 738 if (STp->read_error_frame == 0) 739 STp->read_error_frame = STp->first_frame_position - 1; 740 return 0; 741 } 742 743 /* 744 * Wait for the unit to become Ready 745 */ 746 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt, 747 unsigned timeout, int initial_delay) 748 { 749 unsigned char cmd[MAX_COMMAND_SIZE]; 750 struct osst_request * SRpnt; 751 unsigned long startwait = jiffies; 752 #if DEBUG 753 int dbg = debugging; 754 char * name = tape_name(STp); 755 756 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name); 757 #endif 758 759 if (initial_delay > 0) 760 msleep(jiffies_to_msecs(initial_delay)); 761 762 memset(cmd, 0, MAX_COMMAND_SIZE); 763 cmd[0] = TEST_UNIT_READY; 764 765 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 766 *aSRpnt = SRpnt; 767 if (!SRpnt) return (-EBUSY); 768 769 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) && 770 (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 && 771 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) || 772 ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 && 773 SRpnt->sense[13] == 0 ) )) { 774 #if DEBUG 775 if (debugging) { 776 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name); 777 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 778 debugging = 0; 779 } 780 #endif 781 msleep(100); 782 783 memset(cmd, 0, MAX_COMMAND_SIZE); 784 cmd[0] = TEST_UNIT_READY; 785 786 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 787 } 788 *aSRpnt = SRpnt; 789 #if DEBUG 790 debugging = dbg; 791 #endif 792 if ( STp->buffer->syscall_result && 793 osst_write_error_recovery(STp, aSRpnt, 0) ) { 794 #if DEBUG 795 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name); 796 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name, 797 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2], 798 SRpnt->sense[12], SRpnt->sense[13]); 799 #endif 800 return (-EIO); 801 } 802 #if DEBUG 803 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name); 804 #endif 805 return 0; 806 } 807 808 /* 809 * Wait for a tape to be inserted in the unit 810 */ 811 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout) 812 { 813 unsigned char cmd[MAX_COMMAND_SIZE]; 814 struct osst_request * SRpnt; 815 unsigned long startwait = jiffies; 816 #if DEBUG 817 int dbg = debugging; 818 char * name = tape_name(STp); 819 820 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name); 821 #endif 822 823 memset(cmd, 0, MAX_COMMAND_SIZE); 824 cmd[0] = TEST_UNIT_READY; 825 826 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 827 *aSRpnt = SRpnt; 828 if (!SRpnt) return (-EBUSY); 829 830 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) && 831 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) { 832 #if DEBUG 833 if (debugging) { 834 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name); 835 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 836 debugging = 0; 837 } 838 #endif 839 msleep(100); 840 841 memset(cmd, 0, MAX_COMMAND_SIZE); 842 cmd[0] = TEST_UNIT_READY; 843 844 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 845 } 846 *aSRpnt = SRpnt; 847 #if DEBUG 848 debugging = dbg; 849 #endif 850 if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 && 851 SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) { 852 #if DEBUG 853 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name); 854 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name, 855 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2], 856 SRpnt->sense[12], SRpnt->sense[13]); 857 #endif 858 return 0; 859 } 860 #if DEBUG 861 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name); 862 #endif 863 return 1; 864 } 865 866 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame) 867 { 868 int retval; 869 870 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */ 871 retval = osst_set_frame_position(STp, aSRpnt, frame, 0); 872 if (retval) return (retval); 873 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE); 874 return (osst_get_frame_position(STp, aSRpnt)); 875 } 876 877 /* 878 * Wait for write(s) to complete 879 */ 880 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt) 881 { 882 unsigned char cmd[MAX_COMMAND_SIZE]; 883 struct osst_request * SRpnt; 884 int result = 0; 885 int delay = OSST_WAIT_WRITE_COMPLETE; 886 #if DEBUG 887 char * name = tape_name(STp); 888 889 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name); 890 #endif 891 892 memset(cmd, 0, MAX_COMMAND_SIZE); 893 cmd[0] = WRITE_FILEMARKS; 894 cmd[1] = 1; 895 896 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 897 *aSRpnt = SRpnt; 898 if (!SRpnt) return (-EBUSY); 899 if (STp->buffer->syscall_result) { 900 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) { 901 if (SRpnt->sense[13] == 8) { 902 delay = OSST_WAIT_LONG_WRITE_COMPLETE; 903 } 904 } else 905 result = osst_write_error_recovery(STp, aSRpnt, 0); 906 } 907 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay); 908 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE; 909 910 return (result); 911 } 912 913 #define OSST_POLL_PER_SEC 10 914 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to) 915 { 916 unsigned long startwait = jiffies; 917 char * name = tape_name(STp); 918 #if DEBUG 919 char notyetprinted = 1; 920 #endif 921 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING) 922 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name); 923 924 while (time_before (jiffies, startwait + to*HZ)) 925 { 926 int result; 927 result = osst_get_frame_position(STp, aSRpnt); 928 if (result == -EIO) 929 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0) 930 return 0; /* successful recovery leaves drive ready for frame */ 931 if (result < 0) break; 932 if (STp->first_frame_position == curr && 933 ((minlast < 0 && 934 (signed)STp->last_frame_position > (signed)curr + minlast) || 935 (minlast >= 0 && STp->cur_frames > minlast) 936 ) && result >= 0) 937 { 938 #if DEBUG 939 if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC)) 940 printk (OSST_DEB_MSG 941 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n", 942 name, curr, curr+minlast, STp->first_frame_position, 943 STp->last_frame_position, STp->cur_frames, 944 result, (jiffies-startwait)/HZ, 945 (((jiffies-startwait)%HZ)*10)/HZ); 946 #endif 947 return 0; 948 } 949 #if DEBUG 950 if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted) 951 { 952 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n", 953 name, curr, curr+minlast, STp->first_frame_position, 954 STp->last_frame_position, STp->cur_frames, result); 955 notyetprinted--; 956 } 957 #endif 958 msleep(1000 / OSST_POLL_PER_SEC); 959 } 960 #if DEBUG 961 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n", 962 name, curr, curr+minlast, STp->first_frame_position, 963 STp->last_frame_position, STp->cur_frames, 964 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ); 965 #endif 966 return -EBUSY; 967 } 968 969 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing) 970 { 971 struct osst_request * SRpnt; 972 unsigned char cmd[MAX_COMMAND_SIZE]; 973 unsigned long startwait = jiffies; 974 int retval = 1; 975 char * name = tape_name(STp); 976 977 if (writing) { 978 char mybuf[24]; 979 char * olddata = STp->buffer->b_data; 980 int oldsize = STp->buffer->buffer_size; 981 982 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */ 983 984 memset(cmd, 0, MAX_COMMAND_SIZE); 985 cmd[0] = WRITE_FILEMARKS; 986 cmd[1] = 1; 987 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, 988 MAX_RETRIES, 1); 989 990 while (retval && time_before (jiffies, startwait + 5*60*HZ)) { 991 992 if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) { 993 994 /* some failure - not just not-ready */ 995 retval = osst_write_error_recovery(STp, aSRpnt, 0); 996 break; 997 } 998 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC); 999 1000 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; 1001 memset(cmd, 0, MAX_COMMAND_SIZE); 1002 cmd[0] = READ_POSITION; 1003 1004 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout, 1005 MAX_RETRIES, 1); 1006 1007 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 ); 1008 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; 1009 } 1010 if (retval) 1011 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name); 1012 } else 1013 /* TODO - figure out which error conditions can be handled */ 1014 if (STp->buffer->syscall_result) 1015 printk(KERN_WARNING 1016 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name, 1017 (*aSRpnt)->sense[ 2] & 0x0f, 1018 (*aSRpnt)->sense[12], 1019 (*aSRpnt)->sense[13]); 1020 1021 return retval; 1022 } 1023 1024 /* 1025 * Read the next OnStream tape frame at the current location 1026 */ 1027 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout) 1028 { 1029 unsigned char cmd[MAX_COMMAND_SIZE]; 1030 struct osst_request * SRpnt; 1031 int retval = 0; 1032 #if DEBUG 1033 os_aux_t * aux = STp->buffer->aux; 1034 char * name = tape_name(STp); 1035 #endif 1036 1037 if (STp->poll) 1038 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout)) 1039 retval = osst_recover_wait_frame(STp, aSRpnt, 0); 1040 1041 memset(cmd, 0, MAX_COMMAND_SIZE); 1042 cmd[0] = READ_6; 1043 cmd[1] = 1; 1044 cmd[4] = 1; 1045 1046 #if DEBUG 1047 if (debugging) 1048 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name); 1049 #endif 1050 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE, 1051 STp->timeout, MAX_RETRIES, 1); 1052 *aSRpnt = SRpnt; 1053 if (!SRpnt) 1054 return (-EBUSY); 1055 1056 if ((STp->buffer)->syscall_result) { 1057 retval = 1; 1058 if (STp->read_error_frame == 0) { 1059 STp->read_error_frame = STp->first_frame_position; 1060 #if DEBUG 1061 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame); 1062 #endif 1063 } 1064 #if DEBUG 1065 if (debugging) 1066 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", 1067 name, 1068 SRpnt->sense[0], SRpnt->sense[1], 1069 SRpnt->sense[2], SRpnt->sense[3], 1070 SRpnt->sense[4], SRpnt->sense[5], 1071 SRpnt->sense[6], SRpnt->sense[7]); 1072 #endif 1073 } 1074 else 1075 STp->first_frame_position++; 1076 #if DEBUG 1077 if (debugging) { 1078 char sig[8]; int i; 1079 for (i=0;i<4;i++) 1080 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i]; 1081 sig[4] = '\0'; 1082 printk(OSST_DEB_MSG 1083 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig, 1084 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr), 1085 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK": 1086 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL", 1087 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num), 1088 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) ); 1089 if (aux->frame_type==2) 1090 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name, 1091 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn)); 1092 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval); 1093 } 1094 #endif 1095 return (retval); 1096 } 1097 1098 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt) 1099 { 1100 struct st_partstat * STps = &(STp->ps[STp->partition]); 1101 struct osst_request * SRpnt ; 1102 unsigned char cmd[MAX_COMMAND_SIZE]; 1103 int retval = 0; 1104 char * name = tape_name(STp); 1105 1106 if (STps->rw != ST_READING) { /* Initialize read operation */ 1107 if (STps->rw == ST_WRITING || STp->dirty) { 1108 STp->write_type = OS_WRITE_DATA; 1109 osst_flush_write_buffer(STp, aSRpnt); 1110 osst_flush_drive_buffer(STp, aSRpnt); 1111 } 1112 STps->rw = ST_READING; 1113 STp->frame_in_buffer = 0; 1114 1115 /* 1116 * Issue a read 0 command to get the OnStream drive 1117 * read frames into its buffer. 1118 */ 1119 memset(cmd, 0, MAX_COMMAND_SIZE); 1120 cmd[0] = READ_6; 1121 cmd[1] = 1; 1122 1123 #if DEBUG 1124 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name); 1125 #endif 1126 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 1127 *aSRpnt = SRpnt; 1128 if ((retval = STp->buffer->syscall_result)) 1129 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name); 1130 } 1131 1132 return retval; 1133 } 1134 1135 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, 1136 int frame_seq_number, int quiet) 1137 { 1138 struct st_partstat * STps = &(STp->ps[STp->partition]); 1139 char * name = tape_name(STp); 1140 int cnt = 0, 1141 bad = 0, 1142 past = 0, 1143 x, 1144 position; 1145 1146 /* 1147 * If we want just any frame (-1) and there is a frame in the buffer, return it 1148 */ 1149 if (frame_seq_number == -1 && STp->frame_in_buffer) { 1150 #if DEBUG 1151 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number); 1152 #endif 1153 return (STps->eof); 1154 } 1155 /* 1156 * Search and wait for the next logical tape frame 1157 */ 1158 while (1) { 1159 if (cnt++ > 400) { 1160 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n", 1161 name, frame_seq_number); 1162 if (STp->read_error_frame) { 1163 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0); 1164 #if DEBUG 1165 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n", 1166 name, STp->read_error_frame); 1167 #endif 1168 STp->read_error_frame = 0; 1169 STp->abort_count++; 1170 } 1171 return (-EIO); 1172 } 1173 #if DEBUG 1174 if (debugging) 1175 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n", 1176 name, frame_seq_number, cnt); 1177 #endif 1178 if ( osst_initiate_read(STp, aSRpnt) 1179 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) { 1180 if (STp->raw) 1181 return (-EIO); 1182 position = osst_get_frame_position(STp, aSRpnt); 1183 if (position >= 0xbae && position < 0xbb8) 1184 position = 0xbb8; 1185 else if (position > STp->eod_frame_ppos || ++bad == 10) { 1186 position = STp->read_error_frame - 1; 1187 bad = 0; 1188 } 1189 else { 1190 position += 29; 1191 cnt += 19; 1192 } 1193 #if DEBUG 1194 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n", 1195 name, position); 1196 #endif 1197 osst_set_frame_position(STp, aSRpnt, position, 0); 1198 continue; 1199 } 1200 if (osst_verify_frame(STp, frame_seq_number, quiet)) 1201 break; 1202 if (osst_verify_frame(STp, -1, quiet)) { 1203 x = ntohl(STp->buffer->aux->frame_seq_num); 1204 if (STp->fast_open) { 1205 printk(KERN_WARNING 1206 "%s:W: Found logical frame %d instead of %d after fast open\n", 1207 name, x, frame_seq_number); 1208 STp->header_ok = 0; 1209 STp->read_error_frame = 0; 1210 return (-EIO); 1211 } 1212 if (x > frame_seq_number) { 1213 if (++past > 3) { 1214 /* positioning backwards did not bring us to the desired frame */ 1215 position = STp->read_error_frame - 1; 1216 } 1217 else { 1218 position = osst_get_frame_position(STp, aSRpnt) 1219 + frame_seq_number - x - 1; 1220 1221 if (STp->first_frame_position >= 3000 && position < 3000) 1222 position -= 10; 1223 } 1224 #if DEBUG 1225 printk(OSST_DEB_MSG 1226 "%s:D: Found logical frame %d while looking for %d: back up %d\n", 1227 name, x, frame_seq_number, 1228 STp->first_frame_position - position); 1229 #endif 1230 osst_set_frame_position(STp, aSRpnt, position, 0); 1231 cnt += 10; 1232 } 1233 else 1234 past = 0; 1235 } 1236 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) { 1237 #if DEBUG 1238 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name); 1239 #endif 1240 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0); 1241 cnt--; 1242 } 1243 STp->frame_in_buffer = 0; 1244 } 1245 if (cnt > 1) { 1246 STp->recover_count++; 1247 STp->recover_erreg++; 1248 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n", 1249 name, STp->read_error_frame); 1250 } 1251 STp->read_count++; 1252 1253 #if DEBUG 1254 if (debugging || STps->eof) 1255 printk(OSST_DEB_MSG 1256 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n", 1257 name, frame_seq_number, STp->frame_seq_number, STps->eof); 1258 #endif 1259 STp->fast_open = 0; 1260 STp->read_error_frame = 0; 1261 return (STps->eof); 1262 } 1263 1264 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num) 1265 { 1266 struct st_partstat * STps = &(STp->ps[STp->partition]); 1267 char * name = tape_name(STp); 1268 int retries = 0; 1269 int frame_seq_estimate, ppos_estimate, move; 1270 1271 if (logical_blk_num < 0) logical_blk_num = 0; 1272 #if DEBUG 1273 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n", 1274 name, logical_blk_num, STp->logical_blk_num, 1275 STp->block_size<1024?STp->block_size:STp->block_size/1024, 1276 STp->block_size<1024?'b':'k'); 1277 #endif 1278 /* Do we know where we are? */ 1279 if (STps->drv_block >= 0) { 1280 move = logical_blk_num - STp->logical_blk_num; 1281 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; 1282 move /= (OS_DATA_SIZE / STp->block_size); 1283 frame_seq_estimate = STp->frame_seq_number + move; 1284 } else 1285 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE; 1286 1287 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10; 1288 else ppos_estimate = frame_seq_estimate + 20; 1289 while (++retries < 10) { 1290 if (ppos_estimate > STp->eod_frame_ppos-2) { 1291 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate; 1292 ppos_estimate = STp->eod_frame_ppos - 2; 1293 } 1294 if (frame_seq_estimate < 0) { 1295 frame_seq_estimate = 0; 1296 ppos_estimate = 10; 1297 } 1298 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0); 1299 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) { 1300 /* we've located the estimated frame, now does it have our block? */ 1301 if (logical_blk_num < STp->logical_blk_num || 1302 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) { 1303 if (STps->eof == ST_FM_HIT) 1304 move = logical_blk_num < STp->logical_blk_num? -2 : 1; 1305 else { 1306 move = logical_blk_num - STp->logical_blk_num; 1307 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; 1308 move /= (OS_DATA_SIZE / STp->block_size); 1309 } 1310 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1; 1311 #if DEBUG 1312 printk(OSST_DEB_MSG 1313 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n", 1314 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 1315 STp->logical_blk_num, logical_blk_num, move); 1316 #endif 1317 frame_seq_estimate += move; 1318 ppos_estimate += move; 1319 continue; 1320 } else { 1321 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size; 1322 STp->buffer->buffer_bytes -= STp->buffer->read_pointer; 1323 STp->logical_blk_num = logical_blk_num; 1324 #if DEBUG 1325 printk(OSST_DEB_MSG 1326 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n", 1327 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer, 1328 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size, 1329 STp->block_size); 1330 #endif 1331 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt); 1332 if (STps->eof == ST_FM_HIT) { 1333 STps->drv_file++; 1334 STps->drv_block = 0; 1335 } else { 1336 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)? 1337 STp->logical_blk_num - 1338 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0): 1339 -1; 1340 } 1341 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF; 1342 return 0; 1343 } 1344 } 1345 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0) 1346 goto error; 1347 /* we are not yet at the estimated frame, adjust our estimate of its physical position */ 1348 #if DEBUG 1349 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n", 1350 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 1351 STp->logical_blk_num, logical_blk_num); 1352 #endif 1353 if (frame_seq_estimate != STp->frame_seq_number) 1354 ppos_estimate += frame_seq_estimate - STp->frame_seq_number; 1355 else 1356 break; 1357 } 1358 error: 1359 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n", 1360 name, logical_blk_num, STp->logical_blk_num, retries); 1361 return (-EIO); 1362 } 1363 1364 /* The values below are based on the OnStream frame payload size of 32K == 2**15, 1365 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block 1366 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions 1367 * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1. 1368 */ 1369 #define OSST_FRAME_SHIFT 6 1370 #define OSST_SECTOR_SHIFT 9 1371 #define OSST_SECTOR_MASK 0x03F 1372 1373 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt) 1374 { 1375 int sector; 1376 #if DEBUG 1377 char * name = tape_name(STp); 1378 1379 printk(OSST_DEB_MSG 1380 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n", 1381 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num, 1382 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block, 1383 STp->ps[STp->partition].rw == ST_WRITING?'w':'r', 1384 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes: 1385 STp->buffer->read_pointer, STp->ps[STp->partition].eof); 1386 #endif 1387 /* do we know where we are inside a file? */ 1388 if (STp->ps[STp->partition].drv_block >= 0) { 1389 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 : 1390 STp->first_frame_position) << OSST_FRAME_SHIFT; 1391 if (STp->ps[STp->partition].rw == ST_WRITING) 1392 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK; 1393 else 1394 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK; 1395 } else { 1396 sector = osst_get_frame_position(STp, aSRpnt); 1397 if (sector > 0) 1398 sector <<= OSST_FRAME_SHIFT; 1399 } 1400 return sector; 1401 } 1402 1403 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector) 1404 { 1405 struct st_partstat * STps = &(STp->ps[STp->partition]); 1406 int frame = sector >> OSST_FRAME_SHIFT, 1407 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 1408 r; 1409 #if DEBUG 1410 char * name = tape_name(STp); 1411 1412 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n", 1413 name, sector, frame, offset); 1414 #endif 1415 if (frame < 0 || frame >= STp->capacity) return (-ENXIO); 1416 1417 if (frame <= STp->first_data_ppos) { 1418 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0; 1419 return (osst_set_frame_position(STp, aSRpnt, frame, 0)); 1420 } 1421 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0); 1422 if (r < 0) return r; 1423 1424 r = osst_get_logical_frame(STp, aSRpnt, -1, 1); 1425 if (r < 0) return r; 1426 1427 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO); 1428 1429 if (offset) { 1430 STp->logical_blk_num += offset / STp->block_size; 1431 STp->buffer->read_pointer = offset; 1432 STp->buffer->buffer_bytes -= offset; 1433 } else { 1434 STp->frame_seq_number++; 1435 STp->frame_in_buffer = 0; 1436 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1437 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0; 1438 } 1439 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt); 1440 if (STps->eof == ST_FM_HIT) { 1441 STps->drv_file++; 1442 STps->drv_block = 0; 1443 } else { 1444 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)? 1445 STp->logical_blk_num - 1446 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0): 1447 -1; 1448 } 1449 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF; 1450 #if DEBUG 1451 printk(OSST_DEB_MSG 1452 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n", 1453 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num, 1454 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof); 1455 #endif 1456 return 0; 1457 } 1458 1459 /* 1460 * Read back the drive's internal buffer contents, as a part 1461 * of the write error recovery mechanism for old OnStream 1462 * firmware revisions. 1463 * Precondition for this function to work: all frames in the 1464 * drive's buffer must be of one type (DATA, MARK or EOD)! 1465 */ 1466 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt, 1467 unsigned int frame, unsigned int skip, int pending) 1468 { 1469 struct osst_request * SRpnt = * aSRpnt; 1470 unsigned char * buffer, * p; 1471 unsigned char cmd[MAX_COMMAND_SIZE]; 1472 int flag, new_frame, i; 1473 int nframes = STp->cur_frames; 1474 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1475 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num) 1476 - (nframes + pending - 1); 1477 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num) 1478 - (nframes + pending - 1) * blks_per_frame; 1479 char * name = tape_name(STp); 1480 unsigned long startwait = jiffies; 1481 #if DEBUG 1482 int dbg = debugging; 1483 #endif 1484 1485 if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL) 1486 return (-EIO); 1487 1488 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n", 1489 name, nframes, pending?" and one that was pending":""); 1490 1491 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE])); 1492 #if DEBUG 1493 if (pending && debugging) 1494 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n", 1495 name, frame_seq_number + nframes, 1496 logical_blk_num + nframes * blks_per_frame, 1497 p[0], p[1], p[2], p[3]); 1498 #endif 1499 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) { 1500 1501 memset(cmd, 0, MAX_COMMAND_SIZE); 1502 cmd[0] = 0x3C; /* Buffer Read */ 1503 cmd[1] = 6; /* Retrieve Faulty Block */ 1504 cmd[7] = 32768 >> 8; 1505 cmd[8] = 32768 & 0xff; 1506 1507 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE, 1508 STp->timeout, MAX_RETRIES, 1); 1509 1510 if ((STp->buffer)->syscall_result || !SRpnt) { 1511 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name); 1512 vfree(buffer); 1513 *aSRpnt = SRpnt; 1514 return (-EIO); 1515 } 1516 osst_copy_from_buffer(STp->buffer, p); 1517 #if DEBUG 1518 if (debugging) 1519 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n", 1520 name, frame_seq_number + i, p[0], p[1], p[2], p[3]); 1521 #endif 1522 } 1523 *aSRpnt = SRpnt; 1524 osst_get_frame_position(STp, aSRpnt); 1525 1526 #if DEBUG 1527 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames); 1528 #endif 1529 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */ 1530 /* In the header we don't actually re-write the frames that fail, just the ones after them */ 1531 1532 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) { 1533 1534 if (flag) { 1535 if (STp->write_type == OS_WRITE_HEADER) { 1536 i += skip; 1537 p += skip * OS_DATA_SIZE; 1538 } 1539 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990) 1540 new_frame = 3000-i; 1541 else 1542 new_frame += skip; 1543 #if DEBUG 1544 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n", 1545 name, new_frame+i, frame_seq_number+i); 1546 #endif 1547 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0); 1548 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE); 1549 osst_get_frame_position(STp, aSRpnt); 1550 SRpnt = * aSRpnt; 1551 1552 if (new_frame > frame + 1000) { 1553 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name); 1554 vfree(buffer); 1555 return (-EIO); 1556 } 1557 if ( i >= nframes + pending ) break; 1558 flag = 0; 1559 } 1560 osst_copy_to_buffer(STp->buffer, p); 1561 /* 1562 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type! 1563 */ 1564 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i, 1565 logical_blk_num + i*blks_per_frame, 1566 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame); 1567 memset(cmd, 0, MAX_COMMAND_SIZE); 1568 cmd[0] = WRITE_6; 1569 cmd[1] = 1; 1570 cmd[4] = 1; 1571 1572 #if DEBUG 1573 if (debugging) 1574 printk(OSST_DEB_MSG 1575 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n", 1576 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame, 1577 p[0], p[1], p[2], p[3]); 1578 #endif 1579 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, 1580 STp->timeout, MAX_RETRIES, 1); 1581 1582 if (STp->buffer->syscall_result) 1583 flag = 1; 1584 else { 1585 p += OS_DATA_SIZE; i++; 1586 1587 /* if we just sent the last frame, wait till all successfully written */ 1588 if ( i == nframes + pending ) { 1589 #if DEBUG 1590 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name); 1591 #endif 1592 memset(cmd, 0, MAX_COMMAND_SIZE); 1593 cmd[0] = WRITE_FILEMARKS; 1594 cmd[1] = 1; 1595 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, 1596 STp->timeout, MAX_RETRIES, 1); 1597 #if DEBUG 1598 if (debugging) { 1599 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name); 1600 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 1601 debugging = 0; 1602 } 1603 #endif 1604 flag = STp->buffer->syscall_result; 1605 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) { 1606 1607 memset(cmd, 0, MAX_COMMAND_SIZE); 1608 cmd[0] = TEST_UNIT_READY; 1609 1610 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, 1611 MAX_RETRIES, 1); 1612 1613 if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 && 1614 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) { 1615 /* in the process of becoming ready */ 1616 msleep(100); 1617 continue; 1618 } 1619 if (STp->buffer->syscall_result) 1620 flag = 1; 1621 break; 1622 } 1623 #if DEBUG 1624 debugging = dbg; 1625 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name); 1626 #endif 1627 } 1628 } 1629 *aSRpnt = SRpnt; 1630 if (flag) { 1631 if ((SRpnt->sense[ 2] & 0x0f) == 13 && 1632 SRpnt->sense[12] == 0 && 1633 SRpnt->sense[13] == 2) { 1634 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name); 1635 vfree(buffer); 1636 return (-EIO); /* hit end of tape = fail */ 1637 } 1638 i = ((SRpnt->sense[3] << 24) | 1639 (SRpnt->sense[4] << 16) | 1640 (SRpnt->sense[5] << 8) | 1641 SRpnt->sense[6] ) - new_frame; 1642 p = &buffer[i * OS_DATA_SIZE]; 1643 #if DEBUG 1644 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i); 1645 #endif 1646 osst_get_frame_position(STp, aSRpnt); 1647 #if DEBUG 1648 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n", 1649 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames); 1650 #endif 1651 } 1652 } 1653 if (flag) { 1654 /* error recovery did not successfully complete */ 1655 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name, 1656 STp->write_type == OS_WRITE_HEADER?"header":"body"); 1657 } 1658 if (!pending) 1659 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */ 1660 vfree(buffer); 1661 return 0; 1662 } 1663 1664 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt, 1665 unsigned int frame, unsigned int skip, int pending) 1666 { 1667 unsigned char cmd[MAX_COMMAND_SIZE]; 1668 struct osst_request * SRpnt; 1669 char * name = tape_name(STp); 1670 int expected = 0; 1671 int attempts = 1000 / skip; 1672 int flag = 1; 1673 unsigned long startwait = jiffies; 1674 #if DEBUG 1675 int dbg = debugging; 1676 #endif 1677 1678 while (attempts && time_before(jiffies, startwait + 60*HZ)) { 1679 if (flag) { 1680 #if DEBUG 1681 debugging = dbg; 1682 #endif 1683 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990) 1684 frame = 3000-skip; 1685 expected = frame+skip+STp->cur_frames+pending; 1686 #if DEBUG 1687 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n", 1688 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending); 1689 #endif 1690 osst_set_frame_position(STp, aSRpnt, frame + skip, 1); 1691 flag = 0; 1692 attempts--; 1693 schedule_timeout_interruptible(msecs_to_jiffies(100)); 1694 } 1695 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */ 1696 #if DEBUG 1697 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n", 1698 name, STp->first_frame_position, 1699 STp->last_frame_position, STp->cur_frames); 1700 #endif 1701 frame = STp->last_frame_position; 1702 flag = 1; 1703 continue; 1704 } 1705 if (pending && STp->cur_frames < 50) { 1706 1707 memset(cmd, 0, MAX_COMMAND_SIZE); 1708 cmd[0] = WRITE_6; 1709 cmd[1] = 1; 1710 cmd[4] = 1; 1711 #if DEBUG 1712 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n", 1713 name, STp->frame_seq_number-1, STp->first_frame_position); 1714 #endif 1715 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, 1716 STp->timeout, MAX_RETRIES, 1); 1717 *aSRpnt = SRpnt; 1718 1719 if (STp->buffer->syscall_result) { /* additional write error */ 1720 if ((SRpnt->sense[ 2] & 0x0f) == 13 && 1721 SRpnt->sense[12] == 0 && 1722 SRpnt->sense[13] == 2) { 1723 printk(KERN_ERR 1724 "%s:E: Volume overflow in write error recovery\n", 1725 name); 1726 break; /* hit end of tape = fail */ 1727 } 1728 flag = 1; 1729 } 1730 else 1731 pending = 0; 1732 1733 continue; 1734 } 1735 if (STp->cur_frames == 0) { 1736 #if DEBUG 1737 debugging = dbg; 1738 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name); 1739 #endif 1740 if (STp->first_frame_position != expected) { 1741 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n", 1742 name, STp->first_frame_position, expected); 1743 return (-EIO); 1744 } 1745 return 0; 1746 } 1747 #if DEBUG 1748 if (debugging) { 1749 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name); 1750 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 1751 debugging = 0; 1752 } 1753 #endif 1754 schedule_timeout_interruptible(msecs_to_jiffies(100)); 1755 } 1756 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name); 1757 #if DEBUG 1758 debugging = dbg; 1759 #endif 1760 return (-EIO); 1761 } 1762 1763 /* 1764 * Error recovery algorithm for the OnStream tape. 1765 */ 1766 1767 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending) 1768 { 1769 struct osst_request * SRpnt = * aSRpnt; 1770 struct st_partstat * STps = & STp->ps[STp->partition]; 1771 char * name = tape_name(STp); 1772 int retval = 0; 1773 int rw_state; 1774 unsigned int frame, skip; 1775 1776 rw_state = STps->rw; 1777 1778 if ((SRpnt->sense[ 2] & 0x0f) != 3 1779 || SRpnt->sense[12] != 12 1780 || SRpnt->sense[13] != 0) { 1781 #if DEBUG 1782 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name, 1783 SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]); 1784 #endif 1785 return (-EIO); 1786 } 1787 frame = (SRpnt->sense[3] << 24) | 1788 (SRpnt->sense[4] << 16) | 1789 (SRpnt->sense[5] << 8) | 1790 SRpnt->sense[6]; 1791 skip = SRpnt->sense[9]; 1792 1793 #if DEBUG 1794 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip); 1795 #endif 1796 osst_get_frame_position(STp, aSRpnt); 1797 #if DEBUG 1798 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n", 1799 name, STp->first_frame_position, STp->last_frame_position); 1800 #endif 1801 switch (STp->write_type) { 1802 case OS_WRITE_DATA: 1803 case OS_WRITE_EOD: 1804 case OS_WRITE_NEW_MARK: 1805 printk(KERN_WARNING 1806 "%s:I: Relocating %d buffered logical frames from position %u to %u\n", 1807 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip); 1808 if (STp->os_fw_rev >= 10600) 1809 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending); 1810 else 1811 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending); 1812 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name, 1813 retval?"E" :"I", 1814 retval?"" :"Don't worry, ", 1815 retval?" not ":" "); 1816 break; 1817 case OS_WRITE_LAST_MARK: 1818 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name); 1819 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0); 1820 retval = -EIO; 1821 break; 1822 case OS_WRITE_HEADER: 1823 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name); 1824 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending); 1825 break; 1826 default: 1827 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name); 1828 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0); 1829 } 1830 osst_get_frame_position(STp, aSRpnt); 1831 #if DEBUG 1832 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n", 1833 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position); 1834 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num); 1835 #endif 1836 if (retval == 0) { 1837 STp->recover_count++; 1838 STp->recover_erreg++; 1839 } else 1840 STp->abort_count++; 1841 1842 STps->rw = rw_state; 1843 return retval; 1844 } 1845 1846 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt, 1847 int mt_op, int mt_count) 1848 { 1849 char * name = tape_name(STp); 1850 int cnt; 1851 int last_mark_ppos = -1; 1852 1853 #if DEBUG 1854 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count); 1855 #endif 1856 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1857 #if DEBUG 1858 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name); 1859 #endif 1860 return -EIO; 1861 } 1862 if (STp->linux_media_version >= 4) { 1863 /* 1864 * direct lookup in header filemark list 1865 */ 1866 cnt = ntohl(STp->buffer->aux->filemark_cnt); 1867 if (STp->header_ok && 1868 STp->header_cache != NULL && 1869 (cnt - mt_count) >= 0 && 1870 (cnt - mt_count) < OS_FM_TAB_MAX && 1871 (cnt - mt_count) < STp->filemark_cnt && 1872 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos) 1873 1874 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]); 1875 #if DEBUG 1876 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX) 1877 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name, 1878 STp->header_cache == NULL?"lack of header cache":"count out of range"); 1879 else 1880 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n", 1881 name, cnt, 1882 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || 1883 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == 1884 STp->buffer->aux->last_mark_ppos))?"match":"error", 1885 mt_count, last_mark_ppos); 1886 #endif 1887 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) { 1888 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos); 1889 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1890 #if DEBUG 1891 printk(OSST_DEB_MSG 1892 "%s:D: Couldn't get logical blk num in space_filemarks\n", name); 1893 #endif 1894 return (-EIO); 1895 } 1896 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 1897 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 1898 name, last_mark_ppos); 1899 return (-EIO); 1900 } 1901 goto found; 1902 } 1903 #if DEBUG 1904 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name); 1905 #endif 1906 } 1907 cnt = 0; 1908 while (cnt != mt_count) { 1909 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos); 1910 if (last_mark_ppos == -1) 1911 return (-EIO); 1912 #if DEBUG 1913 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos); 1914 #endif 1915 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos); 1916 cnt++; 1917 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1918 #if DEBUG 1919 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name); 1920 #endif 1921 return (-EIO); 1922 } 1923 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 1924 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 1925 name, last_mark_ppos); 1926 return (-EIO); 1927 } 1928 } 1929 found: 1930 if (mt_op == MTBSFM) { 1931 STp->frame_seq_number++; 1932 STp->frame_in_buffer = 0; 1933 STp->buffer->buffer_bytes = 0; 1934 STp->buffer->read_pointer = 0; 1935 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1936 } 1937 return 0; 1938 } 1939 1940 /* 1941 * ADRL 1.1 compatible "slow" space filemarks fwd version 1942 * 1943 * Just scans for the filemark sequentially. 1944 */ 1945 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt, 1946 int mt_op, int mt_count) 1947 { 1948 int cnt = 0; 1949 #if DEBUG 1950 char * name = tape_name(STp); 1951 1952 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count); 1953 #endif 1954 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1955 #if DEBUG 1956 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name); 1957 #endif 1958 return (-EIO); 1959 } 1960 while (1) { 1961 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1962 #if DEBUG 1963 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name); 1964 #endif 1965 return (-EIO); 1966 } 1967 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER) 1968 cnt++; 1969 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) { 1970 #if DEBUG 1971 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name); 1972 #endif 1973 if (STp->first_frame_position > STp->eod_frame_ppos+1) { 1974 #if DEBUG 1975 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n", 1976 name, STp->eod_frame_ppos, STp->first_frame_position-1); 1977 #endif 1978 STp->eod_frame_ppos = STp->first_frame_position-1; 1979 } 1980 return (-EIO); 1981 } 1982 if (cnt == mt_count) 1983 break; 1984 STp->frame_in_buffer = 0; 1985 } 1986 if (mt_op == MTFSF) { 1987 STp->frame_seq_number++; 1988 STp->frame_in_buffer = 0; 1989 STp->buffer->buffer_bytes = 0; 1990 STp->buffer->read_pointer = 0; 1991 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1992 } 1993 return 0; 1994 } 1995 1996 /* 1997 * Fast linux specific version of OnStream FSF 1998 */ 1999 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt, 2000 int mt_op, int mt_count) 2001 { 2002 char * name = tape_name(STp); 2003 int cnt = 0, 2004 next_mark_ppos = -1; 2005 2006 #if DEBUG 2007 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count); 2008 #endif 2009 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2010 #if DEBUG 2011 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name); 2012 #endif 2013 return (-EIO); 2014 } 2015 2016 if (STp->linux_media_version >= 4) { 2017 /* 2018 * direct lookup in header filemark list 2019 */ 2020 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1; 2021 if (STp->header_ok && 2022 STp->header_cache != NULL && 2023 (cnt + mt_count) < OS_FM_TAB_MAX && 2024 (cnt + mt_count) < STp->filemark_cnt && 2025 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || 2026 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos))) 2027 2028 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]); 2029 #if DEBUG 2030 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX) 2031 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name, 2032 STp->header_cache == NULL?"lack of header cache":"count out of range"); 2033 else 2034 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n", 2035 name, cnt, 2036 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || 2037 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == 2038 STp->buffer->aux->last_mark_ppos))?"match":"error", 2039 mt_count, next_mark_ppos); 2040 #endif 2041 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) { 2042 #if DEBUG 2043 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name); 2044 #endif 2045 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count); 2046 } else { 2047 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos); 2048 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2049 #if DEBUG 2050 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", 2051 name); 2052 #endif 2053 return (-EIO); 2054 } 2055 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 2056 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 2057 name, next_mark_ppos); 2058 return (-EIO); 2059 } 2060 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) { 2061 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n", 2062 name, cnt+mt_count, next_mark_ppos, 2063 ntohl(STp->buffer->aux->filemark_cnt)); 2064 return (-EIO); 2065 } 2066 } 2067 } else { 2068 /* 2069 * Find nearest (usually previous) marker, then jump from marker to marker 2070 */ 2071 while (1) { 2072 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER) 2073 break; 2074 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) { 2075 #if DEBUG 2076 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name); 2077 #endif 2078 return (-EIO); 2079 } 2080 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) { 2081 if (STp->first_mark_ppos == -1) { 2082 #if DEBUG 2083 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name); 2084 #endif 2085 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count); 2086 } 2087 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos); 2088 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2089 #if DEBUG 2090 printk(OSST_DEB_MSG 2091 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n", 2092 name); 2093 #endif 2094 return (-EIO); 2095 } 2096 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 2097 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n", 2098 name, STp->first_mark_ppos); 2099 return (-EIO); 2100 } 2101 } else { 2102 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0) 2103 return (-EIO); 2104 mt_count++; 2105 } 2106 } 2107 cnt++; 2108 while (cnt != mt_count) { 2109 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos); 2110 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) { 2111 #if DEBUG 2112 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name); 2113 #endif 2114 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt); 2115 } 2116 #if DEBUG 2117 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos); 2118 #endif 2119 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos); 2120 cnt++; 2121 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2122 #if DEBUG 2123 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", 2124 name); 2125 #endif 2126 return (-EIO); 2127 } 2128 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 2129 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 2130 name, next_mark_ppos); 2131 return (-EIO); 2132 } 2133 } 2134 } 2135 if (mt_op == MTFSF) { 2136 STp->frame_seq_number++; 2137 STp->frame_in_buffer = 0; 2138 STp->buffer->buffer_bytes = 0; 2139 STp->buffer->read_pointer = 0; 2140 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 2141 } 2142 return 0; 2143 } 2144 2145 /* 2146 * In debug mode, we want to see as many errors as possible 2147 * to test the error recovery mechanism. 2148 */ 2149 #if DEBUG 2150 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries) 2151 { 2152 unsigned char cmd[MAX_COMMAND_SIZE]; 2153 struct osst_request * SRpnt = * aSRpnt; 2154 char * name = tape_name(STp); 2155 2156 memset(cmd, 0, MAX_COMMAND_SIZE); 2157 cmd[0] = MODE_SELECT; 2158 cmd[1] = 0x10; 2159 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH; 2160 2161 (STp->buffer)->b_data[0] = cmd[4] - 1; 2162 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */ 2163 (STp->buffer)->b_data[2] = 0; /* Reserved */ 2164 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */ 2165 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7); 2166 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2; 2167 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4; 2168 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries; 2169 2170 if (debugging) 2171 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries); 2172 2173 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); 2174 *aSRpnt = SRpnt; 2175 2176 if ((STp->buffer)->syscall_result) 2177 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries); 2178 } 2179 #endif 2180 2181 2182 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt) 2183 { 2184 int result; 2185 int this_mark_ppos = STp->first_frame_position; 2186 int this_mark_lbn = STp->logical_blk_num; 2187 #if DEBUG 2188 char * name = tape_name(STp); 2189 #endif 2190 2191 if (STp->raw) return 0; 2192 2193 STp->write_type = OS_WRITE_NEW_MARK; 2194 #if DEBUG 2195 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n", 2196 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn); 2197 #endif 2198 STp->dirty = 1; 2199 result = osst_flush_write_buffer(STp, aSRpnt); 2200 result |= osst_flush_drive_buffer(STp, aSRpnt); 2201 STp->last_mark_ppos = this_mark_ppos; 2202 STp->last_mark_lbn = this_mark_lbn; 2203 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX) 2204 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos); 2205 if (STp->filemark_cnt++ == 0) 2206 STp->first_mark_ppos = this_mark_ppos; 2207 return result; 2208 } 2209 2210 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt) 2211 { 2212 int result; 2213 #if DEBUG 2214 char * name = tape_name(STp); 2215 #endif 2216 2217 if (STp->raw) return 0; 2218 2219 STp->write_type = OS_WRITE_EOD; 2220 STp->eod_frame_ppos = STp->first_frame_position; 2221 #if DEBUG 2222 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name, 2223 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num); 2224 #endif 2225 STp->dirty = 1; 2226 2227 result = osst_flush_write_buffer(STp, aSRpnt); 2228 result |= osst_flush_drive_buffer(STp, aSRpnt); 2229 STp->eod_frame_lfa = --(STp->frame_seq_number); 2230 return result; 2231 } 2232 2233 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count) 2234 { 2235 char * name = tape_name(STp); 2236 2237 #if DEBUG 2238 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where); 2239 #endif 2240 osst_wait_ready(STp, aSRpnt, 60 * 5, 0); 2241 osst_set_frame_position(STp, aSRpnt, where, 0); 2242 STp->write_type = OS_WRITE_FILLER; 2243 while (count--) { 2244 memcpy(STp->buffer->b_data, "Filler", 6); 2245 STp->buffer->buffer_bytes = 6; 2246 STp->dirty = 1; 2247 if (osst_flush_write_buffer(STp, aSRpnt)) { 2248 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name); 2249 return (-EIO); 2250 } 2251 } 2252 #if DEBUG 2253 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name); 2254 #endif 2255 return osst_flush_drive_buffer(STp, aSRpnt); 2256 } 2257 2258 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count) 2259 { 2260 char * name = tape_name(STp); 2261 int result; 2262 2263 #if DEBUG 2264 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where); 2265 #endif 2266 osst_wait_ready(STp, aSRpnt, 60 * 5, 0); 2267 osst_set_frame_position(STp, aSRpnt, where, 0); 2268 STp->write_type = OS_WRITE_HEADER; 2269 while (count--) { 2270 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache); 2271 STp->buffer->buffer_bytes = sizeof(os_header_t); 2272 STp->dirty = 1; 2273 if (osst_flush_write_buffer(STp, aSRpnt)) { 2274 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name); 2275 return (-EIO); 2276 } 2277 } 2278 result = osst_flush_drive_buffer(STp, aSRpnt); 2279 #if DEBUG 2280 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done"); 2281 #endif 2282 return result; 2283 } 2284 2285 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod) 2286 { 2287 os_header_t * header; 2288 int result; 2289 char * name = tape_name(STp); 2290 2291 #if DEBUG 2292 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name); 2293 #endif 2294 if (STp->raw) return 0; 2295 2296 if (STp->header_cache == NULL) { 2297 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) { 2298 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name); 2299 return (-ENOMEM); 2300 } 2301 memset(STp->header_cache, 0, sizeof(os_header_t)); 2302 #if DEBUG 2303 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name); 2304 #endif 2305 } 2306 if (STp->header_ok) STp->update_frame_cntr++; 2307 else STp->update_frame_cntr = 0; 2308 2309 header = STp->header_cache; 2310 strcpy(header->ident_str, "ADR_SEQ"); 2311 header->major_rev = 1; 2312 header->minor_rev = 4; 2313 header->ext_trk_tb_off = htons(17192); 2314 header->pt_par_num = 1; 2315 header->partition[0].partition_num = OS_DATA_PARTITION; 2316 header->partition[0].par_desc_ver = OS_PARTITION_VERSION; 2317 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr); 2318 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos); 2319 header->partition[0].last_frame_ppos = htonl(STp->capacity); 2320 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos); 2321 header->cfg_col_width = htonl(20); 2322 header->dat_col_width = htonl(1500); 2323 header->qfa_col_width = htonl(0); 2324 header->ext_track_tb.nr_stream_part = 1; 2325 header->ext_track_tb.et_ent_sz = 32; 2326 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0; 2327 header->ext_track_tb.dat_ext_trk_ey.fmt = 1; 2328 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736); 2329 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0; 2330 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa); 2331 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos); 2332 header->dat_fm_tab.fm_part_num = 0; 2333 header->dat_fm_tab.fm_tab_ent_sz = 4; 2334 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX? 2335 STp->filemark_cnt:OS_FM_TAB_MAX); 2336 2337 result = __osst_write_header(STp, aSRpnt, 0xbae, 5); 2338 if (STp->update_frame_cntr == 0) 2339 osst_write_filler(STp, aSRpnt, 0xbb3, 5); 2340 result &= __osst_write_header(STp, aSRpnt, 5, 5); 2341 2342 if (locate_eod) { 2343 #if DEBUG 2344 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos); 2345 #endif 2346 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0); 2347 } 2348 if (result) 2349 printk(KERN_ERR "%s:E: Write header failed\n", name); 2350 else { 2351 memcpy(STp->application_sig, "LIN4", 4); 2352 STp->linux_media = 1; 2353 STp->linux_media_version = 4; 2354 STp->header_ok = 1; 2355 } 2356 return result; 2357 } 2358 2359 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt) 2360 { 2361 if (STp->header_cache != NULL) 2362 memset(STp->header_cache, 0, sizeof(os_header_t)); 2363 2364 STp->logical_blk_num = STp->frame_seq_number = 0; 2365 STp->frame_in_buffer = 0; 2366 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A; 2367 STp->filemark_cnt = 0; 2368 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1; 2369 return osst_write_header(STp, aSRpnt, 1); 2370 } 2371 2372 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos) 2373 { 2374 char * name = tape_name(STp); 2375 os_header_t * header; 2376 os_aux_t * aux; 2377 char id_string[8]; 2378 int linux_media_version, 2379 update_frame_cntr; 2380 2381 if (STp->raw) 2382 return 1; 2383 2384 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) { 2385 if (osst_set_frame_position(STp, aSRpnt, ppos, 0)) 2386 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name); 2387 osst_wait_ready(STp, aSRpnt, 60 * 15, 0); 2388 if (osst_initiate_read (STp, aSRpnt)) { 2389 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name); 2390 return 0; 2391 } 2392 } 2393 if (osst_read_frame(STp, aSRpnt, 180)) { 2394 #if DEBUG 2395 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name); 2396 #endif 2397 return 0; 2398 } 2399 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */ 2400 aux = STp->buffer->aux; 2401 if (aux->frame_type != OS_FRAME_TYPE_HEADER) { 2402 #if DEBUG 2403 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos); 2404 #endif 2405 return 0; 2406 } 2407 if (ntohl(aux->frame_seq_num) != 0 || 2408 ntohl(aux->logical_blk_num) != 0 || 2409 aux->partition.partition_num != OS_CONFIG_PARTITION || 2410 ntohl(aux->partition.first_frame_ppos) != 0 || 2411 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) { 2412 #if DEBUG 2413 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name, 2414 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num), 2415 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos), 2416 ntohl(aux->partition.last_frame_ppos)); 2417 #endif 2418 return 0; 2419 } 2420 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 && 2421 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) { 2422 strlcpy(id_string, header->ident_str, 8); 2423 #if DEBUG 2424 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string); 2425 #endif 2426 return 0; 2427 } 2428 update_frame_cntr = ntohl(aux->update_frame_cntr); 2429 if (update_frame_cntr < STp->update_frame_cntr) { 2430 #if DEBUG 2431 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n", 2432 name, ppos, update_frame_cntr, STp->update_frame_cntr); 2433 #endif 2434 return 0; 2435 } 2436 if (header->major_rev != 1 || header->minor_rev != 4 ) { 2437 #if DEBUG 2438 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n", 2439 name, (header->major_rev != 1 || header->minor_rev < 2 || 2440 header->minor_rev > 4 )? "Invalid" : "Warning:", 2441 header->major_rev, header->minor_rev); 2442 #endif 2443 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4) 2444 return 0; 2445 } 2446 #if DEBUG 2447 if (header->pt_par_num != 1) 2448 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n", 2449 name, header->pt_par_num); 2450 #endif 2451 memcpy(id_string, aux->application_sig, 4); 2452 id_string[4] = 0; 2453 if (memcmp(id_string, "LIN", 3) == 0) { 2454 STp->linux_media = 1; 2455 linux_media_version = id_string[3] - ''; 2456 if (linux_media_version != 4) 2457 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n", 2458 name, linux_media_version); 2459 } else { 2460 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string); 2461 return 0; 2462 } 2463 if (linux_media_version < STp->linux_media_version) { 2464 #if DEBUG 2465 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n", 2466 name, ppos, linux_media_version); 2467 #endif 2468 return 0; 2469 } 2470 if (linux_media_version > STp->linux_media_version) { 2471 #if DEBUG 2472 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n", 2473 name, ppos, linux_media_version); 2474 #endif 2475 memcpy(STp->application_sig, id_string, 5); 2476 STp->linux_media_version = linux_media_version; 2477 STp->update_frame_cntr = -1; 2478 } 2479 if (update_frame_cntr > STp->update_frame_cntr) { 2480 #if DEBUG 2481 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n", 2482 name, ppos, update_frame_cntr); 2483 #endif 2484 if (STp->header_cache == NULL) { 2485 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) { 2486 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name); 2487 return 0; 2488 } 2489 #if DEBUG 2490 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name); 2491 #endif 2492 } 2493 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache); 2494 header = STp->header_cache; /* further accesses from cached (full) copy */ 2495 2496 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr); 2497 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos); 2498 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos); 2499 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb); 2500 STp->filemark_cnt = ntohl(aux->filemark_cnt); 2501 STp->first_mark_ppos = ntohl(aux->next_mark_ppos); 2502 STp->last_mark_ppos = ntohl(aux->last_mark_ppos); 2503 STp->last_mark_lbn = ntohl(aux->last_mark_lbn); 2504 STp->update_frame_cntr = update_frame_cntr; 2505 #if DEBUG 2506 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n", 2507 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt); 2508 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name, 2509 STp->first_data_ppos, 2510 ntohl(header->partition[0].last_frame_ppos), 2511 ntohl(header->partition[0].eod_frame_ppos)); 2512 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n", 2513 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos); 2514 #endif 2515 if (header->minor_rev < 4 && STp->linux_media_version == 4) { 2516 #if DEBUG 2517 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name); 2518 #endif 2519 memcpy((void *)header->dat_fm_tab.fm_tab_ent, 2520 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent)); 2521 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list)); 2522 } 2523 if (header->minor_rev == 4 && 2524 (header->ext_trk_tb_off != htons(17192) || 2525 header->partition[0].partition_num != OS_DATA_PARTITION || 2526 header->partition[0].par_desc_ver != OS_PARTITION_VERSION || 2527 header->partition[0].last_frame_ppos != htonl(STp->capacity) || 2528 header->cfg_col_width != htonl(20) || 2529 header->dat_col_width != htonl(1500) || 2530 header->qfa_col_width != htonl(0) || 2531 header->ext_track_tb.nr_stream_part != 1 || 2532 header->ext_track_tb.et_ent_sz != 32 || 2533 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION || 2534 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 || 2535 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) || 2536 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 || 2537 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) || 2538 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION || 2539 header->dat_fm_tab.fm_tab_ent_sz != 4 || 2540 header->dat_fm_tab.fm_tab_ent_cnt != 2541 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX))) 2542 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name); 2543 2544 } 2545 2546 return 1; 2547 } 2548 2549 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt) 2550 { 2551 int position, ppos; 2552 int first, last; 2553 int valid = 0; 2554 char * name = tape_name(STp); 2555 2556 position = osst_get_frame_position(STp, aSRpnt); 2557 2558 if (STp->raw) { 2559 STp->header_ok = STp->linux_media = 1; 2560 STp->linux_media_version = 0; 2561 return 1; 2562 } 2563 STp->header_ok = STp->linux_media = STp->linux_media_version = 0; 2564 STp->wrt_pass_cntr = STp->update_frame_cntr = -1; 2565 STp->eod_frame_ppos = STp->first_data_ppos = -1; 2566 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1; 2567 #if DEBUG 2568 printk(OSST_DEB_MSG "%s:D: Reading header\n", name); 2569 #endif 2570 2571 /* optimization for speed - if we are positioned at ppos 10, read second group first */ 2572 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */ 2573 2574 first = position==10?0xbae: 5; 2575 last = position==10?0xbb3:10; 2576 2577 for (ppos = first; ppos < last; ppos++) 2578 if (__osst_analyze_headers(STp, aSRpnt, ppos)) 2579 valid = 1; 2580 2581 first = position==10? 5:0xbae; 2582 last = position==10?10:0xbb3; 2583 2584 for (ppos = first; ppos < last; ppos++) 2585 if (__osst_analyze_headers(STp, aSRpnt, ppos)) 2586 valid = 1; 2587 2588 if (!valid) { 2589 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name); 2590 STp->eod_frame_ppos = STp->first_data_ppos = 0; 2591 osst_set_frame_position(STp, aSRpnt, 10, 0); 2592 return 0; 2593 } 2594 if (position <= STp->first_data_ppos) { 2595 position = STp->first_data_ppos; 2596 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0; 2597 } 2598 osst_set_frame_position(STp, aSRpnt, position, 0); 2599 STp->header_ok = 1; 2600 2601 return 1; 2602 } 2603 2604 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt) 2605 { 2606 int frame_position = STp->first_frame_position; 2607 int frame_seq_numbr = STp->frame_seq_number; 2608 int logical_blk_num = STp->logical_blk_num; 2609 int halfway_frame = STp->frame_in_buffer; 2610 int read_pointer = STp->buffer->read_pointer; 2611 int prev_mark_ppos = -1; 2612 int actual_mark_ppos, i, n; 2613 #if DEBUG 2614 char * name = tape_name(STp); 2615 2616 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name); 2617 #endif 2618 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); 2619 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2620 #if DEBUG 2621 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name); 2622 #endif 2623 return (-EIO); 2624 } 2625 if (STp->linux_media_version >= 4) { 2626 for (i=0; i<STp->filemark_cnt; i++) 2627 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position) 2628 prev_mark_ppos = n; 2629 } else 2630 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */ 2631 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ? 2632 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos); 2633 if (frame_position != STp->first_frame_position || 2634 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) || 2635 prev_mark_ppos != actual_mark_ppos ) { 2636 #if DEBUG 2637 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name, 2638 STp->first_frame_position, frame_position, 2639 STp->frame_seq_number + (halfway_frame?0:1), 2640 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos); 2641 #endif 2642 return (-EIO); 2643 } 2644 if (halfway_frame) { 2645 /* prepare buffer for append and rewrite on top of original */ 2646 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); 2647 STp->buffer->buffer_bytes = read_pointer; 2648 STp->ps[STp->partition].rw = ST_WRITING; 2649 STp->dirty = 1; 2650 } 2651 STp->frame_in_buffer = halfway_frame; 2652 STp->frame_seq_number = frame_seq_numbr; 2653 STp->logical_blk_num = logical_blk_num; 2654 return 0; 2655 } 2656 2657 /* Acc. to OnStream, the vers. numbering is the following: 2658 * X.XX for released versions (X=digit), 2659 * XXXY for unreleased versions (Y=letter) 2660 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06 2661 * This fn makes monoton numbers out of this scheme ... 2662 */ 2663 static unsigned int osst_parse_firmware_rev (const char * str) 2664 { 2665 if (str[1] == '.') { 2666 return (str[0]-'')*10000 2667 +(str[2]-'')*1000 2668 +(str[3]-'')*100; 2669 } else { 2670 return (str[0]-'')*10000 2671 +(str[1]-'')*1000 2672 +(str[2]-'')*100 - 100 2673 +(str[3]-'@'); 2674 } 2675 } 2676 2677 /* 2678 * Configure the OnStream SCII tape drive for default operation 2679 */ 2680 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt) 2681 { 2682 unsigned char cmd[MAX_COMMAND_SIZE]; 2683 char * name = tape_name(STp); 2684 struct osst_request * SRpnt = * aSRpnt; 2685 osst_mode_parameter_header_t * header; 2686 osst_block_size_page_t * bs; 2687 osst_capabilities_page_t * cp; 2688 osst_tape_paramtr_page_t * prm; 2689 int drive_buffer_size; 2690 2691 if (STp->ready != ST_READY) { 2692 #if DEBUG 2693 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name); 2694 #endif 2695 return (-EIO); 2696 } 2697 2698 if (STp->os_fw_rev < 10600) { 2699 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev); 2700 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name); 2701 } 2702 2703 /* 2704 * Configure 32.5KB (data+aux) frame size. 2705 * Get the current frame size from the block size mode page 2706 */ 2707 memset(cmd, 0, MAX_COMMAND_SIZE); 2708 cmd[0] = MODE_SENSE; 2709 cmd[1] = 8; 2710 cmd[2] = BLOCK_SIZE_PAGE; 2711 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH; 2712 2713 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); 2714 if (SRpnt == NULL) { 2715 #if DEBUG 2716 printk(OSST_DEB_MSG "osst :D: Busy\n"); 2717 #endif 2718 return (-EBUSY); 2719 } 2720 *aSRpnt = SRpnt; 2721 if ((STp->buffer)->syscall_result != 0) { 2722 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name); 2723 return (-EIO); 2724 } 2725 2726 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; 2727 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl); 2728 2729 #if DEBUG 2730 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No"); 2731 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No"); 2732 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No"); 2733 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No"); 2734 #endif 2735 2736 /* 2737 * Configure default auto columns mode, 32.5KB transfer mode 2738 */ 2739 bs->one = 1; 2740 bs->play32 = 0; 2741 bs->play32_5 = 1; 2742 bs->record32 = 0; 2743 bs->record32_5 = 1; 2744 2745 memset(cmd, 0, MAX_COMMAND_SIZE); 2746 cmd[0] = MODE_SELECT; 2747 cmd[1] = 0x10; 2748 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH; 2749 2750 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); 2751 *aSRpnt = SRpnt; 2752 if ((STp->buffer)->syscall_result != 0) { 2753 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name); 2754 return (-EIO); 2755 } 2756 2757 #if DEBUG 2758 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name); 2759 /* 2760 * In debug mode, we want to see as many errors as possible 2761 * to test the error recovery mechanism. 2762 */ 2763 osst_set_retries(STp, aSRpnt, 0); 2764 SRpnt = * aSRpnt; 2765 #endif 2766 2767 /* 2768 * Set vendor name to 'LIN4' for "Linux support version 4". 2769 */ 2770 2771 memset(cmd, 0, MAX_COMMAND_SIZE); 2772 cmd[0] = MODE_SELECT; 2773 cmd[1] = 0x10; 2774 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH; 2775 2776 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1; 2777 header->medium_type = 0; /* Medium Type - ignoring */ 2778 header->dsp = 0; /* Reserved */ 2779 header->bdl = 0; /* Block Descriptor Length */ 2780 2781 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7); 2782 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6; 2783 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L'; 2784 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I'; 2785 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N'; 2786 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4'; 2787 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0; 2788 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0; 2789 2790 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); 2791 *aSRpnt = SRpnt; 2792 2793 if ((STp->buffer)->syscall_result != 0) { 2794 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name, 2795 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2)); 2796 return (-EIO); 2797 } 2798 2799 memset(cmd, 0, MAX_COMMAND_SIZE); 2800 cmd[0] = MODE_SENSE; 2801 cmd[1] = 8; 2802 cmd[2] = CAPABILITIES_PAGE; 2803 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH; 2804 2805 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); 2806 *aSRpnt = SRpnt; 2807 2808 if ((STp->buffer)->syscall_result != 0) { 2809 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name); 2810 return (-EIO); 2811 } 2812 2813 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; 2814 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data + 2815 sizeof(osst_mode_parameter_header_t) + header->bdl); 2816 2817 drive_buffer_size = ntohs(cp->buffer_size) / 2; 2818 2819 memset(cmd, 0, MAX_COMMAND_SIZE); 2820 cmd[0] = MODE_SENSE; 2821 cmd[1] = 8; 2822 cmd[2] = TAPE_PARAMTR_PAGE; 2823 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH; 2824 2825 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); 2826 *aSRpnt = SRpnt; 2827 2828 if ((STp->buffer)->syscall_result != 0) { 2829 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name); 2830 return (-EIO); 2831 } 2832 2833 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; 2834 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data + 2835 sizeof(osst_mode_parameter_header_t) + header->bdl); 2836 2837 STp->density = prm->density; 2838 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks); 2839 #if DEBUG 2840 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n", 2841 name, STp->density, STp->capacity / 32, drive_buffer_size); 2842 #endif 2843 2844 return 0; 2845 2846 } 2847 2848 2849 /* Step over EOF if it has been inadvertently crossed (ioctl not used because 2850 it messes up the block number). */ 2851 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward) 2852 { 2853 int result; 2854 char * name = tape_name(STp); 2855 2856 #if DEBUG 2857 if (debugging) 2858 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n", 2859 name, forward ? "forward" : "backward"); 2860 #endif 2861 2862 if (forward) { 2863 /* assumes that the filemark is already read by the drive, so this is low cost */ 2864 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1); 2865 } 2866 else 2867 /* assumes this is only called if we just read the filemark! */ 2868 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1); 2869 2870 if (result < 0) 2871 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n", 2872 name, forward ? "forward" : "backward"); 2873 2874 return result; 2875 } 2876 2877 2878 /* Get the tape position. */ 2879 2880 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt) 2881 { 2882 unsigned char scmd[MAX_COMMAND_SIZE]; 2883 struct osst_request * SRpnt; 2884 int result = 0; 2885 char * name = tape_name(STp); 2886 2887 /* KG: We want to be able to use it for checking Write Buffer availability 2888 * and thus don't want to risk to overwrite anything. Exchange buffers ... */ 2889 char mybuf[24]; 2890 char * olddata = STp->buffer->b_data; 2891 int oldsize = STp->buffer->buffer_size; 2892 2893 if (STp->ready != ST_READY) return (-EIO); 2894 2895 memset (scmd, 0, MAX_COMMAND_SIZE); 2896 scmd[0] = READ_POSITION; 2897 2898 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; 2899 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE, 2900 STp->timeout, MAX_RETRIES, 1); 2901 if (!SRpnt) { 2902 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; 2903 return (-EBUSY); 2904 } 2905 *aSRpnt = SRpnt; 2906 2907 if (STp->buffer->syscall_result) 2908 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */ 2909 2910 if (result == -EINVAL) 2911 printk(KERN_ERR "%s:E: Can't read tape position.\n", name); 2912 else { 2913 if (result == -EIO) { /* re-read position - this needs to preserve media errors */ 2914 unsigned char mysense[16]; 2915 memcpy (mysense, SRpnt->sense, 16); 2916 memset (scmd, 0, MAX_COMMAND_SIZE); 2917 scmd[0] = READ_POSITION; 2918 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; 2919 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE, 2920 STp->timeout, MAX_RETRIES, 1); 2921 #if DEBUG 2922 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n", 2923 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:", 2924 SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]); 2925 #endif 2926 if (!STp->buffer->syscall_result) 2927 memcpy (SRpnt->sense, mysense, 16); 2928 else 2929 printk(KERN_WARNING "%s:W: Double error in get position\n", name); 2930 } 2931 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24) 2932 + ((STp->buffer)->b_data[5] << 16) 2933 + ((STp->buffer)->b_data[6] << 8) 2934 + (STp->buffer)->b_data[7]; 2935 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24) 2936 + ((STp->buffer)->b_data[ 9] << 16) 2937 + ((STp->buffer)->b_data[10] << 8) 2938 + (STp->buffer)->b_data[11]; 2939 STp->cur_frames = (STp->buffer)->b_data[15]; 2940 #if DEBUG 2941 if (debugging) { 2942 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name, 2943 STp->first_frame_position, STp->last_frame_position, 2944 ((STp->buffer)->b_data[0]&0x80)?" (BOP)": 2945 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"", 2946 STp->cur_frames); 2947 } 2948 #endif 2949 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) { 2950 #if DEBUG 2951 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name, 2952 STp->first_frame_position, STp->last_frame_position, STp->cur_frames); 2953 #endif 2954 STp->first_frame_position = STp->last_frame_position; 2955 } 2956 } 2957 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; 2958 2959 return (result == 0 ? STp->first_frame_position : result); 2960 } 2961 2962 2963 /* Set the tape block */ 2964 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip) 2965 { 2966 unsigned char scmd[MAX_COMMAND_SIZE]; 2967 struct osst_request * SRpnt; 2968 struct st_partstat * STps; 2969 int result = 0; 2970 int pp = (ppos == 3000 && !skip)? 0 : ppos; 2971 char * name = tape_name(STp); 2972 2973 if (STp->ready != ST_READY) return (-EIO); 2974 2975 STps = &(STp->ps[STp->partition]); 2976 2977 if (ppos < 0 || ppos > STp->capacity) { 2978 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos); 2979 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1); 2980 result = (-EINVAL); 2981 } 2982 2983 do { 2984 #if DEBUG 2985 if (debugging) 2986 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp); 2987 #endif 2988 memset (scmd, 0, MAX_COMMAND_SIZE); 2989 scmd[0] = SEEK_10; 2990 scmd[1] = 1; 2991 scmd[3] = (pp >> 24); 2992 scmd[4] = (pp >> 16); 2993 scmd[5] = (pp >> 8); 2994 scmd[6] = pp; 2995 if (skip) 2996 scmd[9] = 0x80; 2997 2998 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout, 2999 MAX_RETRIES, 1); 3000 if (!SRpnt) 3001 return (-EBUSY); 3002 *aSRpnt = SRpnt; 3003 3004 if ((STp->buffer)->syscall_result != 0) { 3005 #if DEBUG 3006 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n", 3007 name, STp->first_frame_position, pp); 3008 #endif 3009 result = (-EIO); 3010 } 3011 if (pp != ppos) 3012 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE); 3013 } while ((pp != ppos) && (pp = ppos)); 3014 STp->first_frame_position = STp->last_frame_position = ppos; 3015 STps->eof = ST_NOEOF; 3016 STps->at_sm = 0; 3017 STps->rw = ST_IDLE; 3018 STp->frame_in_buffer = 0; 3019 return result; 3020 } 3021 3022 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT) 3023 { 3024 struct st_partstat * STps = &(STp->ps[STp->partition]); 3025 int result = 0; 3026 3027 if (STp->write_type != OS_WRITE_NEW_MARK) { 3028 /* true unless the user wrote the filemark for us */ 3029 result = osst_flush_drive_buffer(STp, aSRpnt); 3030 if (result < 0) goto out; 3031 result = osst_write_filemark(STp, aSRpnt); 3032 if (result < 0) goto out; 3033 3034 if (STps->drv_file >= 0) 3035 STps->drv_file++ ; 3036 STps->drv_block = 0; 3037 } 3038 result = osst_write_eod(STp, aSRpnt); 3039 osst_write_header(STp, aSRpnt, leave_at_EOT); 3040 3041 STps->eof = ST_FM; 3042 out: 3043 return result; 3044 } 3045 3046 /* osst versions of st functions - augmented and stripped to suit OnStream only */ 3047 3048 /* Flush the write buffer (never need to write if variable blocksize). */ 3049 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt) 3050 { 3051 int offset, transfer, blks = 0; 3052 int result = 0; 3053 unsigned char cmd[MAX_COMMAND_SIZE]; 3054 struct osst_request * SRpnt = *aSRpnt; 3055 struct st_partstat * STps; 3056 char * name = tape_name(STp); 3057 3058 if ((STp->buffer)->writing) { 3059 if (SRpnt == (STp->buffer)->last_SRpnt) 3060 #if DEBUG 3061 { printk(OSST_DEB_MSG 3062 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name); 3063 #endif 3064 *aSRpnt = SRpnt = NULL; 3065 #if DEBUG 3066 } else if (SRpnt) 3067 printk(OSST_DEB_MSG 3068 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name); 3069 #endif 3070 osst_write_behind_check(STp); 3071 if ((STp->buffer)->syscall_result) { 3072 #if DEBUG 3073 if (debugging) 3074 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n", 3075 name, (STp->buffer)->midlevel_result); 3076 #endif 3077 if ((STp->buffer)->midlevel_result == INT_MAX) 3078 return (-ENOSPC); 3079 return (-EIO); 3080 } 3081 } 3082 3083 result = 0; 3084 if (STp->dirty == 1) { 3085 3086 STp->write_count++; 3087 STps = &(STp->ps[STp->partition]); 3088 STps->rw = ST_WRITING; 3089 offset = STp->buffer->buffer_bytes; 3090 blks = (offset + STp->block_size - 1) / STp->block_size; 3091 transfer = OS_FRAME_SIZE; 3092 3093 if (offset < OS_DATA_SIZE) 3094 osst_zero_buffer_tail(STp->buffer); 3095 3096 if (STp->poll) 3097 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120)) 3098 result = osst_recover_wait_frame(STp, aSRpnt, 1); 3099 3100 memset(cmd, 0, MAX_COMMAND_SIZE); 3101 cmd[0] = WRITE_6; 3102 cmd[1] = 1; 3103 cmd[4] = 1; 3104 3105 switch (STp->write_type) { 3106 case OS_WRITE_DATA: 3107 #if DEBUG 3108 if (debugging) 3109 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", 3110 name, blks, STp->frame_seq_number, 3111 STp->logical_blk_num - blks, STp->logical_blk_num - 1); 3112 #endif 3113 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++, 3114 STp->logical_blk_num - blks, STp->block_size, blks); 3115 break; 3116 case OS_WRITE_EOD: 3117 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++, 3118 STp->logical_blk_num, 0, 0); 3119 break; 3120 case OS_WRITE_NEW_MARK: 3121 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++, 3122 STp->logical_blk_num++, 0, blks=1); 3123 break; 3124 case OS_WRITE_HEADER: 3125 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0); 3126 break; 3127 default: /* probably FILLER */ 3128 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0); 3129 } 3130 #if DEBUG 3131 if (debugging) 3132 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n", 3133 name, offset, transfer, blks); 3134 #endif 3135 3136 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE, 3137 STp->timeout, MAX_RETRIES, 1); 3138 *aSRpnt = SRpnt; 3139 if (!SRpnt) 3140 return (-EBUSY); 3141 3142 if ((STp->buffer)->syscall_result != 0) { 3143 #if DEBUG 3144 printk(OSST_DEB_MSG 3145 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n", 3146 name, SRpnt->sense[0], SRpnt->sense[2], 3147 SRpnt->sense[12], SRpnt->sense[13]); 3148 #endif 3149 if ((SRpnt->sense[0] & 0x70) == 0x70 && 3150 (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */ 3151 (SRpnt->sense[2] & 0x0f) == NO_SENSE) { 3152 STp->dirty = 0; 3153 (STp->buffer)->buffer_bytes = 0; 3154 result = (-ENOSPC); 3155 } 3156 else { 3157 if (osst_write_error_recovery(STp, aSRpnt, 1)) { 3158 printk(KERN_ERR "%s:E: Error on flush write.\n", name); 3159 result = (-EIO); 3160 } 3161 } 3162 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */ 3163 } 3164 else { 3165 STp->first_frame_position++; 3166 STp->dirty = 0; 3167 (STp->buffer)->buffer_bytes = 0; 3168 } 3169 } 3170 #if DEBUG 3171 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result); 3172 #endif 3173 return result; 3174 } 3175 3176 3177 /* Flush the tape buffer. The tape will be positioned correctly unless 3178 seek_next is true. */ 3179 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next) 3180 { 3181 struct st_partstat * STps; 3182 int backspace = 0, result = 0; 3183 #if DEBUG 3184 char * name = tape_name(STp); 3185 #endif 3186 3187 /* 3188 * If there was a bus reset, block further access 3189 * to this device. 3190 */ 3191 if( STp->pos_unknown) 3192 return (-EIO); 3193 3194 if (STp->ready != ST_READY) 3195 return 0; 3196 3197 STps = &(STp->ps[STp->partition]); 3198 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */ 3199 STp->write_type = OS_WRITE_DATA; 3200 return osst_flush_write_buffer(STp, aSRpnt); 3201 } 3202 if (STp->block_size == 0) 3203 return 0; 3204 3205 #if DEBUG 3206 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name); 3207 #endif 3208 3209 if (!STp->can_bsr) { 3210 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size - 3211 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ; 3212 (STp->buffer)->buffer_bytes = 0; 3213 (STp->buffer)->read_pointer = 0; 3214 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */ 3215 } 3216 3217 if (!seek_next) { 3218 if (STps->eof == ST_FM_HIT) { 3219 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */ 3220 if (!result) 3221 STps->eof = ST_NOEOF; 3222 else { 3223 if (STps->drv_file >= 0) 3224 STps->drv_file++; 3225 STps->drv_block = 0; 3226 } 3227 } 3228 if (!result && backspace > 0) /* TODO -- design and run a test case for this */ 3229 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace); 3230 } 3231 else if (STps->eof == ST_FM_HIT) { 3232 if (STps->drv_file >= 0) 3233 STps->drv_file++; 3234 STps->drv_block = 0; 3235 STps->eof = ST_NOEOF; 3236 } 3237 3238 return result; 3239 } 3240 3241 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous) 3242 { 3243 unsigned char cmd[MAX_COMMAND_SIZE]; 3244 struct osst_request * SRpnt; 3245 int blks; 3246 #if DEBUG 3247 char * name = tape_name(STp); 3248 #endif 3249 3250 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */ 3251 #if DEBUG 3252 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name); 3253 #endif 3254 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) { 3255 return (-EIO); 3256 } 3257 /* error recovery may have bumped us past the header partition */ 3258 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) { 3259 #if DEBUG 3260 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name); 3261 #endif 3262 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8); 3263 } 3264 } 3265 3266 if (STp->poll) 3267 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120)) 3268 if (osst_recover_wait_frame(STp, aSRpnt, 1)) 3269 return (-EIO); 3270 3271 // osst_build_stats(STp, &SRpnt); 3272 3273 STp->ps[STp->partition].rw = ST_WRITING; 3274 STp->write_type = OS_WRITE_DATA; 3275 3276 memset(cmd, 0, MAX_COMMAND_SIZE); 3277 cmd[0] = WRITE_6; 3278 cmd[1] = 1; 3279 cmd[4] = 1; /* one frame at a time... */ 3280 blks = STp->buffer->buffer_bytes / STp->block_size; 3281 #if DEBUG 3282 if (debugging) 3283 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks, 3284 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1); 3285 #endif 3286 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++, 3287 STp->logical_blk_num - blks, STp->block_size, blks); 3288 3289 #if DEBUG 3290 if (!synchronous) 3291 STp->write_pending = 1; 3292 #endif 3293 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout, 3294 MAX_RETRIES, synchronous); 3295 if (!SRpnt) 3296 return (-EBUSY); 3297 *aSRpnt = SRpnt; 3298 3299 if (synchronous) { 3300 if (STp->buffer->syscall_result != 0) { 3301 #if DEBUG 3302 if (debugging) 3303 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name); 3304 #endif 3305 if ((SRpnt->sense[0] & 0x70) == 0x70 && 3306 (SRpnt->sense[2] & 0x40)) { 3307 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW) 3308 return (-ENOSPC); 3309 } 3310 else { 3311 if (osst_write_error_recovery(STp, aSRpnt, 1)) 3312 return (-EIO); 3313 } 3314 } 3315 else 3316 STp->first_frame_position++; 3317 } 3318 3319 STp->write_count++; 3320 3321 return 0; 3322 } 3323 3324 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */ 3325 static int do_door_lock(struct osst_tape * STp, int do_lock) 3326 { 3327 int retval, cmd; 3328 3329 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK; 3330 #if DEBUG 3331 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl"); 3332 #endif 3333 retval = scsi_ioctl(STp->device, cmd, NULL); 3334 if (!retval) { 3335 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED; 3336 } 3337 else { 3338 STp->door_locked = ST_LOCK_FAILS; 3339 } 3340 return retval; 3341 } 3342 3343 /* Set the internal state after reset */ 3344 static void reset_state(struct osst_tape *STp) 3345 { 3346 int i; 3347 struct st_partstat *STps; 3348 3349 STp->pos_unknown = 0; 3350 for (i = 0; i < ST_NBR_PARTITIONS; i++) { 3351 STps = &(STp->ps[i]); 3352 STps->rw = ST_IDLE; 3353 STps->eof = ST_NOEOF; 3354 STps->at_sm = 0; 3355 STps->last_block_valid = 0; 3356 STps->drv_block = -1; 3357 STps->drv_file = -1; 3358 } 3359 } 3360 3361 3362 /* Entry points to osst */ 3363 3364 /* Write command */ 3365 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos) 3366 { 3367 ssize_t total, retval = 0; 3368 ssize_t i, do_count, blks, transfer; 3369 int write_threshold; 3370 int doing_write = 0; 3371 const char __user * b_point; 3372 struct osst_request * SRpnt = NULL; 3373 struct st_modedef * STm; 3374 struct st_partstat * STps; 3375 struct osst_tape * STp = filp->private_data; 3376 char * name = tape_name(STp); 3377 3378 3379 if (mutex_lock_interruptible(&STp->lock)) 3380 return (-ERESTARTSYS); 3381 3382 /* 3383 * If we are in the middle of error recovery, don't let anyone 3384 * else try and use this device. Also, if error recovery fails, it 3385 * may try and take the device offline, in which case all further 3386 * access to the device is prohibited. 3387 */ 3388 if( !scsi_block_when_processing_errors(STp->device) ) { 3389 retval = (-ENXIO); 3390 goto out; 3391 } 3392 3393 if (STp->ready != ST_READY) { 3394 if (STp->ready == ST_NO_TAPE) 3395 retval = (-ENOMEDIUM); 3396 else 3397 retval = (-EIO); 3398 goto out; 3399 } 3400 STm = &(STp->modes[STp->current_mode]); 3401 if (!STm->defined) { 3402 retval = (-ENXIO); 3403 goto out; 3404 } 3405 if (count == 0) 3406 goto out; 3407 3408 /* 3409 * If there was a bus reset, block further access 3410 * to this device. 3411 */ 3412 if (STp->pos_unknown) { 3413 retval = (-EIO); 3414 goto out; 3415 } 3416 3417 #if DEBUG 3418 if (!STp->in_use) { 3419 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name); 3420 retval = (-EIO); 3421 goto out; 3422 } 3423 #endif 3424 3425 if (STp->write_prot) { 3426 retval = (-EACCES); 3427 goto out; 3428 } 3429 3430 /* Write must be integral number of blocks */ 3431 if (STp->block_size != 0 && (count % STp->block_size) != 0) { 3432 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n", 3433 name, count, STp->block_size<1024? 3434 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k'); 3435 retval = (-EINVAL); 3436 goto out; 3437 } 3438 3439 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) { 3440 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n", 3441 name, STp->first_frame_position); 3442 retval = (-ENOSPC); 3443 goto out; 3444 } 3445 3446 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1)) 3447 STp->door_locked = ST_LOCKED_AUTO; 3448 3449 STps = &(STp->ps[STp->partition]); 3450 3451 if (STps->rw == ST_READING) { 3452 #if DEBUG 3453 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name, 3454 STps->drv_file, STps->drv_block); 3455 #endif 3456 retval = osst_flush_buffer(STp, &SRpnt, 0); 3457 if (retval) 3458 goto out; 3459 STps->rw = ST_IDLE; 3460 } 3461 if (STps->rw != ST_WRITING) { 3462 /* Are we totally rewriting this tape? */ 3463 if (!STp->header_ok || 3464 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) || 3465 (STps->drv_file == 0 && STps->drv_block == 0)) { 3466 STp->wrt_pass_cntr++; 3467 #if DEBUG 3468 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n", 3469 name, STp->wrt_pass_cntr); 3470 #endif 3471 osst_reset_header(STp, &SRpnt); 3472 STps->drv_file = STps->drv_block = 0; 3473 } 3474 /* Do we know where we'll be writing on the tape? */ 3475 else { 3476 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) || 3477 STps->drv_file < 0 || STps->drv_block < 0) { 3478 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */ 3479 STps->drv_file = STp->filemark_cnt; 3480 STps->drv_block = 0; 3481 } 3482 else { 3483 /* We have no idea where the tape is positioned - give up */ 3484 #if DEBUG 3485 printk(OSST_DEB_MSG 3486 "%s:D: Cannot write at indeterminate position.\n", name); 3487 #endif 3488 retval = (-EIO); 3489 goto out; 3490 } 3491 } 3492 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) { 3493 STp->filemark_cnt = STps->drv_file; 3494 STp->last_mark_ppos = 3495 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]); 3496 printk(KERN_WARNING 3497 "%s:W: Overwriting file %d with old write pass counter %d\n", 3498 name, STps->drv_file, STp->wrt_pass_cntr); 3499 printk(KERN_WARNING 3500 "%s:W: may lead to stale data being accepted on reading back!\n", 3501 name); 3502 #if DEBUG 3503 printk(OSST_DEB_MSG 3504 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n", 3505 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn); 3506 #endif 3507 } 3508 } 3509 STp->fast_open = 0; 3510 } 3511 if (!STp->header_ok) { 3512 #if DEBUG 3513 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name); 3514 #endif 3515 retval = (-EIO); 3516 goto out; 3517 } 3518 3519 if ((STp->buffer)->writing) { 3520 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__); 3521 osst_write_behind_check(STp); 3522 if ((STp->buffer)->syscall_result) { 3523 #if DEBUG 3524 if (debugging) 3525 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name, 3526 (STp->buffer)->midlevel_result); 3527 #endif 3528 if ((STp->buffer)->midlevel_result == INT_MAX) 3529 STps->eof = ST_EOM_OK; 3530 else 3531 STps->eof = ST_EOM_ERROR; 3532 } 3533 } 3534 if (STps->eof == ST_EOM_OK) { 3535 retval = (-ENOSPC); 3536 goto out; 3537 } 3538 else if (STps->eof == ST_EOM_ERROR) { 3539 retval = (-EIO); 3540 goto out; 3541 } 3542 3543 /* Check the buffer readability in cases where copy_user might catch 3544 the problems after some tape movement. */ 3545 if ((copy_from_user(&i, buf, 1) != 0 || 3546 copy_from_user(&i, buf + count - 1, 1) != 0)) { 3547 retval = (-EFAULT); 3548 goto out; 3549 } 3550 3551 if (!STm->do_buffer_writes) { 3552 write_threshold = 1; 3553 } 3554 else 3555 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size; 3556 if (!STm->do_async_writes) 3557 write_threshold--; 3558 3559 total = count; 3560 #if DEBUG 3561 if (debugging) 3562 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n", 3563 name, (int) count, STps->drv_file, STps->drv_block, 3564 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position); 3565 #endif 3566 b_point = buf; 3567 while ((STp->buffer)->buffer_bytes + count > write_threshold) 3568 { 3569 doing_write = 1; 3570 do_count = (STp->buffer)->buffer_blocks * STp->block_size - 3571 (STp->buffer)->buffer_bytes; 3572 if (do_count > count) 3573 do_count = count; 3574 3575 i = append_to_buffer(b_point, STp->buffer, do_count); 3576 if (i) { 3577 retval = i; 3578 goto out; 3579 } 3580 3581 blks = do_count / STp->block_size; 3582 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */ 3583 3584 i = osst_write_frame(STp, &SRpnt, 1); 3585 3586 if (i == (-ENOSPC)) { 3587 transfer = STp->buffer->writing; /* FIXME -- check this logic */ 3588 if (transfer <= do_count) { 3589 filp->f_pos += do_count - transfer; 3590 count -= do_count - transfer; 3591 if (STps->drv_block >= 0) { 3592 STps->drv_block += (do_count - transfer) / STp->block_size; 3593 } 3594 STps->eof = ST_EOM_OK; 3595 retval = (-ENOSPC); /* EOM within current request */ 3596 #if DEBUG 3597 if (debugging) 3598 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n", 3599 name, (int) transfer); 3600 #endif 3601 } 3602 else { 3603 STps->eof = ST_EOM_ERROR; 3604 STps->drv_block = (-1); /* Too cautious? */ 3605 retval = (-EIO); /* EOM for old data */ 3606 #if DEBUG 3607 if (debugging) 3608 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name); 3609 #endif 3610 } 3611 } 3612 else 3613 retval = i; 3614 3615 if (retval < 0) { 3616 if (SRpnt != NULL) { 3617 osst_release_request(SRpnt); 3618 SRpnt = NULL; 3619 } 3620 STp->buffer->buffer_bytes = 0; 3621 STp->dirty = 0; 3622 if (count < total) 3623 retval = total - count; 3624 goto out; 3625 } 3626 3627 filp->f_pos += do_count; 3628 b_point += do_count; 3629 count -= do_count; 3630 if (STps->drv_block >= 0) { 3631 STps->drv_block += blks; 3632 } 3633 STp->buffer->buffer_bytes = 0; 3634 STp->dirty = 0; 3635 } /* end while write threshold exceeded */ 3636 3637 if (count != 0) { 3638 STp->dirty = 1; 3639 i = append_to_buffer(b_point, STp->buffer, count); 3640 if (i) { 3641 retval = i; 3642 goto out; 3643 } 3644 blks = count / STp->block_size; 3645 STp->logical_blk_num += blks; 3646 if (STps->drv_block >= 0) { 3647 STps->drv_block += blks; 3648 } 3649 filp->f_pos += count; 3650 count = 0; 3651 } 3652 3653 if (doing_write && (STp->buffer)->syscall_result != 0) { 3654 retval = (STp->buffer)->syscall_result; 3655 goto out; 3656 } 3657 3658 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) { 3659 /* Schedule an asynchronous write */ 3660 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes / 3661 STp->block_size) * STp->block_size; 3662 STp->dirty = !((STp->buffer)->writing == 3663 (STp->buffer)->buffer_bytes); 3664 3665 i = osst_write_frame(STp, &SRpnt, 0); 3666 if (i < 0) { 3667 retval = (-EIO); 3668 goto out; 3669 } 3670 SRpnt = NULL; /* Prevent releasing this request! */ 3671 } 3672 STps->at_sm &= (total == 0); 3673 if (total > 0) 3674 STps->eof = ST_NOEOF; 3675 3676 retval = total; 3677 3678 out: 3679 if (SRpnt != NULL) osst_release_request(SRpnt); 3680 3681 mutex_unlock(&STp->lock); 3682 3683 return retval; 3684 } 3685 3686 3687 /* Read command */ 3688 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos) 3689 { 3690 ssize_t total, retval = 0; 3691 ssize_t i, transfer; 3692 int special; 3693 struct st_modedef * STm; 3694 struct st_partstat * STps; 3695 struct osst_request * SRpnt = NULL; 3696 struct osst_tape * STp = filp->private_data; 3697 char * name = tape_name(STp); 3698 3699 3700 if (mutex_lock_interruptible(&STp->lock)) 3701 return (-ERESTARTSYS); 3702 3703 /* 3704 * If we are in the middle of error recovery, don't let anyone 3705 * else try and use this device. Also, if error recovery fails, it 3706 * may try and take the device offline, in which case all further 3707 * access to the device is prohibited. 3708 */ 3709 if( !scsi_block_when_processing_errors(STp->device) ) { 3710 retval = (-ENXIO); 3711 goto out; 3712 } 3713 3714 if (STp->ready != ST_READY) { 3715 if (STp->ready == ST_NO_TAPE) 3716 retval = (-ENOMEDIUM); 3717 else 3718 retval = (-EIO); 3719 goto out; 3720 } 3721 STm = &(STp->modes[STp->current_mode]); 3722 if (!STm->defined) { 3723