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 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 26static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 Exp $"; 27static 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/slab.h> 42#include <linux/init.h> 43#include <linux/string.h> 44#include <linux/errno.h> 45#include <linux/mtio.h> 46#include <linux/ioctl.h> 47#include <linux/fcntl.h> 48#include <linux/spinlock.h> 49#include <linux/vmalloc.h> 50#include <linux/blkdev.h> 51#include <linux/moduleparam.h> 52#include <linux/delay.h> 53#include <linux/jiffies.h> 54#include <linux/smp_lock.h> 55#include <asm/uaccess.h> 56#include <asm/dma.h> 57#include <asm/system.h> 58 59/* The driver prints some debugging information on the console if DEBUG 60 is defined and non-zero. */ 61#define DEBUG 0 62 63/* The message level for the debug messages is currently set to KERN_NOTICE 64 so that people can easily see the messages. Later when the debugging messages 65 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */ 66#define OSST_DEB_MSG KERN_NOTICE 67 68#include <scsi/scsi.h> 69#include <scsi/scsi_dbg.h> 70#include <scsi/scsi_device.h> 71#include <scsi/scsi_driver.h> 72#include <scsi/scsi_eh.h> 73#include <scsi/scsi_host.h> 74#include <scsi/scsi_ioctl.h> 75 76#define ST_KILOBYTE 1024 77 78#include "st.h" 79#include "osst.h" 80#include "osst_options.h" 81#include "osst_detect.h" 82 83static int max_dev = 0; 84static int write_threshold_kbs = 0; 85static int max_sg_segs = 0; 86 87#ifdef MODULE 88MODULE_AUTHOR("Willem Riede"); 89MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver"); 90MODULE_LICENSE("GPL"); 91MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR); 92MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE); 93 94module_param(max_dev, int, 0444); 95MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)"); 96 97module_param(write_threshold_kbs, int, 0644); 98MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)"); 99 100module_param(max_sg_segs, int, 0644); 101MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)"); 102#else 103static struct osst_dev_parm { 104 char *name; 105 int *val; 106} parms[] __initdata = { 107 { "max_dev", &max_dev }, 108 { "write_threshold_kbs", &write_threshold_kbs }, 109 { "max_sg_segs", &max_sg_segs } 110}; 111#endif 112 113/* Some default definitions have been moved to osst_options.h */ 114#define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE) 115#define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE) 116 117/* The buffer size should fit into the 24 bits for length in the 118 6-byte SCSI read and write commands. */ 119#if OSST_BUFFER_SIZE >= (2 << 24 - 1) 120#error "Buffer size should not exceed (2 << 24 - 1) bytes!" 121#endif 122 123#if DEBUG 124static int debugging = 1; 125/* uncomment define below to test error recovery */ 126// #define OSST_INJECT_ERRORS 1 127#endif 128 129/* Do not retry! The drive firmware already retries when appropriate, 130 and when it tries to tell us something, we had better listen... */ 131#define MAX_RETRIES 0 132 133#define NO_TAPE NOT_READY 134 135#define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1) 136#define OSST_WAIT_WRITE_COMPLETE (HZ / 12) 137#define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2) 138 139#define OSST_TIMEOUT (200 * HZ) 140#define OSST_LONG_TIMEOUT (1800 * HZ) 141 142#define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT)) 143#define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT) 144#define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0) 145#define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1)) 146 147/* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower 148 24 bits) */ 149#define SET_DENS_AND_BLK 0x10001 150 151static int osst_buffer_size = OSST_BUFFER_SIZE; 152static int osst_write_threshold = OSST_WRITE_THRESHOLD; 153static int osst_max_sg_segs = OSST_MAX_SG; 154static int osst_max_dev = OSST_MAX_TAPES; 155static int osst_nr_dev; 156 157static struct osst_tape **os_scsi_tapes = NULL; 158static DEFINE_RWLOCK(os_scsi_tapes_lock); 159 160static int modes_defined = 0; 161 162static struct osst_buffer *new_tape_buffer(int, int, int); 163static int enlarge_buffer(struct osst_buffer *, int); 164static void normalize_buffer(struct osst_buffer *); 165static int append_to_buffer(const char __user *, struct osst_buffer *, int); 166static int from_buffer(struct osst_buffer *, char __user *, int); 167static int osst_zero_buffer_tail(struct osst_buffer *); 168static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *); 169static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *); 170 171static int osst_probe(struct device *); 172static int osst_remove(struct device *); 173 174static struct scsi_driver osst_template = { 175 .owner = THIS_MODULE, 176 .gendrv = { 177 .name = "osst", 178 .probe = osst_probe, 179 .remove = osst_remove, 180 } 181}; 182 183static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt, 184 unsigned int cmd_in, unsigned long arg); 185 186static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip); 187 188static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt); 189 190static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt); 191 192static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending); 193 194static inline char *tape_name(struct osst_tape *tape) 195{ 196 return tape->drive->disk_name; 197} 198 199/* Routines that handle the interaction with mid-layer SCSI routines */ 200 201 202/* Normalize Sense */ 203static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s) 204{ 205 const u8 *ucp; 206 const u8 *sense = SRpnt->sense; 207 208 s->have_sense = scsi_normalize_sense(SRpnt->sense, 209 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr); 210 s->flags = 0; 211 212 if (s->have_sense) { 213 s->deferred = 0; 214 s->remainder_valid = 215 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64); 216 switch (sense[0] & 0x7f) { 217 case 0x71: 218 s->deferred = 1; 219 case 0x70: 220 s->fixed_format = 1; 221 s->flags = sense[2] & 0xe0; 222 break; 223 case 0x73: 224 s->deferred = 1; 225 case 0x72: 226 s->fixed_format = 0; 227 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4); 228 s->flags = ucp ? (ucp[3] & 0xe0) : 0; 229 break; 230 } 231 } 232} 233 234/* Convert the result to success code */ 235static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt) 236{ 237 char *name = tape_name(STp); 238 int result = SRpnt->result; 239 u8 * sense = SRpnt->sense, scode; 240#if DEBUG 241 const char *stp; 242#endif 243 struct st_cmdstatus *cmdstatp; 244 245 if (!result) 246 return 0; 247 248 cmdstatp = &STp->buffer->cmdstat; 249 osst_analyze_sense(SRpnt, cmdstatp); 250 251 if (cmdstatp->have_sense) 252 scode = STp->buffer->cmdstat.sense_hdr.sense_key; 253 else 254 scode = 0; 255#if DEBUG 256 if (debugging) { 257 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n", 258 name, result, 259 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2], 260 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]); 261 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n", 262 name, scode, sense[12], sense[13]); 263 if (cmdstatp->have_sense) 264 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); 265 } 266 else 267#endif 268 if (cmdstatp->have_sense && ( 269 scode != NO_SENSE && 270 scode != RECOVERED_ERROR && 271/* scode != UNIT_ATTENTION && */ 272 scode != BLANK_CHECK && 273 scode != VOLUME_OVERFLOW && 274 SRpnt->cmd[0] != MODE_SENSE && 275 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */ 276 if (cmdstatp->have_sense) { 277 printk(KERN_WARNING "%s:W: Command with sense data:\n", name); 278 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); 279 } 280 else { 281 static int notyetprinted = 1; 282 283 printk(KERN_WARNING 284 "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n", 285 name, result, driver_byte(result), 286 host_byte(result)); 287 if (notyetprinted) { 288 notyetprinted = 0; 289 printk(KERN_INFO 290 "%s:I: This warning may be caused by your scsi controller,\n", name); 291 printk(KERN_INFO 292 "%s:I: it has been reported with some Buslogic cards.\n", name); 293 } 294 } 295 } 296 STp->pos_unknown |= STp->device->was_reset; 297 298 if (cmdstatp->have_sense && scode == RECOVERED_ERROR) { 299 STp->recover_count++; 300 STp->recover_erreg++; 301#if DEBUG 302 if (debugging) { 303 if (SRpnt->cmd[0] == READ_6) 304 stp = "read"; 305 else if (SRpnt->cmd[0] == WRITE_6) 306 stp = "write"; 307 else 308 stp = "ioctl"; 309 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp, 310 STp->recover_count); 311 } 312#endif 313 if ((sense[2] & 0xe0) == 0) 314 return 0; 315 } 316 return (-EIO); 317} 318 319 320/* Wakeup from interrupt */ 321static void osst_end_async(struct request *req, int update) 322{ 323 struct osst_request *SRpnt = req->end_io_data; 324 struct osst_tape *STp = SRpnt->stp; 325 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; 326 327 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors; 328#if DEBUG 329 STp->write_pending = 0; 330#endif 331 if (SRpnt->waiting) 332 complete(SRpnt->waiting); 333 334 if (SRpnt->bio) { 335 kfree(mdata->pages); 336 blk_rq_unmap_user(SRpnt->bio); 337 } 338 339 __blk_put_request(req->q, req); 340} 341 342/* osst_request memory management */ 343static struct osst_request *osst_allocate_request(void) 344{ 345 return kzalloc(sizeof(struct osst_request), GFP_KERNEL); 346} 347 348static void osst_release_request(struct osst_request *streq) 349{ 350 kfree(streq); 351} 352 353static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd, 354 int cmd_len, int data_direction, void *buffer, unsigned bufflen, 355 int use_sg, int timeout, int retries) 356{ 357 struct request *req; 358 struct page **pages = NULL; 359 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; 360 361 int err = 0; 362 int write = (data_direction == DMA_TO_DEVICE); 363 364 req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL); 365 if (!req) 366 return DRIVER_ERROR << 24; 367 368 req->cmd_type = REQ_TYPE_BLOCK_PC; 369 req->cmd_flags |= REQ_QUIET; 370 371 SRpnt->bio = NULL; 372 373 if (use_sg) { 374 struct scatterlist *sg, *sgl = (struct scatterlist *)buffer; 375 int i; 376 377 pages = kzalloc(use_sg * sizeof(struct page *), GFP_KERNEL); 378 if (!pages) 379 goto free_req; 380 381 for_each_sg(sgl, sg, use_sg, i) 382 pages[i] = sg_page(sg); 383 384 mdata->null_mapped = 1; 385 386 mdata->page_order = get_order(sgl[0].length); 387 mdata->nr_entries = 388 DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order); 389 mdata->offset = 0; 390 391 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL); 392 if (err) { 393 kfree(pages); 394 goto free_req; 395 } 396 SRpnt->bio = req->bio; 397 mdata->pages = pages; 398 399 } else if (bufflen) { 400 err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL); 401 if (err) 402 goto free_req; 403 } 404 405 req->cmd_len = cmd_len; 406 memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ 407 memcpy(req->cmd, cmd, req->cmd_len); 408 req->sense = SRpnt->sense; 409 req->sense_len = 0; 410 req->timeout = timeout; 411 req->retries = retries; 412 req->end_io_data = SRpnt; 413 414 blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async); 415 return 0; 416free_req: 417 blk_put_request(req); 418 return DRIVER_ERROR << 24; 419} 420 421/* Do the scsi command. Waits until command performed if do_wait is true. 422 Otherwise osst_write_behind_check() is used to check that the command 423 has finished. */ 424static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp, 425 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait) 426{ 427 unsigned char *bp; 428 unsigned short use_sg; 429#ifdef OSST_INJECT_ERRORS 430 static int inject = 0; 431 static int repeat = 0; 432#endif 433 struct completion *waiting; 434 435 /* if async, make sure there's no command outstanding */ 436 if (!do_wait && ((STp->buffer)->last_SRpnt)) { 437 printk(KERN_ERR "%s: Async command already active.\n", 438 tape_name(STp)); 439 if (signal_pending(current)) 440 (STp->buffer)->syscall_result = (-EINTR); 441 else 442 (STp->buffer)->syscall_result = (-EBUSY); 443 return NULL; 444 } 445 446 if (SRpnt == NULL) { 447 SRpnt = osst_allocate_request(); 448 if (SRpnt == NULL) { 449 printk(KERN_ERR "%s: Can't allocate SCSI request.\n", 450 tape_name(STp)); 451 if (signal_pending(current)) 452 (STp->buffer)->syscall_result = (-EINTR); 453 else 454 (STp->buffer)->syscall_result = (-EBUSY); 455 return NULL; 456 } 457 SRpnt->stp = STp; 458 } 459 460 /* If async IO, set last_SRpnt. This ptr tells write_behind_check 461 which IO is outstanding. It's nulled out when the IO completes. */ 462 if (!do_wait) 463 (STp->buffer)->last_SRpnt = SRpnt; 464 465 waiting = &STp->wait; 466 init_completion(waiting); 467 SRpnt->waiting = waiting; 468 469 use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0; 470 if (use_sg) { 471 bp = (char *)&(STp->buffer->sg[0]); 472 if (STp->buffer->sg_segs < use_sg) 473 use_sg = STp->buffer->sg_segs; 474 } 475 else 476 bp = (STp->buffer)->b_data; 477 478 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd)); 479 STp->buffer->cmdstat.have_sense = 0; 480 STp->buffer->syscall_result = 0; 481 482 if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes, 483 use_sg, timeout, retries)) 484 /* could not allocate the buffer or request was too large */ 485 (STp->buffer)->syscall_result = (-EBUSY); 486 else if (do_wait) { 487 wait_for_completion(waiting); 488 SRpnt->waiting = NULL; 489 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt); 490#ifdef OSST_INJECT_ERRORS 491 if (STp->buffer->syscall_result == 0 && 492 cmd[0] == READ_6 && 493 cmd[4] && 494 ( (++ inject % 83) == 29 || 495 (STp->first_frame_position == 240 496 /* or STp->read_error_frame to fail again on the block calculated above */ && 497 ++repeat < 3))) { 498 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp)); 499 STp->buffer->last_result_fatal = 1; 500 } 501#endif 502 } 503 return SRpnt; 504} 505 506 507/* Handle the write-behind checking (downs the semaphore) */ 508static void osst_write_behind_check(struct osst_tape *STp) 509{ 510 struct osst_buffer * STbuffer; 511 512 STbuffer = STp->buffer; 513 514#if DEBUG 515 if (STp->write_pending) 516 STp->nbr_waits++; 517 else 518 STp->nbr_finished++; 519#endif 520 wait_for_completion(&(STp->wait)); 521 STp->buffer->last_SRpnt->waiting = NULL; 522 523 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt); 524 525 if (STp->buffer->syscall_result) 526 STp->buffer->syscall_result = 527 osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1); 528 else 529 STp->first_frame_position++; 530 531 osst_release_request(STp->buffer->last_SRpnt); 532 533 if (STbuffer->writing < STbuffer->buffer_bytes) 534 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n"); 535 536 STbuffer->last_SRpnt = NULL; 537 STbuffer->buffer_bytes -= STbuffer->writing; 538 STbuffer->writing = 0; 539 540 return; 541} 542 543 544 545/* Onstream specific Routines */ 546/* 547 * Initialize the OnStream AUX 548 */ 549static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number, 550 int logical_blk_num, int blk_sz, int blk_cnt) 551{ 552 os_aux_t *aux = STp->buffer->aux; 553 os_partition_t *par = &aux->partition; 554 os_dat_t *dat = &aux->dat; 555 556 if (STp->raw) return; 557 558 memset(aux, 0, sizeof(*aux)); 559 aux->format_id = htonl(0); 560 memcpy(aux->application_sig, "LIN4", 4); 561 aux->hdwr = htonl(0); 562 aux->frame_type = frame_type; 563 564 switch (frame_type) { 565 case OS_FRAME_TYPE_HEADER: 566 aux->update_frame_cntr = htonl(STp->update_frame_cntr); 567 par->partition_num = OS_CONFIG_PARTITION; 568 par->par_desc_ver = OS_PARTITION_VERSION; 569 par->wrt_pass_cntr = htons(0xffff); 570 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */ 571 par->first_frame_ppos = htonl(0); 572 par->last_frame_ppos = htonl(0xbb7); 573 aux->frame_seq_num = htonl(0); 574 aux->logical_blk_num_high = htonl(0); 575 aux->logical_blk_num = htonl(0); 576 aux->next_mark_ppos = htonl(STp->first_mark_ppos); 577 break; 578 case OS_FRAME_TYPE_DATA: 579 case OS_FRAME_TYPE_MARKER: 580 dat->dat_sz = 8; 581 dat->reserved1 = 0; 582 dat->entry_cnt = 1; 583 dat->reserved3 = 0; 584 dat->dat_list[0].blk_sz = htonl(blk_sz); 585 dat->dat_list[0].blk_cnt = htons(blk_cnt); 586 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER? 587 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA; 588 dat->dat_list[0].reserved = 0; 589 case OS_FRAME_TYPE_EOD: 590 aux->update_frame_cntr = htonl(0); 591 par->partition_num = OS_DATA_PARTITION; 592 par->par_desc_ver = OS_PARTITION_VERSION; 593 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr); 594 par->first_frame_ppos = htonl(STp->first_data_ppos); 595 par->last_frame_ppos = htonl(STp->capacity); 596 aux->frame_seq_num = htonl(frame_seq_number); 597 aux->logical_blk_num_high = htonl(0); 598 aux->logical_blk_num = htonl(logical_blk_num); 599 break; 600 default: ; /* probably FILL */ 601 } 602 aux->filemark_cnt = htonl(STp->filemark_cnt); 603 aux->phys_fm = htonl(0xffffffff); 604 aux->last_mark_ppos = htonl(STp->last_mark_ppos); 605 aux->last_mark_lbn = htonl(STp->last_mark_lbn); 606} 607 608/* 609 * Verify that we have the correct tape frame 610 */ 611static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet) 612{ 613 char * name = tape_name(STp); 614 os_aux_t * aux = STp->buffer->aux; 615 os_partition_t * par = &(aux->partition); 616 struct st_partstat * STps = &(STp->ps[STp->partition]); 617 int blk_cnt, blk_sz, i; 618 619 if (STp->raw) { 620 if (STp->buffer->syscall_result) { 621 for (i=0; i < STp->buffer->sg_segs; i++) 622 memset(page_address(sg_page(&STp->buffer->sg[i])), 623 0, STp->buffer->sg[i].length); 624 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME"); 625 } else 626 STp->buffer->buffer_bytes = OS_FRAME_SIZE; 627 return 1; 628 } 629 if (STp->buffer->syscall_result) { 630#if DEBUG 631 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name); 632#endif 633 return 0; 634 } 635 if (ntohl(aux->format_id) != 0) { 636#if DEBUG 637 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id)); 638#endif 639 goto err_out; 640 } 641 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 && 642 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) { 643#if DEBUG 644 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name); 645#endif 646 goto err_out; 647 } 648 if (par->partition_num != OS_DATA_PARTITION) { 649 if (!STp->linux_media || STp->linux_media_version != 2) { 650#if DEBUG 651 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n", 652 name, par->partition_num); 653#endif 654 goto err_out; 655 } 656 } 657 if (par->par_desc_ver != OS_PARTITION_VERSION) { 658#if DEBUG 659 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver); 660#endif 661 goto err_out; 662 } 663 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) { 664#if DEBUG 665 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n", 666 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr); 667#endif 668 goto err_out; 669 } 670 if (aux->frame_type != OS_FRAME_TYPE_DATA && 671 aux->frame_type != OS_FRAME_TYPE_EOD && 672 aux->frame_type != OS_FRAME_TYPE_MARKER) { 673 if (!quiet) { 674#if DEBUG 675 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type); 676#endif 677 } 678 goto err_out; 679 } 680 if (aux->frame_type == OS_FRAME_TYPE_EOD && 681 STp->first_frame_position < STp->eod_frame_ppos) { 682 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name, 683 STp->first_frame_position); 684 goto err_out; 685 } 686 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) { 687 if (!quiet) { 688#if DEBUG 689 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n", 690 name, ntohl(aux->frame_seq_num), frame_seq_number); 691#endif 692 } 693 goto err_out; 694 } 695 if (aux->frame_type == OS_FRAME_TYPE_MARKER) { 696 STps->eof = ST_FM_HIT; 697 698 i = ntohl(aux->filemark_cnt); 699 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt || 700 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) { 701#if DEBUG 702 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name, 703 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected", 704 i, STp->first_frame_position - 1); 705#endif 706 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1); 707 if (i >= STp->filemark_cnt) 708 STp->filemark_cnt = i+1; 709 } 710 } 711 if (aux->frame_type == OS_FRAME_TYPE_EOD) { 712 STps->eof = ST_EOD_1; 713 STp->frame_in_buffer = 1; 714 } 715 if (aux->frame_type == OS_FRAME_TYPE_DATA) { 716 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt); 717 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz); 718 STp->buffer->buffer_bytes = blk_cnt * blk_sz; 719 STp->buffer->read_pointer = 0; 720 STp->frame_in_buffer = 1; 721 722 /* See what block size was used to write file */ 723 if (STp->block_size != blk_sz && blk_sz > 0) { 724 printk(KERN_INFO 725 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n", 726 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k', 727 STp->block_size<1024?STp->block_size:STp->block_size/1024, 728 STp->block_size<1024?'b':'k'); 729 STp->block_size = blk_sz; 730 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz; 731 } 732 STps->eof = ST_NOEOF; 733 } 734 STp->frame_seq_number = ntohl(aux->frame_seq_num); 735 STp->logical_blk_num = ntohl(aux->logical_blk_num); 736 return 1; 737 738err_out: 739 if (STp->read_error_frame == 0) 740 STp->read_error_frame = STp->first_frame_position - 1; 741 return 0; 742} 743 744/* 745 * Wait for the unit to become Ready 746 */ 747static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt, 748 unsigned timeout, int initial_delay) 749{ 750 unsigned char cmd[MAX_COMMAND_SIZE]; 751 struct osst_request * SRpnt; 752 unsigned long startwait = jiffies; 753#if DEBUG 754 int dbg = debugging; 755 char * name = tape_name(STp); 756 757 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name); 758#endif 759 760 if (initial_delay > 0) 761 msleep(jiffies_to_msecs(initial_delay)); 762 763 memset(cmd, 0, MAX_COMMAND_SIZE); 764 cmd[0] = TEST_UNIT_READY; 765 766 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 767 *aSRpnt = SRpnt; 768 if (!SRpnt) return (-EBUSY); 769 770 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) && 771 (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 && 772 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) || 773 ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 && 774 SRpnt->sense[13] == 0 ) )) { 775#if DEBUG 776 if (debugging) { 777 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name); 778 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 779 debugging = 0; 780 } 781#endif 782 msleep(100); 783 784 memset(cmd, 0, MAX_COMMAND_SIZE); 785 cmd[0] = TEST_UNIT_READY; 786 787 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 788 } 789 *aSRpnt = SRpnt; 790#if DEBUG 791 debugging = dbg; 792#endif 793 if ( STp->buffer->syscall_result && 794 osst_write_error_recovery(STp, aSRpnt, 0) ) { 795#if DEBUG 796 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name); 797 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name, 798 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2], 799 SRpnt->sense[12], SRpnt->sense[13]); 800#endif 801 return (-EIO); 802 } 803#if DEBUG 804 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name); 805#endif 806 return 0; 807} 808 809/* 810 * Wait for a tape to be inserted in the unit 811 */ 812static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout) 813{ 814 unsigned char cmd[MAX_COMMAND_SIZE]; 815 struct osst_request * SRpnt; 816 unsigned long startwait = jiffies; 817#if DEBUG 818 int dbg = debugging; 819 char * name = tape_name(STp); 820 821 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name); 822#endif 823 824 memset(cmd, 0, MAX_COMMAND_SIZE); 825 cmd[0] = TEST_UNIT_READY; 826 827 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 828 *aSRpnt = SRpnt; 829 if (!SRpnt) return (-EBUSY); 830 831 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) && 832 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) { 833#if DEBUG 834 if (debugging) { 835 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name); 836 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 837 debugging = 0; 838 } 839#endif 840 msleep(100); 841 842 memset(cmd, 0, MAX_COMMAND_SIZE); 843 cmd[0] = TEST_UNIT_READY; 844 845 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 846 } 847 *aSRpnt = SRpnt; 848#if DEBUG 849 debugging = dbg; 850#endif 851 if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 && 852 SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) { 853#if DEBUG 854 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name); 855 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name, 856 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2], 857 SRpnt->sense[12], SRpnt->sense[13]); 858#endif 859 return 0; 860 } 861#if DEBUG 862 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name); 863#endif 864 return 1; 865} 866 867static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame) 868{ 869 int retval; 870 871 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */ 872 retval = osst_set_frame_position(STp, aSRpnt, frame, 0); 873 if (retval) return (retval); 874 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE); 875 return (osst_get_frame_position(STp, aSRpnt)); 876} 877 878/* 879 * Wait for write(s) to complete 880 */ 881static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt) 882{ 883 unsigned char cmd[MAX_COMMAND_SIZE]; 884 struct osst_request * SRpnt; 885 int result = 0; 886 int delay = OSST_WAIT_WRITE_COMPLETE; 887#if DEBUG 888 char * name = tape_name(STp); 889 890 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name); 891#endif 892 893 memset(cmd, 0, MAX_COMMAND_SIZE); 894 cmd[0] = WRITE_FILEMARKS; 895 cmd[1] = 1; 896 897 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 898 *aSRpnt = SRpnt; 899 if (!SRpnt) return (-EBUSY); 900 if (STp->buffer->syscall_result) { 901 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) { 902 if (SRpnt->sense[13] == 8) { 903 delay = OSST_WAIT_LONG_WRITE_COMPLETE; 904 } 905 } else 906 result = osst_write_error_recovery(STp, aSRpnt, 0); 907 } 908 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay); 909 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE; 910 911 return (result); 912} 913 914#define OSST_POLL_PER_SEC 10 915static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to) 916{ 917 unsigned long startwait = jiffies; 918 char * name = tape_name(STp); 919#if DEBUG 920 char notyetprinted = 1; 921#endif 922 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING) 923 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name); 924 925 while (time_before (jiffies, startwait + to*HZ)) 926 { 927 int result; 928 result = osst_get_frame_position(STp, aSRpnt); 929 if (result == -EIO) 930 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0) 931 return 0; /* successful recovery leaves drive ready for frame */ 932 if (result < 0) break; 933 if (STp->first_frame_position == curr && 934 ((minlast < 0 && 935 (signed)STp->last_frame_position > (signed)curr + minlast) || 936 (minlast >= 0 && STp->cur_frames > minlast) 937 ) && result >= 0) 938 { 939#if DEBUG 940 if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC)) 941 printk (OSST_DEB_MSG 942 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n", 943 name, curr, curr+minlast, STp->first_frame_position, 944 STp->last_frame_position, STp->cur_frames, 945 result, (jiffies-startwait)/HZ, 946 (((jiffies-startwait)%HZ)*10)/HZ); 947#endif 948 return 0; 949 } 950#if DEBUG 951 if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted) 952 { 953 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n", 954 name, curr, curr+minlast, STp->first_frame_position, 955 STp->last_frame_position, STp->cur_frames, result); 956 notyetprinted--; 957 } 958#endif 959 msleep(1000 / OSST_POLL_PER_SEC); 960 } 961#if DEBUG 962 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n", 963 name, curr, curr+minlast, STp->first_frame_position, 964 STp->last_frame_position, STp->cur_frames, 965 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ); 966#endif 967 return -EBUSY; 968} 969 970static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing) 971{ 972 struct osst_request * SRpnt; 973 unsigned char cmd[MAX_COMMAND_SIZE]; 974 unsigned long startwait = jiffies; 975 int retval = 1; 976 char * name = tape_name(STp); 977 978 if (writing) { 979 char mybuf[24]; 980 char * olddata = STp->buffer->b_data; 981 int oldsize = STp->buffer->buffer_size; 982 983 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */ 984 985 memset(cmd, 0, MAX_COMMAND_SIZE); 986 cmd[0] = WRITE_FILEMARKS; 987 cmd[1] = 1; 988 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, 989 MAX_RETRIES, 1); 990 991 while (retval && time_before (jiffies, startwait + 5*60*HZ)) { 992 993 if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) { 994 995 /* some failure - not just not-ready */ 996 retval = osst_write_error_recovery(STp, aSRpnt, 0); 997 break; 998 } 999 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC); 1000 1001 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; 1002 memset(cmd, 0, MAX_COMMAND_SIZE); 1003 cmd[0] = READ_POSITION; 1004 1005 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout, 1006 MAX_RETRIES, 1); 1007 1008 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 ); 1009 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; 1010 } 1011 if (retval) 1012 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name); 1013 } else 1014 /* TODO - figure out which error conditions can be handled */ 1015 if (STp->buffer->syscall_result) 1016 printk(KERN_WARNING 1017 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name, 1018 (*aSRpnt)->sense[ 2] & 0x0f, 1019 (*aSRpnt)->sense[12], 1020 (*aSRpnt)->sense[13]); 1021 1022 return retval; 1023} 1024 1025/* 1026 * Read the next OnStream tape frame at the current location 1027 */ 1028static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout) 1029{ 1030 unsigned char cmd[MAX_COMMAND_SIZE]; 1031 struct osst_request * SRpnt; 1032 int retval = 0; 1033#if DEBUG 1034 os_aux_t * aux = STp->buffer->aux; 1035 char * name = tape_name(STp); 1036#endif 1037 1038 if (STp->poll) 1039 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout)) 1040 retval = osst_recover_wait_frame(STp, aSRpnt, 0); 1041 1042 memset(cmd, 0, MAX_COMMAND_SIZE); 1043 cmd[0] = READ_6; 1044 cmd[1] = 1; 1045 cmd[4] = 1; 1046 1047#if DEBUG 1048 if (debugging) 1049 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name); 1050#endif 1051 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE, 1052 STp->timeout, MAX_RETRIES, 1); 1053 *aSRpnt = SRpnt; 1054 if (!SRpnt) 1055 return (-EBUSY); 1056 1057 if ((STp->buffer)->syscall_result) { 1058 retval = 1; 1059 if (STp->read_error_frame == 0) { 1060 STp->read_error_frame = STp->first_frame_position; 1061#if DEBUG 1062 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame); 1063#endif 1064 } 1065#if DEBUG 1066 if (debugging) 1067 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", 1068 name, 1069 SRpnt->sense[0], SRpnt->sense[1], 1070 SRpnt->sense[2], SRpnt->sense[3], 1071 SRpnt->sense[4], SRpnt->sense[5], 1072 SRpnt->sense[6], SRpnt->sense[7]); 1073#endif 1074 } 1075 else 1076 STp->first_frame_position++; 1077#if DEBUG 1078 if (debugging) { 1079 char sig[8]; int i; 1080 for (i=0;i<4;i++) 1081 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i]; 1082 sig[4] = '\0'; 1083 printk(OSST_DEB_MSG 1084 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig, 1085 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr), 1086 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK": 1087 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL", 1088 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num), 1089 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) ); 1090 if (aux->frame_type==2) 1091 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name, 1092 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn)); 1093 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval); 1094 } 1095#endif 1096 return (retval); 1097} 1098 1099static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt) 1100{ 1101 struct st_partstat * STps = &(STp->ps[STp->partition]); 1102 struct osst_request * SRpnt ; 1103 unsigned char cmd[MAX_COMMAND_SIZE]; 1104 int retval = 0; 1105 char * name = tape_name(STp); 1106 1107 if (STps->rw != ST_READING) { /* Initialize read operation */ 1108 if (STps->rw == ST_WRITING || STp->dirty) { 1109 STp->write_type = OS_WRITE_DATA; 1110 osst_flush_write_buffer(STp, aSRpnt); 1111 osst_flush_drive_buffer(STp, aSRpnt); 1112 } 1113 STps->rw = ST_READING; 1114 STp->frame_in_buffer = 0; 1115 1116 /* 1117 * Issue a read 0 command to get the OnStream drive 1118 * read frames into its buffer. 1119 */ 1120 memset(cmd, 0, MAX_COMMAND_SIZE); 1121 cmd[0] = READ_6; 1122 cmd[1] = 1; 1123 1124#if DEBUG 1125 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name); 1126#endif 1127 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 1128 *aSRpnt = SRpnt; 1129 if ((retval = STp->buffer->syscall_result)) 1130 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name); 1131 } 1132 1133 return retval; 1134} 1135 1136static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, 1137 int frame_seq_number, int quiet) 1138{ 1139 struct st_partstat * STps = &(STp->ps[STp->partition]); 1140 char * name = tape_name(STp); 1141 int cnt = 0, 1142 bad = 0, 1143 past = 0, 1144 x, 1145 position; 1146 1147 /* 1148 * If we want just any frame (-1) and there is a frame in the buffer, return it 1149 */ 1150 if (frame_seq_number == -1 && STp->frame_in_buffer) { 1151#if DEBUG 1152 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number); 1153#endif 1154 return (STps->eof); 1155 } 1156 /* 1157 * Search and wait for the next logical tape frame 1158 */ 1159 while (1) { 1160 if (cnt++ > 400) { 1161 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n", 1162 name, frame_seq_number); 1163 if (STp->read_error_frame) { 1164 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0); 1165#if DEBUG 1166 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n", 1167 name, STp->read_error_frame); 1168#endif 1169 STp->read_error_frame = 0; 1170 STp->abort_count++; 1171 } 1172 return (-EIO); 1173 } 1174#if DEBUG 1175 if (debugging) 1176 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n", 1177 name, frame_seq_number, cnt); 1178#endif 1179 if ( osst_initiate_read(STp, aSRpnt) 1180 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) { 1181 if (STp->raw) 1182 return (-EIO); 1183 position = osst_get_frame_position(STp, aSRpnt); 1184 if (position >= 0xbae && position < 0xbb8) 1185 position = 0xbb8; 1186 else if (position > STp->eod_frame_ppos || ++bad == 10) { 1187 position = STp->read_error_frame - 1; 1188 bad = 0; 1189 } 1190 else { 1191 position += 29; 1192 cnt += 19; 1193 } 1194#if DEBUG 1195 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n", 1196 name, position); 1197#endif 1198 osst_set_frame_position(STp, aSRpnt, position, 0); 1199 continue; 1200 } 1201 if (osst_verify_frame(STp, frame_seq_number, quiet)) 1202 break; 1203 if (osst_verify_frame(STp, -1, quiet)) { 1204 x = ntohl(STp->buffer->aux->frame_seq_num); 1205 if (STp->fast_open) { 1206 printk(KERN_WARNING 1207 "%s:W: Found logical frame %d instead of %d after fast open\n", 1208 name, x, frame_seq_number); 1209 STp->header_ok = 0; 1210 STp->read_error_frame = 0; 1211 return (-EIO); 1212 } 1213 if (x > frame_seq_number) { 1214 if (++past > 3) { 1215 /* positioning backwards did not bring us to the desired frame */ 1216 position = STp->read_error_frame - 1; 1217 } 1218 else { 1219 position = osst_get_frame_position(STp, aSRpnt) 1220 + frame_seq_number - x - 1; 1221 1222 if (STp->first_frame_position >= 3000 && position < 3000) 1223 position -= 10; 1224 } 1225#if DEBUG 1226 printk(OSST_DEB_MSG 1227 "%s:D: Found logical frame %d while looking for %d: back up %d\n", 1228 name, x, frame_seq_number, 1229 STp->first_frame_position - position); 1230#endif 1231 osst_set_frame_position(STp, aSRpnt, position, 0); 1232 cnt += 10; 1233 } 1234 else 1235 past = 0; 1236 } 1237 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) { 1238#if DEBUG 1239 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name); 1240#endif 1241 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0); 1242 cnt--; 1243 } 1244 STp->frame_in_buffer = 0; 1245 } 1246 if (cnt > 1) { 1247 STp->recover_count++; 1248 STp->recover_erreg++; 1249 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n", 1250 name, STp->read_error_frame); 1251 } 1252 STp->read_count++; 1253 1254#if DEBUG 1255 if (debugging || STps->eof) 1256 printk(OSST_DEB_MSG 1257 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n", 1258 name, frame_seq_number, STp->frame_seq_number, STps->eof); 1259#endif 1260 STp->fast_open = 0; 1261 STp->read_error_frame = 0; 1262 return (STps->eof); 1263} 1264 1265static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num) 1266{ 1267 struct st_partstat * STps = &(STp->ps[STp->partition]); 1268 char * name = tape_name(STp); 1269 int retries = 0; 1270 int frame_seq_estimate, ppos_estimate, move; 1271 1272 if (logical_blk_num < 0) logical_blk_num = 0; 1273#if DEBUG 1274 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n", 1275 name, logical_blk_num, STp->logical_blk_num, 1276 STp->block_size<1024?STp->block_size:STp->block_size/1024, 1277 STp->block_size<1024?'b':'k'); 1278#endif 1279 /* Do we know where we are? */ 1280 if (STps->drv_block >= 0) { 1281 move = logical_blk_num - STp->logical_blk_num; 1282 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; 1283 move /= (OS_DATA_SIZE / STp->block_size); 1284 frame_seq_estimate = STp->frame_seq_number + move; 1285 } else 1286 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE; 1287 1288 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10; 1289 else ppos_estimate = frame_seq_estimate + 20; 1290 while (++retries < 10) { 1291 if (ppos_estimate > STp->eod_frame_ppos-2) { 1292 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate; 1293 ppos_estimate = STp->eod_frame_ppos - 2; 1294 } 1295 if (frame_seq_estimate < 0) { 1296 frame_seq_estimate = 0; 1297 ppos_estimate = 10; 1298 } 1299 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0); 1300 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) { 1301 /* we've located the estimated frame, now does it have our block? */ 1302 if (logical_blk_num < STp->logical_blk_num || 1303 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) { 1304 if (STps->eof == ST_FM_HIT) 1305 move = logical_blk_num < STp->logical_blk_num? -2 : 1; 1306 else { 1307 move = logical_blk_num - STp->logical_blk_num; 1308 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; 1309 move /= (OS_DATA_SIZE / STp->block_size); 1310 } 1311 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1; 1312#if DEBUG 1313 printk(OSST_DEB_MSG 1314 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n", 1315 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 1316 STp->logical_blk_num, logical_blk_num, move); 1317#endif 1318 frame_seq_estimate += move; 1319 ppos_estimate += move; 1320 continue; 1321 } else { 1322 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size; 1323 STp->buffer->buffer_bytes -= STp->buffer->read_pointer; 1324 STp->logical_blk_num = logical_blk_num; 1325#if DEBUG 1326 printk(OSST_DEB_MSG 1327 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n", 1328 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer, 1329 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size, 1330 STp->block_size); 1331#endif 1332 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt); 1333 if (STps->eof == ST_FM_HIT) { 1334 STps->drv_file++; 1335 STps->drv_block = 0; 1336 } else { 1337 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)? 1338 STp->logical_blk_num - 1339 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0): 1340 -1; 1341 } 1342 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF; 1343 return 0; 1344 } 1345 } 1346 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0) 1347 goto error; 1348 /* we are not yet at the estimated frame, adjust our estimate of its physical position */ 1349#if DEBUG 1350 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n", 1351 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 1352 STp->logical_blk_num, logical_blk_num); 1353#endif 1354 if (frame_seq_estimate != STp->frame_seq_number) 1355 ppos_estimate += frame_seq_estimate - STp->frame_seq_number; 1356 else 1357 break; 1358 } 1359error: 1360 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n", 1361 name, logical_blk_num, STp->logical_blk_num, retries); 1362 return (-EIO); 1363} 1364 1365/* The values below are based on the OnStream frame payload size of 32K == 2**15, 1366 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block 1367 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions 1368 * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1. 1369 */ 1370#define OSST_FRAME_SHIFT 6 1371#define OSST_SECTOR_SHIFT 9 1372#define OSST_SECTOR_MASK 0x03F 1373 1374static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt) 1375{ 1376 int sector; 1377#if DEBUG 1378 char * name = tape_name(STp); 1379 1380 printk(OSST_DEB_MSG 1381 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n", 1382 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num, 1383 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block, 1384 STp->ps[STp->partition].rw == ST_WRITING?'w':'r', 1385 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes: 1386 STp->buffer->read_pointer, STp->ps[STp->partition].eof); 1387#endif 1388 /* do we know where we are inside a file? */ 1389 if (STp->ps[STp->partition].drv_block >= 0) { 1390 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 : 1391 STp->first_frame_position) << OSST_FRAME_SHIFT; 1392 if (STp->ps[STp->partition].rw == ST_WRITING) 1393 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK; 1394 else 1395 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK; 1396 } else { 1397 sector = osst_get_frame_position(STp, aSRpnt); 1398 if (sector > 0) 1399 sector <<= OSST_FRAME_SHIFT; 1400 } 1401 return sector; 1402} 1403 1404static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector) 1405{ 1406 struct st_partstat * STps = &(STp->ps[STp->partition]); 1407 int frame = sector >> OSST_FRAME_SHIFT, 1408 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 1409 r; 1410#if DEBUG 1411 char * name = tape_name(STp); 1412 1413 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n", 1414 name, sector, frame, offset); 1415#endif 1416 if (frame < 0 || frame >= STp->capacity) return (-ENXIO); 1417 1418 if (frame <= STp->first_data_ppos) { 1419 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0; 1420 return (osst_set_frame_position(STp, aSRpnt, frame, 0)); 1421 } 1422 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0); 1423 if (r < 0) return r; 1424 1425 r = osst_get_logical_frame(STp, aSRpnt, -1, 1); 1426 if (r < 0) return r; 1427 1428 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO); 1429 1430 if (offset) { 1431 STp->logical_blk_num += offset / STp->block_size; 1432 STp->buffer->read_pointer = offset; 1433 STp->buffer->buffer_bytes -= offset; 1434 } else { 1435 STp->frame_seq_number++; 1436 STp->frame_in_buffer = 0; 1437 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1438 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0; 1439 } 1440 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt); 1441 if (STps->eof == ST_FM_HIT) { 1442 STps->drv_file++; 1443 STps->drv_block = 0; 1444 } else { 1445 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)? 1446 STp->logical_blk_num - 1447 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0): 1448 -1; 1449 } 1450 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF; 1451#if DEBUG 1452 printk(OSST_DEB_MSG 1453 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n", 1454 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num, 1455 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof); 1456#endif 1457 return 0; 1458} 1459 1460/* 1461 * Read back the drive's internal buffer contents, as a part 1462 * of the write error recovery mechanism for old OnStream 1463 * firmware revisions. 1464 * Precondition for this function to work: all frames in the 1465 * drive's buffer must be of one type (DATA, MARK or EOD)! 1466 */ 1467static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt, 1468 unsigned int frame, unsigned int skip, int pending) 1469{ 1470 struct osst_request * SRpnt = * aSRpnt; 1471 unsigned char * buffer, * p; 1472 unsigned char cmd[MAX_COMMAND_SIZE]; 1473 int flag, new_frame, i; 1474 int nframes = STp->cur_frames; 1475 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1476 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num) 1477 - (nframes + pending - 1); 1478 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num) 1479 - (nframes + pending - 1) * blks_per_frame; 1480 char * name = tape_name(STp); 1481 unsigned long startwait = jiffies; 1482#if DEBUG 1483 int dbg = debugging; 1484#endif 1485 1486 if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL) 1487 return (-EIO); 1488 1489 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n", 1490 name, nframes, pending?" and one that was pending":""); 1491 1492 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE])); 1493#if DEBUG 1494 if (pending && debugging) 1495 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n", 1496 name, frame_seq_number + nframes, 1497 logical_blk_num + nframes * blks_per_frame, 1498 p[0], p[1], p[2], p[3]); 1499#endif 1500 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) { 1501 1502 memset(cmd, 0, MAX_COMMAND_SIZE); 1503 cmd[0] = 0x3C; /* Buffer Read */ 1504 cmd[1] = 6; /* Retrieve Faulty Block */ 1505 cmd[7] = 32768 >> 8; 1506 cmd[8] = 32768 & 0xff; 1507 1508 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE, 1509 STp->timeout, MAX_RETRIES, 1); 1510 1511 if ((STp->buffer)->syscall_result || !SRpnt) { 1512 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name); 1513 vfree(buffer); 1514 *aSRpnt = SRpnt; 1515 return (-EIO); 1516 } 1517 osst_copy_from_buffer(STp->buffer, p); 1518#if DEBUG 1519 if (debugging) 1520 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n", 1521 name, frame_seq_number + i, p[0], p[1], p[2], p[3]); 1522#endif 1523 } 1524 *aSRpnt = SRpnt; 1525 osst_get_frame_position(STp, aSRpnt); 1526 1527#if DEBUG 1528 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames); 1529#endif 1530 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */ 1531 /* In the header we don't actually re-write the frames that fail, just the ones after them */ 1532 1533 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) { 1534 1535 if (flag) { 1536 if (STp->write_type == OS_WRITE_HEADER) { 1537 i += skip; 1538 p += skip * OS_DATA_SIZE; 1539 } 1540 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990) 1541 new_frame = 3000-i; 1542 else 1543 new_frame += skip; 1544#if DEBUG 1545 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n", 1546 name, new_frame+i, frame_seq_number+i); 1547#endif 1548 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0); 1549 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE); 1550 osst_get_frame_position(STp, aSRpnt); 1551 SRpnt = * aSRpnt; 1552 1553 if (new_frame > frame + 1000) { 1554 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name); 1555 vfree(buffer); 1556 return (-EIO); 1557 } 1558 if ( i >= nframes + pending ) break; 1559 flag = 0; 1560 } 1561 osst_copy_to_buffer(STp->buffer, p); 1562 /* 1563 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type! 1564 */ 1565 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i, 1566 logical_blk_num + i*blks_per_frame, 1567 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame); 1568 memset(cmd, 0, MAX_COMMAND_SIZE); 1569 cmd[0] = WRITE_6; 1570 cmd[1] = 1; 1571 cmd[4] = 1; 1572 1573#if DEBUG 1574 if (debugging) 1575 printk(OSST_DEB_MSG 1576 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n", 1577 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame, 1578 p[0], p[1], p[2], p[3]); 1579#endif 1580 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, 1581 STp->timeout, MAX_RETRIES, 1); 1582 1583 if (STp->buffer->syscall_result) 1584 flag = 1; 1585 else { 1586 p += OS_DATA_SIZE; i++; 1587 1588 /* if we just sent the last frame, wait till all successfully written */ 1589 if ( i == nframes + pending ) { 1590#if DEBUG 1591 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name); 1592#endif 1593 memset(cmd, 0, MAX_COMMAND_SIZE); 1594 cmd[0] = WRITE_FILEMARKS; 1595 cmd[1] = 1; 1596 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, 1597 STp->timeout, MAX_RETRIES, 1); 1598#if DEBUG 1599 if (debugging) { 1600 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name); 1601 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 1602 debugging = 0; 1603 } 1604#endif 1605 flag = STp->buffer->syscall_result; 1606 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) { 1607 1608 memset(cmd, 0, MAX_COMMAND_SIZE); 1609 cmd[0] = TEST_UNIT_READY; 1610 1611 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, 1612 MAX_RETRIES, 1); 1613 1614 if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 && 1615 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) { 1616 /* in the process of becoming ready */ 1617 msleep(100); 1618 continue; 1619 } 1620 if (STp->buffer->syscall_result) 1621 flag = 1; 1622 break; 1623 } 1624#if DEBUG 1625 debugging = dbg; 1626 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name); 1627#endif 1628 } 1629 } 1630 *aSRpnt = SRpnt; 1631 if (flag) { 1632 if ((SRpnt->sense[ 2] & 0x0f) == 13 && 1633 SRpnt->sense[12] == 0 && 1634 SRpnt->sense[13] == 2) { 1635 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name); 1636 vfree(buffer); 1637 return (-EIO); /* hit end of tape = fail */ 1638 } 1639 i = ((SRpnt->sense[3] << 24) | 1640 (SRpnt->sense[4] << 16) | 1641 (SRpnt->sense[5] << 8) | 1642 SRpnt->sense[6] ) - new_frame; 1643 p = &buffer[i * OS_DATA_SIZE]; 1644#if DEBUG 1645 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i); 1646#endif 1647 osst_get_frame_position(STp, aSRpnt); 1648#if DEBUG 1649 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n", 1650 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames); 1651#endif 1652 } 1653 } 1654 if (flag) { 1655 /* error recovery did not successfully complete */ 1656 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name, 1657 STp->write_type == OS_WRITE_HEADER?"header":"body"); 1658 } 1659 if (!pending) 1660 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */ 1661 vfree(buffer); 1662 return 0; 1663} 1664 1665static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt, 1666 unsigned int frame, unsigned int skip, int pending) 1667{ 1668 unsigned char cmd[MAX_COMMAND_SIZE]; 1669 struct osst_request * SRpnt; 1670 char * name = tape_name(STp); 1671 int expected = 0; 1672 int attempts = 1000 / skip; 1673 int flag = 1; 1674 unsigned long startwait = jiffies; 1675#if DEBUG 1676 int dbg = debugging; 1677#endif 1678 1679 while (attempts && time_before(jiffies, startwait + 60*HZ)) { 1680 if (flag) { 1681#if DEBUG 1682 debugging = dbg; 1683#endif 1684 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990) 1685 frame = 3000-skip; 1686 expected = frame+skip+STp->cur_frames+pending; 1687#if DEBUG 1688 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n", 1689 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending); 1690#endif 1691 osst_set_frame_position(STp, aSRpnt, frame + skip, 1); 1692 flag = 0; 1693 attempts--; 1694 schedule_timeout_interruptible(msecs_to_jiffies(100)); 1695 } 1696 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */ 1697#if DEBUG 1698 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n", 1699 name, STp->first_frame_position, 1700 STp->last_frame_position, STp->cur_frames); 1701#endif 1702 frame = STp->last_frame_position; 1703 flag = 1; 1704 continue; 1705 } 1706 if (pending && STp->cur_frames < 50) { 1707 1708 memset(cmd, 0, MAX_COMMAND_SIZE); 1709 cmd[0] = WRITE_6; 1710 cmd[1] = 1; 1711 cmd[4] = 1; 1712#if DEBUG 1713 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n", 1714 name, STp->frame_seq_number-1, STp->first_frame_position); 1715#endif 1716 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, 1717 STp->timeout, MAX_RETRIES, 1); 1718 *aSRpnt = SRpnt; 1719 1720 if (STp->buffer->syscall_result) { /* additional write error */ 1721 if ((SRpnt->sense[ 2] & 0x0f) == 13 && 1722 SRpnt->sense[12] == 0 && 1723 SRpnt->sense[13] == 2) { 1724 printk(KERN_ERR 1725 "%s:E: Volume overflow in write error recovery\n", 1726 name); 1727 break; /* hit end of tape = fail */ 1728 } 1729 flag = 1; 1730 } 1731 else 1732 pending = 0; 1733 1734 continue; 1735 } 1736 if (STp->cur_frames == 0) { 1737#if DEBUG 1738 debugging = dbg; 1739 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name); 1740#endif 1741 if (STp->first_frame_position != expected) { 1742 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n", 1743 name, STp->first_frame_position, expected); 1744 return (-EIO); 1745 } 1746 return 0; 1747 } 1748#if DEBUG 1749 if (debugging) { 1750 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name); 1751 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 1752 debugging = 0; 1753 } 1754#endif 1755 schedule_timeout_interruptible(msecs_to_jiffies(100)); 1756 } 1757 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name); 1758#if DEBUG 1759 debugging = dbg; 1760#endif 1761 return (-EIO); 1762} 1763 1764/* 1765 * Error recovery algorithm for the OnStream tape. 1766 */ 1767 1768static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending) 1769{ 1770 struct osst_request * SRpnt = * aSRpnt; 1771 struct st_partstat * STps = & STp->ps[STp->partition]; 1772 char * name = tape_name(STp); 1773 int retval = 0; 1774 int rw_state; 1775 unsigned int frame, skip; 1776 1777 rw_state = STps->rw; 1778 1779 if ((SRpnt->sense[ 2] & 0x0f) != 3 1780 || SRpnt->sense[12] != 12 1781 || SRpnt->sense[13] != 0) { 1782#if DEBUG 1783 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name, 1784 SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]); 1785#endif 1786 return (-EIO); 1787 } 1788 frame = (SRpnt->sense[3] << 24) | 1789 (SRpnt->sense[4] << 16) | 1790 (SRpnt->sense[5] << 8) | 1791 SRpnt->sense[6]; 1792 skip = SRpnt->sense[9]; 1793 1794#if DEBUG 1795 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip); 1796#endif 1797 osst_get_frame_position(STp, aSRpnt); 1798#if DEBUG 1799 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n", 1800 name, STp->first_frame_position, STp->last_frame_position); 1801#endif 1802 switch (STp->write_type) { 1803 case OS_WRITE_DATA: 1804 case OS_WRITE_EOD: 1805 case OS_WRITE_NEW_MARK: 1806 printk(KERN_WARNING 1807 "%s:I: Relocating %d buffered logical frames from position %u to %u\n", 1808 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip); 1809 if (STp->os_fw_rev >= 10600) 1810 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending); 1811 else 1812 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending); 1813 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name, 1814 retval?"E" :"I", 1815 retval?"" :"Don't worry, ", 1816 retval?" not ":" "); 1817 break; 1818 case OS_WRITE_LAST_MARK: 1819 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name); 1820 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0); 1821 retval = -EIO; 1822 break; 1823 case OS_WRITE_HEADER: 1824 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name); 1825 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending); 1826 break; 1827 default: 1828 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name); 1829 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0); 1830 } 1831 osst_get_frame_position(STp, aSRpnt); 1832#if DEBUG 1833 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n", 1834 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position); 1835 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num); 1836#endif 1837 if (retval == 0) { 1838 STp->recover_count++; 1839 STp->recover_erreg++; 1840 } else 1841 STp->abort_count++; 1842 1843 STps->rw = rw_state; 1844 return retval; 1845} 1846 1847static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt, 1848 int mt_op, int mt_count) 1849{ 1850 char * name = tape_name(STp); 1851 int cnt; 1852 int last_mark_ppos = -1; 1853 1854#if DEBUG 1855 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count); 1856#endif 1857 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1858#if DEBUG 1859 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name); 1860#endif 1861 return -EIO; 1862 } 1863 if (STp->linux_media_version >= 4) { 1864 /* 1865 * direct lookup in header filemark list 1866 */ 1867 cnt = ntohl(STp->buffer->aux->filemark_cnt); 1868 if (STp->header_ok && 1869 STp->header_cache != NULL && 1870 (cnt - mt_count) >= 0 && 1871 (cnt - mt_count) < OS_FM_TAB_MAX && 1872 (cnt - mt_count) < STp->filemark_cnt && 1873 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos) 1874 1875 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]); 1876#if DEBUG 1877 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX) 1878 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name, 1879 STp->header_cache == NULL?"lack of header cache":"count out of range"); 1880 else 1881 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n", 1882 name, cnt, 1883 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || 1884 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == 1885 STp->buffer->aux->last_mark_ppos))?"match":"error", 1886 mt_count, last_mark_ppos); 1887#endif 1888 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) { 1889 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos); 1890 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1891#if DEBUG 1892 printk(OSST_DEB_MSG 1893 "%s:D: Couldn't get logical blk num in space_filemarks\n", name); 1894#endif 1895 return (-EIO); 1896 } 1897 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 1898 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 1899 name, last_mark_ppos); 1900 return (-EIO); 1901 } 1902 goto found; 1903 } 1904#if DEBUG 1905 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name); 1906#endif 1907 } 1908 cnt = 0; 1909 while (cnt != mt_count) { 1910 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos); 1911 if (last_mark_ppos == -1) 1912 return (-EIO); 1913#if DEBUG 1914 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos); 1915#endif 1916 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos); 1917 cnt++; 1918 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1919#if DEBUG 1920 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name); 1921#endif 1922 return (-EIO); 1923 } 1924 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 1925 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 1926 name, last_mark_ppos); 1927 return (-EIO); 1928 } 1929 } 1930found: 1931 if (mt_op == MTBSFM) { 1932 STp->frame_seq_number++; 1933 STp->frame_in_buffer = 0; 1934 STp->buffer->buffer_bytes = 0; 1935 STp->buffer->read_pointer = 0; 1936 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1937 } 1938 return 0; 1939} 1940 1941/* 1942 * ADRL 1.1 compatible "slow" space filemarks fwd version 1943 * 1944 * Just scans for the filemark sequentially. 1945 */ 1946static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt, 1947 int mt_op, int mt_count) 1948{ 1949 int cnt = 0; 1950#if DEBUG 1951 char * name = tape_name(STp); 1952 1953 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count); 1954#endif 1955 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1956#if DEBUG 1957 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name); 1958#endif 1959 return (-EIO); 1960 } 1961 while (1) { 1962 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1963#if DEBUG 1964 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name); 1965#endif 1966 return (-EIO); 1967 } 1968 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER) 1969 cnt++; 1970 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) { 1971#if DEBUG 1972 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name); 1973#endif 1974 if (STp->first_frame_position > STp->eod_frame_ppos+1) { 1975#if DEBUG 1976 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n", 1977 name, STp->eod_frame_ppos, STp->first_frame_position-1); 1978#endif 1979 STp->eod_frame_ppos = STp->first_frame_position-1; 1980 } 1981 return (-EIO); 1982 } 1983 if (cnt == mt_count) 1984 break; 1985 STp->frame_in_buffer = 0; 1986 } 1987 if (mt_op == MTFSF) { 1988 STp->frame_seq_number++; 1989 STp->frame_in_buffer = 0; 1990 STp->buffer->buffer_bytes = 0; 1991 STp->buffer->read_pointer = 0; 1992 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1993 } 1994 return 0; 1995} 1996 1997/* 1998 * Fast linux specific version of OnStream FSF 1999 */ 2000static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt, 2001 int mt_op, int mt_count) 2002{ 2003 char * name = tape_name(STp); 2004 int cnt = 0, 2005 next_mark_ppos = -1; 2006 2007#if DEBUG 2008 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count); 2009#endif 2010 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2011#if DEBUG 2012 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name); 2013#endif 2014 return (-EIO); 2015 } 2016 2017 if (STp->linux_media_version >= 4) { 2018 /* 2019 * direct lookup in header filemark list 2020 */ 2021 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1; 2022 if (STp->header_ok && 2023 STp->header_cache != NULL && 2024 (cnt + mt_count) < OS_FM_TAB_MAX && 2025 (cnt + mt_count) < STp->filemark_cnt && 2026 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || 2027 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos))) 2028 2029 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]); 2030#if DEBUG 2031 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX) 2032 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name, 2033 STp->header_cache == NULL?"lack of header cache":"count out of range"); 2034 else 2035 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n", 2036 name, cnt, 2037 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || 2038 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == 2039 STp->buffer->aux->last_mark_ppos))?"match":"error", 2040 mt_count, next_mark_ppos); 2041#endif 2042 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) { 2043#if DEBUG 2044 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name); 2045#endif 2046 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count); 2047 } else { 2048 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos); 2049 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2050#if DEBUG 2051 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", 2052 name); 2053#endif 2054 return (-EIO); 2055 } 2056 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 2057 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 2058 name, next_mark_ppos); 2059 return (-EIO); 2060 } 2061 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) { 2062 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n", 2063 name, cnt+mt_count, next_mark_ppos, 2064 ntohl(STp->buffer->aux->filemark_cnt)); 2065 return (-EIO); 2066 } 2067 } 2068 } else { 2069 /* 2070 * Find nearest (usually previous) marker, then jump from marker to marker 2071 */ 2072 while (1) { 2073 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER) 2074 break; 2075 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) { 2076#if DEBUG 2077 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name); 2078#endif 2079 return (-EIO); 2080 } 2081 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) { 2082 if (STp->first_mark_ppos == -1) { 2083#if DEBUG 2084 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name); 2085#endif 2086 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count); 2087 } 2088 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos); 2089 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2090#if DEBUG 2091 printk(OSST_DEB_MSG 2092 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n", 2093 name); 2094#endif 2095 return (-EIO); 2096 } 2097 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 2098 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n", 2099 name, STp->first_mark_ppos); 2100 return (-EIO); 2101 } 2102 } else { 2103 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0) 2104 return (-EIO); 2105 mt_count++; 2106 } 2107 } 2108 cnt++; 2109 while (cnt != mt_count) { 2110 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos); 2111 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) { 2112#if DEBUG 2113 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name); 2114#endif 2115 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt); 2116 } 2117#if DEBUG 2118 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos); 2119#endif 2120 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos); 2121 cnt++; 2122 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2123#if DEBUG 2124 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", 2125 name); 2126#endif 2127 return (-EIO); 2128 } 2129 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 2130 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 2131 name, next_mark_ppos); 2132 return (-EIO); 2133 } 2134 } 2135 } 2136 if (mt_op == MTFSF) { 2137 STp->frame_seq_number++; 2138 STp->frame_in_buffer = 0; 2139 STp->buffer->buffer_bytes = 0; 2140 STp->buffer->read_pointer = 0; 2141 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 2142 } 2143 return 0; 2144} 2145 2146/* 2147 * In debug mode, we want to see as many errors as possible 2148 * to test the error recovery mechanism. 2149 */ 2150#if DEBUG 2151static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries) 2152{ 2153 unsigned char cmd[MAX_COMMAND_SIZE]; 2154 struct osst_request * SRpnt = * aSRpnt; 2155 char * name = tape_name(STp); 2156 2157 memset(cmd, 0, MAX_COMMAND_SIZE); 2158 cmd[0] = MODE_SELECT; 2159 cmd[1] = 0x10; 2160 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH; 2161 2162 (STp->buffer)->b_data[0] = cmd[4] - 1; 2163 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */ 2164 (STp->buffer)->b_data[2] = 0; /* Reserved */ 2165 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */ 2166 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7); 2167 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2; 2168 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4; 2169 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries; 2170 2171 if (debugging) 2172 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries); 2173 2174 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); 2175 *aSRpnt = SRpnt; 2176 2177 if ((STp->buffer)->syscall_result) 2178 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries); 2179} 2180#endif 2181 2182 2183static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt) 2184{ 2185 int result; 2186 int this_mark_ppos = STp->first_frame_position; 2187 int this_mark_lbn = STp->logical_blk_num; 2188#if DEBUG 2189 char * name = tape_name(STp); 2190#endif 2191 2192 if (STp->raw) return 0; 2193 2194 STp->write_type = OS_WRITE_NEW_MARK; 2195#if DEBUG 2196 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n", 2197 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn); 2198#endif 2199 STp->dirty = 1; 2200 result = osst_flush_write_buffer(STp, aSRpnt); 2201 result |= osst_flush_drive_buffer(STp, aSRpnt); 2202 STp->last_mark_ppos = this_mark_ppos; 2203 STp->last_mark_lbn = this_mark_lbn; 2204 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX) 2205 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos); 2206 if (STp->filemark_cnt++ == 0) 2207 STp->first_mark_ppos = this_mark_ppos; 2208 return result; 2209} 2210 2211static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt) 2212{ 2213 int result; 2214#if DEBUG 2215 char * name = tape_name(STp); 2216#endif 2217 2218 if (STp->raw) return 0; 2219 2220 STp->write_type = OS_WRITE_EOD; 2221 STp->eod_frame_ppos = STp->first_frame_position; 2222#if DEBUG 2223 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name, 2224 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num); 2225#endif 2226 STp->dirty = 1; 2227 2228 result = osst_flush_write_buffer(STp, aSRpnt); 2229 result |= osst_flush_drive_buffer(STp, aSRpnt); 2230 STp->eod_frame_lfa = --(STp->frame_seq_number); 2231 return result; 2232} 2233 2234static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count) 2235{ 2236 char * name = tape_name(STp); 2237 2238#if DEBUG 2239 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where); 2240#endif 2241 osst_wait_ready(STp, aSRpnt, 60 * 5, 0); 2242 osst_set_frame_position(STp, aSRpnt, where, 0); 2243 STp->write_type = OS_WRITE_FILLER; 2244 while (count--) { 2245 memcpy(STp->buffer->b_data, "Filler", 6); 2246 STp->buffer->buffer_bytes = 6; 2247 STp->dirty = 1; 2248 if (osst_flush_write_buffer(STp, aSRpnt)) { 2249 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name); 2250 return (-EIO); 2251 } 2252 } 2253#if DEBUG 2254 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name); 2255#endif 2256 return osst_flush_drive_buffer(STp, aSRpnt); 2257} 2258 2259static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count) 2260{ 2261 char * name = tape_name(STp); 2262 int result; 2263 2264#if DEBUG 2265 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where); 2266#endif 2267 osst_wait_ready(STp, aSRpnt, 60 * 5, 0); 2268 osst_set_frame_position(STp, aSRpnt, where, 0); 2269 STp->write_type = OS_WRITE_HEADER; 2270 while (count--) { 2271 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache); 2272 STp->buffer->buffer_bytes = sizeof(os_header_t); 2273 STp->dirty = 1; 2274 if (osst_flush_write_buffer(STp, aSRpnt)) { 2275 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name); 2276 return (-EIO); 2277 } 2278 } 2279 result = osst_flush_drive_buffer(STp, aSRpnt); 2280#if DEBUG 2281 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done"); 2282#endif 2283 return result; 2284} 2285 2286static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod) 2287{ 2288 os_header_t * header; 2289 int result; 2290 char * name = tape_name(STp); 2291 2292#if DEBUG 2293 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name); 2294#endif 2295 if (STp->raw) return 0; 2296 2297 if (STp->header_cache == NULL) { 2298 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) { 2299 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name); 2300 return (-ENOMEM); 2301 } 2302 memset(STp->header_cache, 0, sizeof(os_header_t)); 2303#if DEBUG 2304 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name); 2305#endif 2306 } 2307 if (STp->header_ok) STp->update_frame_cntr++; 2308 else STp->update_frame_cntr = 0; 2309 2310 header = STp->header_cache; 2311 strcpy(header->ident_str, "ADR_SEQ"); 2312 header->major_rev = 1; 2313 header->minor_rev = 4; 2314 header->ext_trk_tb_off = htons(17192); 2315 header->pt_par_num = 1; 2316 header->partition[0].partition_num = OS_DATA_PARTITION; 2317 header->partition[0].par_desc_ver = OS_PARTITION_VERSION; 2318 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr); 2319 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos); 2320 header->partition[0].last_frame_ppos = htonl(STp->capacity); 2321 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos); 2322 header->cfg_col_width = htonl(20); 2323 header->dat_col_width = htonl(1500); 2324 header->qfa_col_width = htonl(0); 2325 header->ext_track_tb.nr_stream_part = 1; 2326 header->ext_track_tb.et_ent_sz = 32; 2327 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0; 2328 header->ext_track_tb.dat_ext_trk_ey.fmt = 1; 2329 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736); 2330 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0; 2331 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa); 2332 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos); 2333 header->dat_fm_tab.fm_part_num = 0; 2334 header->dat_fm_tab.fm_tab_ent_sz = 4; 2335 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX? 2336 STp->filemark_cnt:OS_FM_TAB_MAX); 2337 2338 result = __osst_write_header(STp, aSRpnt, 0xbae, 5); 2339 if (STp->update_frame_cntr == 0) 2340 osst_write_filler(STp, aSRpnt, 0xbb3, 5); 2341 result &= __osst_write_header(STp, aSRpnt, 5, 5); 2342 2343 if (locate_eod) { 2344#if DEBUG 2345 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos); 2346#endif 2347 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0); 2348 } 2349 if (result) 2350 printk(KERN_ERR "%s:E: Write header failed\n", name); 2351 else { 2352 memcpy(STp->application_sig, "LIN4", 4); 2353 STp->linux_media = 1; 2354 STp->linux_media_version = 4; 2355 STp->header_ok = 1; 2356 } 2357 return result; 2358} 2359 2360static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt) 2361{ 2362 if (STp->header_cache != NULL) 2363 memset(STp->header_cache, 0, sizeof(os_header_t)); 2364 2365 STp->logical_blk_num = STp->frame_seq_number = 0; 2366 STp->frame_in_buffer = 0; 2367 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A; 2368 STp->filemark_cnt = 0; 2369 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1; 2370 return osst_write_header(STp, aSRpnt, 1); 2371} 2372 2373static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos) 2374{ 2375 char * name = tape_name(STp); 2376 os_header_t * header; 2377 os_aux_t * aux; 2378 char id_string[8]; 2379 int linux_media_version, 2380 update_frame_cntr; 2381 2382 if (STp->raw) 2383 return 1; 2384 2385 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) { 2386 if (osst_set_frame_position(STp, aSRpnt, ppos, 0)) 2387 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name); 2388 osst_wait_ready(STp, aSRpnt, 60 * 15, 0); 2389 if (osst_initiate_read (STp, aSRpnt)) { 2390 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name); 2391 return 0; 2392 } 2393 } 2394 if (osst_read_frame(STp, aSRpnt, 180)) { 2395#if DEBUG 2396 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name); 2397#endif 2398 return 0; 2399 } 2400 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */ 2401 aux = STp->buffer->aux; 2402 if (aux->frame_type != OS_FRAME_TYPE_HEADER) { 2403#if DEBUG 2404 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos); 2405#endif 2406 return 0; 2407 } 2408 if (ntohl(aux->frame_seq_num) != 0 || 2409 ntohl(aux->logical_blk_num) != 0 || 2410 aux->partition.partition_num != OS_CONFIG_PARTITION || 2411 ntohl(aux->partition.first_frame_ppos) != 0 || 2412 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) { 2413#if DEBUG 2414 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name, 2415 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num), 2416 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos), 2417 ntohl(aux->partition.last_frame_ppos)); 2418#endif 2419 return 0; 2420 } 2421 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 && 2422 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) { 2423 strlcpy(id_string, header->ident_str, 8); 2424#if DEBUG 2425 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string); 2426#endif 2427 return 0; 2428 } 2429 update_frame_cntr = ntohl(aux->update_frame_cntr); 2430 if (update_frame_cntr < STp->update_frame_cntr) { 2431#if DEBUG 2432 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n", 2433 name, ppos, update_frame_cntr, STp->update_frame_cntr); 2434#endif 2435 return 0; 2436 } 2437 if (header->major_rev != 1 || header->minor_rev != 4 ) { 2438#if DEBUG 2439 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n", 2440 name, (header->major_rev != 1 || header->minor_rev < 2 || 2441 header->minor_rev > 4 )? "Invalid" : "Warning:", 2442 header->major_rev, header->minor_rev); 2443#endif 2444 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4) 2445 return 0; 2446 } 2447#if DEBUG 2448 if (header->pt_par_num != 1) 2449 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n", 2450 name, header->pt_par_num); 2451#endif 2452 memcpy(id_string, aux->application_sig, 4); 2453 id_string[4] = 0; 2454 if (memcmp(id_string, "LIN", 3) == 0) { 2455 STp->linux_media = 1; 2456 linux_media_version = id_string[3] - '0'; 2457 if (linux_media_version != 4) 2458 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n", 2459 name, linux_media_version); 2460 } else { 2461 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string); 2462 return 0; 2463 } 2464 if (linux_media_version < STp->linux_media_version) { 2465#if DEBUG 2466 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n", 2467 name, ppos, linux_media_version); 2468#endif 2469 return 0; 2470 } 2471 if (linux_media_version > STp->linux_media_version) { 2472#if DEBUG 2473 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n", 2474 name, ppos, linux_media_version); 2475#endif 2476 memcpy(STp->application_sig, id_string, 5); 2477 STp->linux_media_version = linux_media_version; 2478 STp->update_frame_cntr = -1; 2479 } 2480 if (update_frame_cntr > STp->update_frame_cntr) { 2481#if DEBUG 2482 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n", 2483 name, ppos, update_frame_cntr); 2484#endif 2485 if (STp->header_cache == NULL) { 2486 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) { 2487 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name); 2488 return 0; 2489 } 2490#if DEBUG 2491 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name); 2492#endif 2493 } 2494 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache); 2495 header = STp->header_cache; /* further accesses from cached (full) copy */ 2496 2497 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr); 2498 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos); 2499 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos); 2500 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb); 2501 STp->filemark_cnt = ntohl(aux->filemark_cnt); 2502 STp->first_mark_ppos = ntohl(aux->next_mark_ppos); 2503 STp->last_mark_ppos = ntohl(aux->last_mark_ppos); 2504 STp->last_mark_lbn = ntohl(aux->last_mark_lbn); 2505 STp->update_frame_cntr = update_frame_cntr; 2506#if DEBUG 2507 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n", 2508 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt); 2509 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name, 2510 STp->first_data_ppos, 2511 ntohl(header->partition[0].last_frame_ppos), 2512 ntohl(header->partition[0].eod_frame_ppos)); 2513 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n", 2514 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos); 2515#endif 2516 if (header->minor_rev < 4 && STp->linux_media_version == 4) { 2517#if DEBUG 2518 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name); 2519#endif 2520 memcpy((void *)header->dat_fm_tab.fm_tab_ent, 2521 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent)); 2522 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list)); 2523 } 2524 if (header->minor_rev == 4 && 2525 (header->ext_trk_tb_off != htons(17192) || 2526 header->partition[0].partition_num != OS_DATA_PARTITION || 2527 header->partition[0].par_desc_ver != OS_PARTITION_VERSION || 2528 header->partition[0].last_frame_ppos != htonl(STp->capacity) || 2529 header->cfg_col_width != htonl(20) || 2530 header->dat_col_width != htonl(1500) || 2531 header->qfa_col_width != htonl(0) || 2532 header->ext_track_tb.nr_stream_part != 1 || 2533 header->ext_track_tb.et_ent_sz != 32 || 2534 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION || 2535 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 || 2536 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) || 2537 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 || 2538 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) || 2539 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION || 2540 header->dat_fm_tab.fm_tab_ent_sz != 4 || 2541 header->dat_fm_tab.fm_tab_ent_cnt != 2542 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX))) 2543 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name); 2544 2545 } 2546 2547 return 1; 2548} 2549 2550static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt) 2551{ 2552 int position, ppos; 2553 int first, last; 2554 int valid = 0; 2555 char * name = tape_name(STp); 2556 2557 position = osst_get_frame_position(STp, aSRpnt); 2558 2559 if (STp->raw) { 2560 STp->header_ok = STp->linux_media = 1; 2561 STp->linux_media_version = 0; 2562 return 1; 2563 } 2564 STp->header_ok = STp->linux_media = STp->linux_media_version = 0; 2565 STp->wrt_pass_cntr = STp->update_frame_cntr = -1; 2566 STp->eod_frame_ppos = STp->first_data_ppos = -1; 2567 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1; 2568#if DEBUG 2569 printk(OSST_DEB_MSG "%s:D: Reading header\n", name); 2570#endif 2571 2572 /* optimization for speed - if we are positioned at ppos 10, read second group first */ 2573 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */ 2574 2575 first = position==10?0xbae: 5; 2576 last = position==10?0xbb3:10; 2577 2578 for (ppos = first; ppos < last; ppos++) 2579 if (__osst_analyze_headers(STp, aSRpnt, ppos)) 2580 valid = 1; 2581 2582 first = position==10? 5:0xbae; 2583 last = position==10?10:0xbb3; 2584 2585 for (ppos = first; ppos < last; ppos++) 2586 if (__osst_analyze_headers(STp, aSRpnt, ppos)) 2587 valid = 1; 2588 2589 if (!valid) { 2590 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name); 2591 STp->eod_frame_ppos = STp->first_data_ppos = 0; 2592 osst_set_frame_position(STp, aSRpnt, 10, 0); 2593 return 0; 2594 } 2595 if (position <= STp->first_data_ppos) { 2596 position = STp->first_data_ppos; 2597 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0; 2598 } 2599 osst_set_frame_position(STp, aSRpnt, position, 0); 2600 STp->header_ok = 1; 2601 2602 return 1; 2603} 2604 2605static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt) 2606{ 2607 int frame_position = STp->first_frame_position; 2608 int frame_seq_numbr = STp->frame_seq_number; 2609 int logical_blk_num = STp->logical_blk_num; 2610 int halfway_frame = STp->frame_in_buffer; 2611 int read_pointer = STp->buffer->read_pointer; 2612 int prev_mark_ppos = -1; 2613 int actual_mark_ppos, i, n; 2614#if DEBUG 2615 char * name = tape_name(STp); 2616 2617 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name); 2618#endif 2619 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); 2620 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2621#if DEBUG 2622 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name); 2623#endif 2624 return (-EIO); 2625 } 2626 if (STp->linux_media_version >= 4) { 2627 for (i=0; i<STp->filemark_cnt; i++) 2628 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position) 2629 prev_mark_ppos = n; 2630 } else 2631 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */ 2632 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ? 2633 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos); 2634 if (frame_position != STp->first_frame_position || 2635 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) || 2636 prev_mark_ppos != actual_mark_ppos ) { 2637#if DEBUG 2638 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name, 2639 STp->first_frame_position, frame_position, 2640 STp->frame_seq_number + (halfway_frame?0:1), 2641 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos); 2642#endif 2643 return (-EIO); 2644 } 2645 if (halfway_frame) { 2646 /* prepare buffer for append and rewrite on top of original */ 2647 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); 2648 STp->buffer->buffer_bytes = read_pointer; 2649 STp->ps[STp->partition].rw = ST_WRITING; 2650 STp->dirty = 1; 2651 } 2652 STp->frame_in_buffer = halfway_frame; 2653 STp->frame_seq_number = frame_seq_numbr; 2654 STp->logical_blk_num = logical_blk_num; 2655 return 0; 2656} 2657 2658/* Acc. to OnStream, the vers. numbering is the following: 2659 * X.XX for released versions (X=digit), 2660 * XXXY for unreleased versions (Y=letter) 2661 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06 2662 * This fn makes monoton numbers out of this scheme ... 2663 */ 2664static unsigned int osst_parse_firmware_rev (const char * str) 2665{ 2666 if (str[1] == '.') { 2667 return (str[0]-'0')*10000 2668 +(str[2]-'0')*1000 2669 +(str[3]-'0')*100; 2670 } else { 2671 return (str[0]-'0')*10000 2672 +(str[1]-'0')*1000 2673 +(str[2]-'0')*100 - 100 2674 +(str[3]-'@'); 2675 } 2676} 2677 2678/* 2679 * Configure the OnStream SCII tape drive for default operation 2680 */ 2681static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt) 2682{ 2683 unsigned char cmd[MAX_COMMAND_SIZE]; 2684 char * name = tape_name(STp); 2685 struct osst_request * SRpnt = * aSRpnt; 2686 osst_mode_parameter_header_t * header; 2687 osst_block_size_page_t * bs; 2688 osst_capabilities_page_t * cp; 2689 osst_tape_paramtr_page_t * prm; 2690 int drive_buffer_size; 2691 2692 if (STp->ready != ST_READY) { 2693#if DEBUG 2694 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name); 2695#endif 2696 return (-EIO); 2697 } 2698 2699 if (STp->os_fw_rev < 10600) { 2700 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev); 2701 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name); 2702 } 2703 2704 /* 2705 * Configure 32.5KB (data+aux) frame size. 2706 * Get the current frame size from the block size mode page 2707 */ 2708 memset(cmd, 0, MAX_COMMAND_SIZE); 2709 cmd[0] = MODE_SENSE; 2710 cmd[1] = 8; 2711 cmd[2] = BLOCK_SIZE_PAGE; 2712 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH; 2713 2714 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); 2715 if (SRpnt == NULL) { 2716#if DEBUG 2717 printk(OSST_DEB_MSG "osst :D: Busy\n"); 2718#endif 2719 return (-EBUSY); 2720 } 2721 *aSRpnt = SRpnt; 2722 if ((STp->buffer)->syscall_result != 0) { 2723 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name); 2724 return (-EIO); 2725 } 2726 2727 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; 2728 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl); 2729 2730#if DEBUG 2731 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No"); 2732 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No"); 2733 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No"); 2734 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No"); 2735#endif 2736 2737 /* 2738 * Configure default auto columns mode, 32.5KB transfer mode 2739 */ 2740 bs->one = 1; 2741 bs->play32 = 0; 2742 bs->play32_5 = 1; 2743 bs->record32 = 0; 2744 bs->record32_5 = 1; 2745 2746 memset(cmd, 0, MAX_COMMAND_SIZE); 2747 cmd[0] = MODE_SELECT; 2748 cmd[1] = 0x10; 2749 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH; 2750 2751 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); 2752 *aSRpnt = SRpnt; 2753 if ((STp->buffer)->syscall_result != 0) { 2754 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name); 2755 return (-EIO); 2756 } 2757 2758#if DEBUG 2759 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name); 2760 /* 2761 * In debug mode, we want to see as many errors as possible 2762 * to test the error recovery mechanism. 2763 */ 2764 osst_set_retries(STp, aSRpnt, 0); 2765 SRpnt = * aSRpnt; 2766#endif 2767 2768 /* 2769 * Set vendor name to 'LIN4' for "Linux support version 4". 2770 */ 2771 2772 memset(cmd, 0, MAX_COMMAND_SIZE); 2773 cmd[0] = MODE_SELECT; 2774 cmd[1] = 0x10; 2775 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH; 2776 2777 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1; 2778 header->medium_type = 0; /* Medium Type - ignoring */ 2779 header->dsp = 0; /* Reserved */ 2780 header->bdl = 0; /* Block Descriptor Length */ 2781 2782 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7); 2783 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6; 2784 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L'; 2785 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I'; 2786 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N'; 2787 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4'; 2788 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0; 2789 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0; 2790 2791 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); 2792 *aSRpnt = SRpnt; 2793 2794 if ((STp->buffer)->syscall_result != 0) { 2795 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name, 2796 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2)); 2797 return (-EIO); 2798 } 2799 2800 memset(cmd, 0, MAX_COMMAND_SIZE); 2801 cmd[0] = MODE_SENSE; 2802 cmd[1] = 8; 2803 cmd[2] = CAPABILITIES_PAGE; 2804 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH; 2805 2806 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); 2807 *aSRpnt = SRpnt; 2808 2809 if ((STp->buffer)->syscall_result != 0) { 2810 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name); 2811 return (-EIO); 2812 } 2813 2814 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; 2815 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data + 2816 sizeof(osst_mode_parameter_header_t) + header->bdl); 2817 2818 drive_buffer_size = ntohs(cp->buffer_size) / 2; 2819 2820 memset(cmd, 0, MAX_COMMAND_SIZE); 2821 cmd[0] = MODE_SENSE; 2822 cmd[1] = 8; 2823 cmd[2] = TAPE_PARAMTR_PAGE; 2824 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH; 2825 2826 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); 2827 *aSRpnt = SRpnt; 2828 2829 if ((STp->buffer)->syscall_result != 0) { 2830 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name); 2831 return (-EIO); 2832 } 2833 2834 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; 2835 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data + 2836 sizeof(osst_mode_parameter_header_t) + header->bdl); 2837 2838 STp->density = prm->density; 2839 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks); 2840#if DEBUG 2841 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n", 2842 name, STp->density, STp->capacity / 32, drive_buffer_size); 2843#endif 2844 2845 return 0; 2846 2847} 2848 2849 2850/* Step over EOF if it has been inadvertently crossed (ioctl not used because 2851 it messes up the block number). */ 2852static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward) 2853{ 2854 int result; 2855 char * name = tape_name(STp); 2856 2857#if DEBUG 2858 if (debugging) 2859 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n", 2860 name, forward ? "forward" : "backward"); 2861#endif 2862 2863 if (forward) { 2864 /* assumes that the filemark is already read by the drive, so this is low cost */ 2865 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1); 2866 } 2867 else 2868 /* assumes this is only called if we just read the filemark! */ 2869 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1); 2870 2871 if (result < 0) 2872 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n", 2873 name, forward ? "forward" : "backward"); 2874 2875 return result; 2876} 2877 2878 2879/* Get the tape position. */ 2880 2881static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt) 2882{ 2883 unsigned char scmd[MAX_COMMAND_SIZE]; 2884 struct osst_request * SRpnt; 2885 int result = 0; 2886 char * name = tape_name(STp); 2887 2888 /* KG: We want to be able to use it for checking Write Buffer availability 2889 * and thus don't want to risk to overwrite anything. Exchange buffers ... */ 2890 char mybuf[24]; 2891 char * olddata = STp->buffer->b_data; 2892 int oldsize = STp->buffer->buffer_size; 2893 2894 if (STp->ready != ST_READY) return (-EIO); 2895 2896 memset (scmd, 0, MAX_COMMAND_SIZE); 2897 scmd[0] = READ_POSITION; 2898 2899 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; 2900 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE, 2901 STp->timeout, MAX_RETRIES, 1); 2902 if (!SRpnt) { 2903 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; 2904 return (-EBUSY); 2905 } 2906 *aSRpnt = SRpnt; 2907 2908 if (STp->buffer->syscall_result) 2909 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */ 2910 2911 if (result == -EINVAL) 2912 printk(KERN_ERR "%s:E: Can't read tape position.\n", name); 2913 else { 2914 if (result == -EIO) { /* re-read position - this needs to preserve media errors */ 2915 unsigned char mysense[16]; 2916 memcpy (mysense, SRpnt->sense, 16); 2917 memset (scmd, 0, MAX_COMMAND_SIZE); 2918 scmd[0] = READ_POSITION; 2919 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; 2920 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE, 2921 STp->timeout, MAX_RETRIES, 1); 2922#if DEBUG 2923 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n", 2924 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:", 2925 SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]); 2926#endif 2927 if (!STp->buffer->syscall_result) 2928 memcpy (SRpnt->sense, mysense, 16); 2929 else 2930 printk(KERN_WARNING "%s:W: Double error in get position\n", name); 2931 } 2932 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24) 2933 + ((STp->buffer)->b_data[5] << 16) 2934 + ((STp->buffer)->b_data[6] << 8) 2935 + (STp->buffer)->b_data[7]; 2936 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24) 2937 + ((STp->buffer)->b_data[ 9] << 16) 2938 + ((STp->buffer)->b_data[10] << 8) 2939 + (STp->buffer)->b_data[11]; 2940 STp->cur_frames = (STp->buffer)->b_data[15]; 2941#if DEBUG 2942 if (debugging) { 2943 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name, 2944 STp->first_frame_position, STp->last_frame_position, 2945 ((STp->buffer)->b_data[0]&0x80)?" (BOP)": 2946 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"", 2947 STp->cur_frames); 2948 } 2949#endif 2950 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) { 2951#if DEBUG 2952 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name, 2953 STp->first_frame_position, STp->last_frame_position, STp->cur_frames); 2954#endif 2955 STp->first_frame_position = STp->last_frame_position; 2956 } 2957 } 2958 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; 2959 2960 return (result == 0 ? STp->first_frame_position : result); 2961} 2962 2963 2964/* Set the tape block */ 2965static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip) 2966{ 2967 unsigned char scmd[MAX_COMMAND_SIZE]; 2968 struct osst_request * SRpnt; 2969 struct st_partstat * STps; 2970 int result = 0; 2971 int pp = (ppos == 3000 && !skip)? 0 : ppos; 2972 char * name = tape_name(STp); 2973 2974 if (STp->ready != ST_READY) return (-EIO); 2975 2976 STps = &(STp->ps[STp->partition]); 2977 2978 if (ppos < 0 || ppos > STp->capacity) { 2979 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos); 2980 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1); 2981 result = (-EINVAL); 2982 } 2983 2984 do { 2985#if DEBUG 2986 if (debugging) 2987 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp); 2988#endif 2989 memset (scmd, 0, MAX_COMMAND_SIZE); 2990 scmd[0] = SEEK_10; 2991 scmd[1] = 1; 2992 scmd[3] = (pp >> 24); 2993 scmd[4] = (pp >> 16); 2994 scmd[5] = (pp >> 8); 2995 scmd[6] = pp; 2996 if (skip) 2997 scmd[9] = 0x80; 2998 2999 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout, 3000 MAX_RETRIES, 1); 3001 if (!SRpnt) 3002 return (-EBUSY); 3003 *aSRpnt = SRpnt; 3004 3005 if ((STp->buffer)->syscall_result != 0) { 3006#if DEBUG 3007 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n", 3008 name, STp->first_frame_position, pp); 3009#endif 3010 result = (-EIO); 3011 } 3012 if (pp != ppos) 3013 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE); 3014 } while ((pp != ppos) && (pp = ppos)); 3015 STp->first_frame_position = STp->last_frame_position = ppos; 3016 STps->eof = ST_NOEOF; 3017 STps->at_sm = 0; 3018 STps->rw = ST_IDLE; 3019 STp->frame_in_buffer = 0; 3020 return result; 3021} 3022 3023static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT) 3024{ 3025 struct st_partstat * STps = &(STp->ps[STp->partition]); 3026 int result = 0; 3027 3028 if (STp->write_type != OS_WRITE_NEW_MARK) { 3029 /* true unless the user wrote the filemark for us */ 3030 result = osst_flush_drive_buffer(STp, aSRpnt); 3031 if (result < 0) goto out; 3032 result = osst_write_filemark(STp, aSRpnt); 3033 if (result < 0) goto out; 3034 3035 if (STps->drv_file >= 0) 3036 STps->drv_file++ ; 3037 STps->drv_block = 0; 3038 } 3039 result = osst_write_eod(STp, aSRpnt); 3040 osst_write_header(STp, aSRpnt, leave_at_EOT); 3041 3042 STps->eof = ST_FM; 3043out: 3044 return result; 3045} 3046 3047/* osst versions of st functions - augmented and stripped to suit OnStream only */ 3048 3049/* Flush the write buffer (never need to write if variable blocksize). */ 3050static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt) 3051{ 3052 int offset, transfer, blks = 0; 3053 int result = 0; 3054 unsigned char cmd[MAX_COMMAND_SIZE]; 3055 struct osst_request * SRpnt = *aSRpnt; 3056 struct st_partstat * STps; 3057 char * name = tape_name(STp); 3058 3059 if ((STp->buffer)->writing) { 3060 if (SRpnt == (STp->buffer)->last_SRpnt) 3061#if DEBUG 3062 { printk(OSST_DEB_MSG 3063 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name); 3064#endif 3065 *aSRpnt = SRpnt = NULL; 3066#if DEBUG 3067 } else if (SRpnt) 3068 printk(OSST_DEB_MSG 3069 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name); 3070#endif 3071 osst_write_behind_check(STp); 3072 if ((STp->buffer)->syscall_result) { 3073#if DEBUG 3074 if (debugging) 3075 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n", 3076 name, (STp->buffer)->midlevel_result); 3077#endif 3078 if ((STp->buffer)->midlevel_result == INT_MAX) 3079 return (-ENOSPC); 3080 return (-EIO); 3081 } 3082 } 3083 3084 result = 0; 3085 if (STp->dirty == 1) { 3086 3087 STp->write_count++; 3088 STps = &(STp->ps[STp->partition]); 3089 STps->rw = ST_WRITING; 3090 offset = STp->buffer->buffer_bytes; 3091 blks = (offset + STp->block_size - 1) / STp->block_size; 3092 transfer = OS_FRAME_SIZE; 3093 3094 if (offset < OS_DATA_SIZE) 3095 osst_zero_buffer_tail(STp->buffer); 3096 3097 if (STp->poll) 3098 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120)) 3099 result = osst_recover_wait_frame(STp, aSRpnt, 1); 3100 3101 memset(cmd, 0, MAX_COMMAND_SIZE); 3102 cmd[0] = WRITE_6; 3103 cmd[1] = 1; 3104 cmd[4] = 1; 3105 3106 switch (STp->write_type) { 3107 case OS_WRITE_DATA: 3108#if DEBUG 3109 if (debugging) 3110 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", 3111 name, blks, STp->frame_seq_number, 3112 STp->logical_blk_num - blks, STp->logical_blk_num - 1); 3113#endif 3114 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++, 3115 STp->logical_blk_num - blks, STp->block_size, blks); 3116 break; 3117 case OS_WRITE_EOD: 3118 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++, 3119 STp->logical_blk_num, 0, 0); 3120 break; 3121 case OS_WRITE_NEW_MARK: 3122 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++, 3123 STp->logical_blk_num++, 0, blks=1); 3124 break; 3125 case OS_WRITE_HEADER: 3126 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0); 3127 break; 3128 default: /* probably FILLER */ 3129 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0); 3130 } 3131#if DEBUG 3132 if (debugging) 3133 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n", 3134 name, offset, transfer, blks); 3135#endif 3136 3137 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE, 3138 STp->timeout, MAX_RETRIES, 1); 3139 *aSRpnt = SRpnt; 3140 if (!SRpnt) 3141 return (-EBUSY); 3142 3143 if ((STp->buffer)->syscall_result != 0) { 3144#if DEBUG 3145 printk(OSST_DEB_MSG 3146 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n", 3147 name, SRpnt->sense[0], SRpnt->sense[2], 3148 SRpnt->sense[12], SRpnt->sense[13]); 3149#endif 3150 if ((SRpnt->sense[0] & 0x70) == 0x70 && 3151 (SRpnt->sense[2] & 0x40) && 3152 (SRpnt->sense[2] & 0x0f) == NO_SENSE) { 3153 STp->dirty = 0; 3154 (STp->buffer)->buffer_bytes = 0; 3155 result = (-ENOSPC); 3156 } 3157 else { 3158 if (osst_write_error_recovery(STp, aSRpnt, 1)) { 3159 printk(KERN_ERR "%s:E: Error on flush write.\n", name); 3160 result = (-EIO); 3161 } 3162 } 3163 STps->drv_block = (-1); 3164 } 3165 else { 3166 STp->first_frame_position++; 3167 STp->dirty = 0; 3168 (STp->buffer)->buffer_bytes = 0; 3169 } 3170 } 3171#if DEBUG 3172 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result); 3173#endif 3174 return result; 3175} 3176 3177 3178/* Flush the tape buffer. The tape will be positioned correctly unless 3179 seek_next is true. */ 3180static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next) 3181{ 3182 struct st_partstat * STps; 3183 int backspace = 0, result = 0; 3184#if DEBUG 3185 char * name = tape_name(STp); 3186#endif 3187 3188 /* 3189 * If there was a bus reset, block further access 3190 * to this device. 3191 */ 3192 if( STp->pos_unknown) 3193 return (-EIO); 3194 3195 if (STp->ready != ST_READY) 3196 return 0; 3197 3198 STps = &(STp->ps[STp->partition]); 3199 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */ 3200 STp->write_type = OS_WRITE_DATA; 3201 return osst_flush_write_buffer(STp, aSRpnt); 3202 } 3203 if (STp->block_size == 0) 3204 return 0; 3205 3206#if DEBUG 3207 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name); 3208#endif 3209 3210 if (!STp->can_bsr) { 3211 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size - 3212 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ; 3213 (STp->buffer)->buffer_bytes = 0; 3214 (STp->buffer)->read_pointer = 0; 3215 STp->frame_in_buffer = 0; 3216 } 3217 3218 if (!seek_next) { 3219 if (STps->eof == ST_FM_HIT) { 3220 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */ 3221 if (!result) 3222 STps->eof = ST_NOEOF; 3223 else { 3224 if (STps->drv_file >= 0) 3225 STps->drv_file++; 3226 STps->drv_block = 0; 3227 } 3228 } 3229 if (!result && backspace > 0) /* TODO -- design and run a test case for this */ 3230 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace); 3231 } 3232 else if (STps->eof == ST_FM_HIT) { 3233 if (STps->drv_file >= 0) 3234 STps->drv_file++; 3235 STps->drv_block = 0; 3236 STps->eof = ST_NOEOF; 3237 } 3238 3239 return result; 3240} 3241 3242static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous) 3243{ 3244 unsigned char cmd[MAX_COMMAND_SIZE]; 3245 struct osst_request * SRpnt; 3246 int blks; 3247#if DEBUG 3248 char * name = tape_name(STp); 3249#endif 3250 3251 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */ 3252#if DEBUG 3253 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name); 3254#endif 3255 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) { 3256 return (-EIO); 3257 } 3258 /* error recovery may have bumped us past the header partition */ 3259 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) { 3260#if DEBUG 3261 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name); 3262#endif 3263 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8); 3264 } 3265 } 3266 3267 if (STp->poll) 3268 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120)) 3269 if (osst_recover_wait_frame(STp, aSRpnt, 1)) 3270 return (-EIO); 3271 3272// osst_build_stats(STp, &SRpnt); 3273 3274 STp->ps[STp->partition].rw = ST_WRITING; 3275 STp->write_type = OS_WRITE_DATA; 3276 3277 memset(cmd, 0, MAX_COMMAND_SIZE); 3278 cmd[0] = WRITE_6; 3279 cmd[1] = 1; 3280 cmd[4] = 1; /* one frame at a time... */ 3281 blks = STp->buffer->buffer_bytes / STp->block_size; 3282#if DEBUG 3283 if (debugging) 3284 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks, 3285 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1); 3286#endif 3287 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++, 3288 STp->logical_blk_num - blks, STp->block_size, blks); 3289 3290#if DEBUG 3291 if (!synchronous) 3292 STp->write_pending = 1; 3293#endif 3294 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout, 3295 MAX_RETRIES, synchronous); 3296 if (!SRpnt) 3297 return (-EBUSY); 3298 *aSRpnt = SRpnt; 3299 3300 if (synchronous) { 3301 if (STp->buffer->syscall_result != 0) { 3302#if DEBUG 3303 if (debugging) 3304 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name); 3305#endif 3306 if ((SRpnt->sense[0] & 0x70) == 0x70 && 3307 (SRpnt->sense[2] & 0x40)) { 3308 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW) 3309 return (-ENOSPC); 3310 } 3311 else { 3312 if (osst_write_error_recovery(STp, aSRpnt, 1)) 3313 return (-EIO); 3314 } 3315 } 3316 else 3317 STp->first_frame_position++; 3318 } 3319 3320 STp->write_count++; 3321 3322 return 0; 3323} 3324 3325/* Lock or unlock the drive door. Don't use when struct osst_request allocated. */ 3326static int do_door_lock(struct osst_tape * STp, int do_lock) 3327{ 3328 int retval, cmd; 3329 3330 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK; 3331#if DEBUG 3332 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl"); 3333#endif 3334 retval = scsi_ioctl(STp->device, cmd, NULL); 3335 if (!retval) { 3336 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED; 3337 } 3338 else { 3339 STp->door_locked = ST_LOCK_FAILS; 3340 } 3341 return retval; 3342} 3343 3344/* Set the internal state after reset */ 3345static void reset_state(struct osst_tape *STp) 3346{ 3347 int i; 3348 struct st_partstat *STps; 3349 3350 STp->pos_unknown = 0; 3351 for (i = 0; i < ST_NBR_PARTITIONS; i++) { 3352 STps = &(STp->ps[i]); 3353 STps->rw = ST_IDLE; 3354 STps->eof = ST_NOEOF; 3355 STps->at_sm = 0; 3356 STps->last_block_valid = 0; 3357 STps->drv_block = -1; 3358 STps->drv_file = -1; 3359 } 3360} 3361 3362 3363/* Entry points to osst */ 3364 3365/* Write command */ 3366static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos) 3367{ 3368 ssize_t total, retval = 0; 3369 ssize_t i, do_count, blks, transfer; 3370 int write_threshold; 3371 int doing_write = 0; 3372 const char __user * b_point; 3373 struct osst_request * SRpnt = NULL; 3374 struct st_modedef * STm; 3375 struct st_partstat * STps; 3376 struct osst_tape * STp = filp->private_data; 3377 char * name = tape_name(STp); 3378 3379 3380 if (mutex_lock_interruptible(&STp->lock)) 3381 return (-ERESTARTSYS); 3382 3383 /* 3384 * If we are in the middle of error recovery, don't let anyone 3385 * else try and use this device. Also, if error recovery fails, it 3386 * may try and take the device offline, in which case all further 3387 * access to the device is prohibited. 3388 */ 3389 if( !scsi_block_when_processing_errors(STp->device) ) { 3390 retval = (-ENXIO); 3391 goto out; 3392 } 3393 3394 if (STp->ready != ST_READY) { 3395 if (STp->ready == ST_NO_TAPE) 3396 retval = (-ENOMEDIUM); 3397 else 3398 retval = (-EIO); 3399 goto out; 3400 } 3401 STm = &(STp->modes[STp->current_mode]); 3402 if (!STm->defined) { 3403 retval = (-ENXIO); 3404 goto out; 3405 } 3406 if (count == 0) 3407 goto out; 3408 3409 /* 3410 * If there was a bus reset, block further access 3411 * to this device. 3412 */ 3413 if (STp->pos_unknown) { 3414 retval = (-EIO); 3415 goto out; 3416 } 3417 3418#if DEBUG 3419 if (!STp->in_use) { 3420 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name); 3421 retval = (-EIO); 3422 goto out; 3423 } 3424#endif 3425 3426 if (STp->write_prot) { 3427 retval = (-EACCES); 3428 goto out; 3429 } 3430 3431 /* Write must be integral number of blocks */ 3432 if (STp->block_size != 0 && (count % STp->block_size) != 0) { 3433 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n", 3434 name, count, STp->block_size<1024? 3435 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k'); 3436 retval = (-EINVAL); 3437 goto out; 3438 } 3439 3440 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) { 3441 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n", 3442 name, STp->first_frame_position); 3443 retval = (-ENOSPC); 3444 goto out; 3445 } 3446 3447 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1)) 3448 STp->door_locked = ST_LOCKED_AUTO; 3449 3450 STps = &(STp->ps[STp->partition]); 3451 3452 if (STps->rw == ST_READING) { 3453#if DEBUG 3454 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name, 3455 STps->drv_file, STps->drv_block); 3456#endif 3457 retval = osst_flush_buffer(STp, &SRpnt, 0); 3458 if (retval) 3459 goto out; 3460 STps->rw = ST_IDLE; 3461 } 3462 if (STps->rw != ST_WRITING) { 3463 /* Are we totally rewriting this tape? */ 3464 if (!STp->header_ok || 3465 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) || 3466 (STps->drv_file == 0 && STps->drv_block == 0)) { 3467 STp->wrt_pass_cntr++; 3468#if DEBUG 3469 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n", 3470 name, STp->wrt_pass_cntr); 3471#endif 3472 osst_reset_header(STp, &SRpnt); 3473 STps->drv_file = STps->drv_block = 0; 3474 } 3475 /* Do we know where we'll be writing on the tape? */ 3476 else { 3477 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) || 3478 STps->drv_file < 0 || STps->drv_block < 0) { 3479 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */ 3480 STps->drv_file = STp->filemark_cnt; 3481 STps->drv_block = 0; 3482 } 3483 else { 3484 /* We have no idea where the tape is positioned - give up */ 3485#if DEBUG 3486 printk(OSST_DEB_MSG 3487 "%s:D: Cannot write at indeterminate position.\n", name); 3488#endif 3489 retval = (-EIO); 3490 goto out; 3491 } 3492 } 3493 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) { 3494 STp->filemark_cnt = STps->drv_file; 3495 STp->last_mark_ppos = 3496 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]); 3497 printk(KERN_WARNING 3498 "%s:W: Overwriting file %d with old write pass counter %d\n", 3499 name, STps->drv_file, STp->wrt_pass_cntr); 3500 printk(KERN_WARNING 3501 "%s:W: may lead to stale data being accepted on reading back!\n", 3502 name); 3503#if DEBUG 3504 printk(OSST_DEB_MSG 3505 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n", 3506 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn); 3507#endif 3508 } 3509 } 3510 STp->fast_open = 0; 3511 } 3512 if (!STp->header_ok) { 3513#if DEBUG 3514 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name); 3515#endif 3516 retval = (-EIO); 3517 goto out; 3518 } 3519 3520 if ((STp->buffer)->writing) { 3521if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__); 3522 osst_write_behind_check(STp); 3523 if ((STp->buffer)->syscall_result) { 3524#if DEBUG 3525 if (debugging) 3526 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name, 3527 (STp->buffer)->midlevel_result); 3528#endif 3529 if ((STp->buffer)->midlevel_result == INT_MAX) 3530 STps->eof = ST_EOM_OK; 3531 else 3532 STps->eof = ST_EOM_ERROR; 3533 } 3534 } 3535 if (STps->eof == ST_EOM_OK) { 3536 retval = (-ENOSPC); 3537 goto out; 3538 } 3539 else if (STps->eof == ST_EOM_ERROR) { 3540 retval = (-EIO); 3541 goto out; 3542 } 3543 3544 /* Check the buffer readability in cases where copy_user might catch 3545 the problems after some tape movement. */ 3546 if ((copy_from_user(&i, buf, 1) != 0 || 3547 copy_from_user(&i, buf + count - 1, 1) != 0)) { 3548 retval = (-EFAULT); 3549 goto out; 3550 } 3551 3552 if (!STm->do_buffer_writes) { 3553 write_threshold = 1; 3554 } 3555 else 3556 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size; 3557 if (!STm->do_async_writes) 3558 write_threshold--; 3559 3560 total = count; 3561#if DEBUG 3562 if (debugging) 3563 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n", 3564 name, (int) count, STps->drv_file, STps->drv_block, 3565 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position); 3566#endif 3567 b_point = buf; 3568 while ((STp->buffer)->buffer_bytes + count > write_threshold) 3569 { 3570 doing_write = 1; 3571 do_count = (STp->buffer)->buffer_blocks * STp->block_size - 3572 (STp->buffer)->buffer_bytes; 3573 if (do_count > count) 3574 do_count = count; 3575 3576 i = append_to_buffer(b_point, STp->buffer, do_count); 3577 if (i) { 3578 retval = i; 3579 goto out; 3580 } 3581 3582 blks = do_count / STp->block_size; 3583 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */ 3584 3585 i = osst_write_frame(STp, &SRpnt, 1); 3586 3587 if (i == (-ENOSPC)) { 3588 transfer = STp->buffer->writing; 3589 if (transfer <= do_count) { 3590 *ppos += do_count - transfer; 3591 count -= do_count - transfer; 3592 if (STps->drv_block >= 0) { 3593 STps->drv_block += (do_count - transfer) / STp->block_size; 3594 } 3595 STps->eof = ST_EOM_OK; 3596 retval = (-ENOSPC); /* EOM within current request */ 3597#if DEBUG 3598 if (debugging) 3599 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n", 3600 name, (int) transfer); 3601#endif 3602 } 3603 else { 3604 STps->eof = ST_EOM_ERROR; 3605 STps->drv_block = (-1); /* Too cautious? */ 3606 retval = (-EIO); /* EOM for old data */ 3607#if DEBUG 3608 if (debugging) 3609 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name); 3610#endif 3611 } 3612 } 3613 else 3614 retval = i; 3615 3616 if (retval < 0) { 3617 if (SRpnt != NULL) { 3618 osst_release_request(SRpnt); 3619 SRpnt = NULL; 3620 } 3621 STp->buffer->buffer_bytes = 0; 3622 STp->dirty = 0; 3623 if (count < total) 3624 retval = total - count; 3625 goto out; 3626 } 3627 3628 *ppos += do_count; 3629 b_point += do_count; 3630 count -= do_count; 3631 if (STps->drv_block >= 0) { 3632 STps->drv_block += blks; 3633 } 3634 STp->buffer->buffer_bytes = 0; 3635 STp->dirty = 0; 3636 } /* end while write threshold exceeded */ 3637 3638 if (count != 0) { 3639 STp->dirty = 1; 3640 i = append_to_buffer(b_point, STp->buffer, count); 3641 if (i) { 3642 retval = i; 3643 goto out; 3644 } 3645 blks = count / STp->block_size; 3646 STp->logical_blk_num += blks; 3647 if (STps->drv_block >= 0) { 3648 STps->drv_block += blks; 3649 } 3650 *ppos += count; 3651 count = 0; 3652 } 3653 3654 if (doing_write && (STp->buffer)->syscall_result != 0) { 3655 retval = (STp->buffer)->syscall_result; 3656 goto out; 3657 } 3658 3659 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) { 3660 /* Schedule an asynchronous write */ 3661 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes / 3662 STp->block_size) * STp->block_size; 3663 STp->dirty = !((STp->buffer)->writing == 3664 (STp->buffer)->buffer_bytes); 3665 3666 i = osst_write_frame(STp, &SRpnt, 0); 3667 if (i < 0) { 3668 retval = (-EIO); 3669 goto out; 3670 } 3671 SRpnt = NULL; /* Prevent releasing this request! */ 3672 } 3673 STps->at_sm &= (total == 0); 3674 if (total > 0) 3675 STps->eof = ST_NOEOF; 3676 3677 retval = total; 3678 3679out: 3680 if (SRpnt != NULL) osst_release_request(SRpnt); 3681 3682 mutex_unlock(&STp->lock); 3683 3684 return retval; 3685} 3686 3687 3688/* Read command */ 3689static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos) 3690{ 3691 ssize_t total, retval = 0; 3692 ssize_t i, transfer; 3693 int special; 3694 struct st_modedef * STm; 3695 struct st_partstat * STps; 3696 struct osst_request * SRpnt = NULL; 3697 struct osst_tape * STp = filp->private_data; 3698 char * name = tape_name(STp); 3699 3700 3701 if (mutex_lock_interruptible(&STp->lock)) 3702 return (-ERESTARTSYS); 3703 3704 /* 3705 * If we are in the middle of error recovery, don't let anyone 3706 * else try and use this device. Also, if error recovery fails, it 3707 * may try and take the device offline, in which case all further 3708 * access to the device is prohibited. 3709 */ 3710 if( !scsi_block_when_processing_errors(STp->device) ) { 3711 retval = (-ENXIO); 3712 goto out; 3713 } 3714 3715 if (STp->ready != ST_READY) { 3716 if (STp->ready == ST_NO_TAPE) 3717 retval = (-ENOMEDIUM); 3718 else 3719 retval = (-EIO); 3720 goto out; 3721 } 3722 STm = &(STp->modes[STp->current_mode]); 3723 if (!STm->defined) { 3724 retval = (-ENXIO); 3725 goto out; 3726 } 3727#if DEBUG 3728 if (!STp->in_use) { 3729 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name); 3730 retval = (-EIO); 3731 goto out; 3732 } 3733#endif 3734 /* Must have initialized medium */ 3735 if (!STp->header_ok) { 3736 retval = (-EIO); 3737 goto out; 3738 } 3739 3740 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1)) 3741 STp->door_locked = ST_LOCKED_AUTO; 3742 3743 STps = &(STp->ps[STp->partition]); 3744 if (STps->rw == ST_WRITING) { 3745 retval = osst_flush_buffer(STp, &SRpnt, 0); 3746 if (retval) 3747 goto out; 3748 STps->rw = ST_IDLE; 3749 } 3750 3751 if ((count % STp->block_size) != 0) { 3752 printk(KERN_WARNING 3753 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count, 3754 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k'); 3755 } 3756 3757#if DEBUG 3758 if (debugging && STps->eof != ST_NOEOF) 3759 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name, 3760 STps->eof, (STp->buffer)->buffer_bytes); 3761#endif 3762 if ((STp->buffer)->buffer_bytes == 0 && 3763 STps->eof >= ST_EOD_1) { 3764 if (STps->eof < ST_EOD) { 3765 STps->eof += 1; 3766 retval = 0; 3767 goto out; 3768 } 3769 retval = (-EIO); /* EOM or Blank Check */ 3770 goto out; 3771 } 3772 3773 /* Check the buffer writability before any tape movement. Don't alter 3774 buffer data. */ 3775 if (copy_from_user(&i, buf, 1) != 0 || 3776 copy_to_user (buf, &i, 1) != 0 || 3777 copy_from_user(&i, buf + count - 1, 1) != 0 || 3778 copy_to_user (buf + count - 1, &i, 1) != 0) { 3779 retval = (-EFAULT); 3780 goto out; 3781 } 3782 3783 /* Loop until enough data in buffer or a special condition found */ 3784 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) { 3785 3786 /* Get new data if the buffer is empty */ 3787 if ((STp->buffer)->buffer_bytes == 0) { 3788 if (STps->eof == ST_FM_HIT) 3789 break; 3790 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0); 3791 if (special < 0) { /* No need to continue read */ 3792 STp->frame_in_buffer = 0; 3793 retval = special; 3794 goto out; 3795 } 3796 } 3797 3798 /* Move the data from driver buffer to user buffer */ 3799 if ((STp->buffer)->buffer_bytes > 0) { 3800#if DEBUG 3801 if (debugging && STps->eof != ST_NOEOF) 3802 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name, 3803 STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total)); 3804#endif 3805 /* force multiple of block size, note block_size may have been adjusted */ 3806 transfer = (((STp->buffer)->buffer_bytes < count - total ? 3807 (STp->buffer)->buffer_bytes : count - total)/ 3808 STp->block_size) * STp->block_size; 3809 3810 if (transfer == 0) { 3811 printk(KERN_WARNING 3812 "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n", 3813 name, count, STp->block_size < 1024? 3814 STp->block_size:STp->block_size/1024, 3815 STp->block_size<1024?'b':'k'); 3816 break; 3817 } 3818 i = from_buffer(STp->buffer, buf, transfer); 3819 if (i) { 3820 retval = i; 3821 goto out; 3822 } 3823 STp->logical_blk_num += transfer / STp->block_size; 3824 STps->drv_block += transfer / STp->block_size; 3825 *ppos += transfer; 3826 buf += transfer; 3827 total += transfer; 3828 } 3829 3830 if ((STp->buffer)->buffer_bytes == 0) { 3831#if DEBUG 3832 if (debugging) 3833 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n", 3834 name, STp->frame_seq_number); 3835#endif 3836 STp->frame_in_buffer = 0; 3837 STp->frame_seq_number++; /* frame to look for next time */ 3838 } 3839 } /* for (total = 0, special = 0; total < count && !special; ) */ 3840 3841 /* Change the eof state if no data from tape or buffer */ 3842 if (total == 0) { 3843 if (STps->eof == ST_FM_HIT) { 3844 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM; 3845 STps->drv_block = 0; 3846 if (STps->drv_file >= 0) 3847 STps->drv_file++; 3848 } 3849 else if (STps->eof == ST_EOD_1) { 3850 STps->eof = ST_EOD_2; 3851 if (STps->drv_block > 0 && STps->drv_file >= 0) 3852 STps->drv_file++; 3853 STps->drv_block = 0; 3854 } 3855 else if (STps->eof == ST_EOD_2) 3856 STps->eof = ST_EOD; 3857 } 3858 else if (STps->eof == ST_FM) 3859 STps->eof = ST_NOEOF; 3860 3861 retval = total; 3862 3863out: 3864 if (SRpnt != NULL) osst_release_request(SRpnt); 3865 3866 mutex_unlock(&STp->lock); 3867 3868 return retval; 3869} 3870 3871 3872/* Set the driver options */ 3873static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name) 3874{ 3875 printk(KERN_INFO 3876"%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n", 3877 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes, 3878 STm->do_read_ahead); 3879 printk(KERN_INFO 3880"%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n", 3881 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock); 3882 printk(KERN_INFO 3883"%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n", 3884 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions, 3885 STp->scsi2_logical); 3886 printk(KERN_INFO 3887"%s:I: sysv: %d\n", name, STm->sysv); 3888#if DEBUG 3889 printk(KERN_INFO 3890 "%s:D: debugging: %d\n", 3891 name, debugging); 3892#endif 3893} 3894 3895 3896static int osst_set_options(struct osst_tape *STp, long options) 3897{ 3898 int value; 3899 long code; 3900 struct st_modedef * STm; 3901 char * name = tape_name(STp); 3902 3903 STm = &(STp->modes[STp->current_mode]); 3904 if (!STm->defined) { 3905 memcpy(STm, &(STp->modes[0]), sizeof(*STm)); 3906 modes_defined = 1; 3907#if DEBUG 3908 if (debugging) 3909 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n", 3910 name, STp->current_mode); 3911#endif 3912 } 3913 3914 code = options & MT_ST_OPTIONS; 3915 if (code == MT_ST_BOOLEANS) { 3916 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0; 3917 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0; 3918 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0; 3919 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0; 3920 STp->two_fm = (options & MT_ST_TWO_FM) != 0; 3921 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0; 3922 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0; 3923 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0; 3924 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0; 3925 if ((STp->device)->scsi_level >= SCSI_2) 3926 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0; 3927 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0; 3928 STm->sysv = (options & MT_ST_SYSV) != 0; 3929#if DEBUG 3930 debugging = (options & MT_ST_DEBUGGING) != 0; 3931#endif 3932 osst_log_options(STp, STm, name); 3933 } 3934 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) { 3935 value = (code == MT_ST_SETBOOLEANS); 3936 if ((options & MT_ST_BUFFER_WRITES) != 0) 3937 STm->do_buffer_writes = value; 3938 if ((options & MT_ST_ASYNC_WRITES) != 0) 3939 STm->do_async_writes = value; 3940 if ((options & MT_ST_DEF_WRITES) != 0) 3941 STm->defaults_for_writes = value; 3942 if ((options & MT_ST_READ_AHEAD) != 0) 3943 STm->do_read_ahead = value; 3944 if ((options & MT_ST_TWO_FM) != 0) 3945 STp->two_fm = value; 3946 if ((options & MT_ST_FAST_MTEOM) != 0) 3947 STp->fast_mteom = value; 3948 if ((options & MT_ST_AUTO_LOCK) != 0) 3949 STp->do_auto_lock = value; 3950 if ((options & MT_ST_CAN_BSR) != 0) 3951 STp->can_bsr = value; 3952 if ((options & MT_ST_NO_BLKLIMS) != 0) 3953 STp->omit_blklims = value; 3954 if ((STp->device)->scsi_level >= SCSI_2 && 3955 (options & MT_ST_CAN_PARTITIONS) != 0) 3956 STp->can_partitions = value; 3957 if ((options & MT_ST_SCSI2LOGICAL) != 0) 3958 STp->scsi2_logical = value; 3959 if ((options & MT_ST_SYSV) != 0) 3960 STm->sysv = value; 3961#if DEBUG 3962 if ((options & MT_ST_DEBUGGING) != 0) 3963 debugging = value; 3964#endif 3965 osst_log_options(STp, STm, name); 3966 } 3967 else if (code == MT_ST_WRITE_THRESHOLD) { 3968 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE; 3969 if (value < 1 || value > osst_buffer_size) { 3970 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n", 3971 name, value); 3972 return (-EIO); 3973 } 3974 STp->write_threshold = value; 3975 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n", 3976 name, value); 3977 } 3978 else if (code == MT_ST_DEF_BLKSIZE) { 3979 value = (options & ~MT_ST_OPTIONS); 3980 if (value == ~MT_ST_OPTIONS) { 3981 STm->default_blksize = (-1); 3982 printk(KERN_INFO "%s:I: Default block size disabled.\n", name); 3983 } 3984 else { 3985 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) { 3986 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n", 3987 name, value); 3988 return (-EINVAL); 3989 } 3990 STm->default_blksize = value; 3991 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n", 3992 name, STm->default_blksize); 3993 } 3994 } 3995 else if (code == MT_ST_TIMEOUTS) { 3996 value = (options & ~MT_ST_OPTIONS); 3997 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) { 3998 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ; 3999 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name, 4000 (value & ~MT_ST_SET_LONG_TIMEOUT)); 4001 } 4002 else { 4003 STp->timeout = value * HZ; 4004 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value); 4005 } 4006 } 4007 else if (code == MT_ST_DEF_OPTIONS) { 4008 code = (options & ~MT_ST_CLEAR_DEFAULT); 4009 value = (options & MT_ST_CLEAR_DEFAULT); 4010 if (code == MT_ST_DEF_DENSITY) { 4011 if (value == MT_ST_CLEAR_DEFAULT) { 4012 STm->default_density = (-1); 4013 printk(KERN_INFO "%s:I: Density default disabled.\n", name); 4014 } 4015 else { 4016 STm->default_density = value & 0xff; 4017 printk(KERN_INFO "%s:I: Density default set to %x\n", 4018 name, STm->default_density); 4019 } 4020 } 4021 else if (code == MT_ST_DEF_DRVBUFFER) { 4022 if (value == MT_ST_CLEAR_DEFAULT) { 4023 STp->default_drvbuffer = 0xff; 4024 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name); 4025 } 4026 else { 4027 STp->default_drvbuffer = value & 7; 4028 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n", 4029 name, STp->default_drvbuffer); 4030 } 4031 } 4032 else if (code == MT_ST_DEF_COMPRESSION) { 4033 if (value == MT_ST_CLEAR_DEFAULT) { 4034 STm->default_compression = ST_DONT_TOUCH; 4035 printk(KERN_INFO "%s:I: Compression default disabled.\n", name); 4036 } 4037 else { 4038 STm->default_compression = (value & 1 ? ST_YES : ST_NO); 4039 printk(KERN_INFO "%s:I: Compression default set to %x\n", 4040 name, (value & 1)); 4041 } 4042 } 4043 } 4044 else 4045 return (-EIO); 4046 4047 return 0; 4048} 4049 4050 4051/* Internal ioctl function */ 4052static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt, 4053 unsigned int cmd_in, unsigned long arg) 4054{ 4055 int timeout; 4056 long ltmp; 4057 int i, ioctl_result; 4058 int chg_eof = 1; 4059 unsigned char cmd[MAX_COMMAND_SIZE]; 4060 struct osst_request * SRpnt = * aSRpnt; 4061 struct st_partstat * STps; 4062 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num; 4063 int datalen = 0, direction = DMA_NONE; 4064 char * name = tape_name(STp); 4065 4066 if (STp->ready != ST_READY && cmd_in != MTLOAD) { 4067 if (STp->ready == ST_NO_TAPE) 4068 return (-ENOMEDIUM); 4069 else 4070 return (-EIO); 4071 } 4072 timeout = STp->long_timeout; 4073 STps = &(STp->ps[STp->partition]); 4074 fileno = STps->drv_file; 4075 blkno = STps->drv_block; 4076 at_sm = STps->at_sm; 4077 frame_seq_numbr = STp->frame_seq_number; 4078 logical_blk_num = STp->logical_blk_num; 4079 4080 memset(cmd, 0, MAX_COMMAND_SIZE); 4081 switch (cmd_in) { 4082 case MTFSFM: 4083 chg_eof = 0; /* Changed from the FSF after this */ 4084 case MTFSF: 4085 if (STp->raw) 4086 return (-EIO); 4087 if (STp->linux_media) 4088 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg); 4089 else 4090 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg); 4091 if (fileno >= 0) 4092 fileno += arg; 4093 blkno = 0; 4094 at_sm &= (arg == 0); 4095 goto os_bypass; 4096 4097 case MTBSF: 4098 chg_eof = 0; /* Changed from the FSF after this */ 4099 case MTBSFM: 4100 if (STp->raw) 4101 return (-EIO); 4102 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg); 4103 if (fileno >= 0) 4104 fileno -= arg; 4105 blkno = (-1); /* We can't know the block number */ 4106 at_sm &= (arg == 0); 4107 goto os_bypass; 4108 4109 case MTFSR: 4110 case MTBSR: 4111#if DEBUG 4112 if (debugging) 4113 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n", 4114 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num); 4115#endif 4116 if (cmd_in == MTFSR) { 4117 logical_blk_num += arg; 4118 if (blkno >= 0) blkno += arg; 4119 } 4120 else { 4121 logical_blk_num -= arg; 4122 if (blkno >= 0) blkno -= arg; 4123 } 4124 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num); 4125 fileno = STps->drv_file; 4126 blkno = STps->drv_block; 4127 at_sm &= (arg == 0); 4128 goto os_bypass; 4129 4130 case MTFSS: 4131 cmd[0] = SPACE; 4132 cmd[1] = 0x04; /* Space Setmarks */ 4133 cmd[2] = (arg >> 16); 4134 cmd[3] = (arg >> 8); 4135 cmd[4] = arg; 4136#if DEBUG 4137 if (debugging) 4138 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name, 4139 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]); 4140#endif 4141 if (arg != 0) { 4142 blkno = fileno = (-1); 4143 at_sm = 1; 4144 } 4145 break; 4146 case MTBSS: 4147 cmd[0] = SPACE; 4148 cmd[1] = 0x04; /* Space Setmarks */ 4149 ltmp = (-arg); 4150 cmd[2] = (ltmp >> 16); 4151 cmd[3] = (ltmp >> 8); 4152 cmd[4] = ltmp; 4153#if DEBUG 4154 if (debugging) { 4155 if (cmd[2] & 0x80) 4156 ltmp = 0xff000000; 4157 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4]; 4158 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n", 4159 name, (-ltmp)); 4160 } 4161#endif 4162 if (arg != 0) { 4163 blkno = fileno = (-1); 4164 at_sm = 1; 4165 } 4166 break; 4167 case MTWEOF: 4168 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) { 4169 STp->write_type = OS_WRITE_DATA; 4170 ioctl_result = osst_flush_write_buffer(STp, &SRpnt); 4171 } else 4172 ioctl_result = 0; 4173#if DEBUG 4174 if (debugging) 4175 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg); 4176#endif 4177 for (i=0; i<arg; i++) 4178 ioctl_result |= osst_write_filemark(STp, &SRpnt); 4179 if (fileno >= 0) fileno += arg; 4180 if (blkno >= 0) blkno = 0; 4181 goto os_bypass; 4182 4183 case MTWSM: 4184 if (STp->write_prot) 4185 return (-EACCES); 4186 if (!STp->raw) 4187 return 0; 4188 cmd[0] = WRITE_FILEMARKS; 4189 if (cmd_in == MTWSM) 4190 cmd[1] = 2; 4191 cmd[2] = (arg >> 16); 4192 cmd[3] = (arg >> 8); 4193 cmd[4] = arg; 4194 timeout = STp->timeout; 4195#if DEBUG 4196 if (debugging) 4197 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name, 4198 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]); 4199#endif 4200 if (fileno >= 0) 4201 fileno += arg; 4202 blkno = 0; 4203 at_sm = (cmd_in == MTWSM); 4204 break; 4205 case MTOFFL: 4206 case MTLOAD: 4207 case MTUNLOAD: 4208 case MTRETEN: 4209 cmd[0] = START_STOP; 4210 cmd[1] = 1; /* Don't wait for completion */ 4211 if (cmd_in == MTLOAD) { 4212 if (STp->ready == ST_NO_TAPE) 4213 cmd[4] = 4; /* open tray */ 4214 else 4215 cmd[4] = 1; /* load */ 4216 } 4217 if (cmd_in == MTRETEN) 4218 cmd[4] = 3; /* retension then mount */ 4219 if (cmd_in == MTOFFL) 4220 cmd[4] = 4; /* rewind then eject */ 4221 timeout = STp->timeout; 4222#if DEBUG 4223 if (debugging) { 4224 switch (cmd_in) { 4225 case MTUNLOAD: 4226 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name); 4227 break; 4228 case MTLOAD: 4229 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name); 4230 break; 4231 case MTRETEN: 4232 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name); 4233 break; 4234 case MTOFFL: 4235 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name); 4236 break; 4237 } 4238 } 4239#endif 4240 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ; 4241 break; 4242 case MTNOP: 4243#if DEBUG 4244 if (debugging) 4245 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name); 4246#endif 4247 return 0; /* Should do something ? */ 4248 break; 4249 case MTEOM: 4250#if DEBUG 4251 if (debugging) 4252 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name); 4253#endif 4254 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) || 4255 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) { 4256 ioctl_result = -EIO; 4257 goto os_bypass; 4258 } 4259 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) { 4260#if DEBUG 4261 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name); 4262#endif 4263 ioctl_result = -EIO; 4264 goto os_bypass; 4265 } 4266 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0); 4267 fileno = STp->filemark_cnt; 4268 blkno = at_sm = 0; 4269 goto os_bypass; 4270 4271 case MTERASE: 4272 if (STp->write_prot) 4273 return (-EACCES); 4274 ioctl_result = osst_reset_header(STp, &SRpnt); 4275 i = osst_write_eod(STp, &SRpnt); 4276 if (i < ioctl_result) ioctl_result = i; 4277 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos); 4278 if (i < ioctl_result) ioctl_result = i; 4279 fileno = blkno = at_sm = 0 ; 4280 goto os_bypass; 4281 4282 case MTREW: 4283 cmd[0] = REZERO_UNIT; /* rewind */ 4284 cmd[1] = 1; 4285#if DEBUG 4286 if (debugging) 4287 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]); 4288#endif 4289 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ; 4290 break; 4291 4292 case MTSETBLK: /* Set block length */ 4293 if ((STps->drv_block == 0 ) && 4294 !STp->dirty && 4295 ((STp->buffer)->buffer_bytes == 0) && 4296 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) && 4297 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) && 4298 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) { 4299 /* 4300 * Only allowed to change the block size if you opened the 4301 * device at the beginning of a file before writing anything. 4302 * Note, that when reading, changing block_size is futile, 4303 * as the size used when writing overrides it. 4304 */ 4305 STp->block_size = (arg & MT_ST_BLKSIZE_MASK); 4306 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n", 4307 name, STp->block_size); 4308 return 0; 4309 } 4310 case MTSETDENSITY: /* Set tape density */ 4311 case MTSETDRVBUFFER: /* Set drive buffering */ 4312 case SET_DENS_AND_BLK: /* Set density and block size */ 4313 chg_eof = 0; 4314 if (STp->dirty || (STp->buffer)->buffer_bytes != 0) 4315 return (-EIO); /* Not allowed if data in buffer */ 4316 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) && 4317 (arg & MT_ST_BLKSIZE_MASK) != 0 && 4318 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) { 4319 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n", 4320 name, (int)(arg & MT_ST_BLKSIZE_MASK), 4321 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now"); 4322 return (-EINVAL); 4323 } 4324 return 0; 4325 4326 default: 4327 return (-ENOSYS); 4328 } 4329 4330 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1); 4331 4332 ioctl_result = (STp->buffer)->syscall_result; 4333 4334 if (!SRpnt) { 4335#if DEBUG 4336 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name); 4337#endif 4338 return ioctl_result; 4339 } 4340 4341 if (!ioctl_result) { /* SCSI command successful */ 4342 STp->frame_seq_number = frame_seq_numbr; 4343 STp->logical_blk_num = logical_blk_num; 4344 } 4345 4346os_bypass: 4347#if DEBUG 4348 if (debugging) 4349 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result); 4350#endif 4351 4352 if (!ioctl_result) { /* success */ 4353 4354 if (cmd_in == MTFSFM) { 4355 fileno--; 4356 blkno--; 4357 } 4358 if (cmd_in == MTBSFM) { 4359 fileno++; 4360 blkno++; 4361 } 4362 STps->drv_block = blkno; 4363 STps->drv_file = fileno; 4364 STps->at_sm = at_sm; 4365 4366 if (cmd_in == MTEOM) 4367 STps->eof = ST_EOD; 4368 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) { 4369 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1); 4370 STps->drv_block++; 4371 STp->logical_blk_num++; 4372 STp->frame_seq_number++; 4373 STp->frame_in_buffer = 0; 4374 STp->buffer->read_pointer = 0; 4375 } 4376 else if (cmd_in == MTFSF) 4377 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM; 4378 else if (chg_eof) 4379 STps->eof = ST_NOEOF; 4380 4381 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD) 4382 STp->rew_at_close = 0; 4383 else if (cmd_in == MTLOAD) { 4384 for (i=0; i < ST_NBR_PARTITIONS; i++) { 4385 STp->ps[i].rw = ST_IDLE; 4386 STp->ps[i].last_block_valid = 0; 4387 } 4388 STp->partition = 0; 4389 } 4390 4391 if (cmd_in == MTREW) { 4392 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos); 4393 if (ioctl_result > 0) 4394 ioctl_result = 0; 4395 } 4396 4397 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) { 4398 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0) 4399 STps->drv_file = STps->drv_block = -1; 4400 else 4401 STps->drv_file = STps->drv_block = 0; 4402 STps->eof = ST_NOEOF; 4403 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) { 4404 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) 4405 STps->drv_file = STps->drv_block = -1; 4406 else { 4407 STps->drv_file = STp->filemark_cnt; 4408 STps->drv_block = 0; 4409 } 4410 STps->eof = ST_EOD; 4411 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) { 4412 STps->drv_file = STps->drv_block = (-1); 4413 STps->eof = ST_NOEOF; 4414 STp->header_ok = 0; 4415 } else if (cmd_in == MTERASE) { 4416 STp->header_ok = 0; 4417 } else if (SRpnt) { /* SCSI command was not completely successful. */ 4418 if (SRpnt->sense[2] & 0x40) { 4419 STps->eof = ST_EOM_OK; 4420 STps->drv_block = 0; 4421 } 4422 if (chg_eof) 4423 STps->eof = ST_NOEOF; 4424 4425 if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK) 4426 STps->eof = ST_EOD; 4427 4428 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60)) 4429 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE); 4430 } 4431 *aSRpnt = SRpnt; 4432 4433 return ioctl_result; 4434} 4435 4436 4437/* Open the device */ 4438static int __os_scsi_tape_open(struct inode * inode, struct file * filp) 4439{ 4440 unsigned short flags; 4441 int i, b_size, new_session = 0, retval = 0; 4442 unsigned char cmd[MAX_COMMAND_SIZE]; 4443 struct osst_request * SRpnt = NULL; 4444 struct osst_tape * STp; 4445 struct st_modedef * STm; 4446 struct st_partstat * STps; 4447 char * name; 4448 int dev = TAPE_NR(inode); 4449 int mode = TAPE_MODE(inode); 4450 4451 /* 4452 * We really want to do nonseekable_open(inode, filp); here, but some 4453 * versions of tar incorrectly call lseek on tapes and bail out if that 4454 * fails. So we disallow pread() and pwrite(), but permit lseeks. 4455 */ 4456 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); 4457 4458 write_lock(&os_scsi_tapes_lock); 4459 if (dev >= osst_max_dev || os_scsi_tapes == NULL || 4460 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) { 4461 write_unlock(&os_scsi_tapes_lock); 4462 return (-ENXIO); 4463 } 4464 4465 name = tape_name(STp); 4466 4467 if (STp->in_use) { 4468 write_unlock(&os_scsi_tapes_lock); 4469#if DEBUG 4470 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name); 4471#endif 4472 return (-EBUSY); 4473 } 4474 if (scsi_device_get(STp->device)) { 4475 write_unlock(&os_scsi_tapes_lock); 4476#if DEBUG 4477 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name); 4478#endif 4479 return (-ENXIO); 4480 } 4481 filp->private_data = STp; 4482 STp->in_use = 1; 4483 write_unlock(&os_scsi_tapes_lock); 4484 STp->rew_at_close = TAPE_REWIND(inode); 4485 4486 if( !scsi_block_when_processing_errors(STp->device) ) { 4487 return -ENXIO; 4488 } 4489 4490 if (mode != STp->current_mode) { 4491#if DEBUG 4492 if (debugging) 4493 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n", 4494 name, STp->current_mode, mode); 4495#endif 4496 new_session = 1; 4497 STp->current_mode = mode; 4498 } 4499 STm = &(STp->modes[STp->current_mode]); 4500 4501 flags = filp->f_flags; 4502 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY); 4503 4504 STp->raw = TAPE_IS_RAW(inode); 4505 if (STp->raw) 4506 STp->header_ok = 0; 4507 4508 /* Allocate data segments for this device's tape buffer */ 4509 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) { 4510 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name); 4511 retval = (-EOVERFLOW); 4512 goto err_out; 4513 } 4514 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) { 4515 for (i = 0, b_size = 0; 4516 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); 4517 b_size += STp->buffer->sg[i++].length); 4518 STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size); 4519#if DEBUG 4520 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name, 4521 STp->buffer->b_data, page_address(STp->buffer->sg[0].page)); 4522 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name, 4523 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page)); 4524#endif 4525 } else { 4526 STp->buffer->aux = NULL; /* this had better never happen! */ 4527 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE); 4528 retval = (-EIO); 4529 goto err_out; 4530 } 4531 STp->buffer->writing = 0; 4532 STp->buffer->syscall_result = 0; 4533 STp->dirty = 0; 4534 for (i=0; i < ST_NBR_PARTITIONS; i++) { 4535 STps = &(STp->ps[i]); 4536 STps->rw = ST_IDLE; 4537 } 4538 STp->ready = ST_READY; 4539#if DEBUG 4540 STp->nbr_waits = STp->nbr_finished = 0; 4541#endif 4542 4543 memset (cmd, 0, MAX_COMMAND_SIZE); 4544 cmd[0] = TEST_UNIT_READY; 4545 4546 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 4547 if (!SRpnt) { 4548 retval = (STp->buffer)->syscall_result; 4549 goto err_out; 4550 } 4551 if ((SRpnt->sense[0] & 0x70) == 0x70 && 4552 (SRpnt->sense[2] & 0x0f) == NOT_READY && 4553 SRpnt->sense[12] == 4 ) { 4554#if DEBUG 4555 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]); 4556#endif 4557 if (filp->f_flags & O_NONBLOCK) { 4558 retval = -EAGAIN; 4559 goto err_out; 4560 } 4561 if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */ 4562 memset (cmd, 0, MAX_COMMAND_SIZE); 4563 cmd[0] = START_STOP; 4564 cmd[1] = 1; 4565 cmd[4] = 1; 4566 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, 4567 STp->timeout, MAX_RETRIES, 1); 4568 } 4569 osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0); 4570 } 4571 if ((SRpnt->sense[0] & 0x70) == 0x70 && 4572 (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */ 4573#if DEBUG 4574 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name); 4575#endif 4576 STp->header_ok = 0; 4577 4578 for (i=0; i < 10; i++) { 4579 4580 memset (cmd, 0, MAX_COMMAND_SIZE); 4581 cmd[0] = TEST_UNIT_READY; 4582 4583 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, 4584 STp->timeout, MAX_RETRIES, 1); 4585 if ((SRpnt->sense[0] & 0x70) != 0x70 || 4586 (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION) 4587 break; 4588 } 4589 4590 STp->pos_unknown = 0; 4591 STp->partition = STp->new_partition = 0; 4592 if (STp->can_partitions) 4593 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */ 4594 for (i=0; i < ST_NBR_PARTITIONS; i++) { 4595 STps = &(STp->ps[i]); 4596 STps->rw = ST_IDLE; 4597 STps->eof = ST_NOEOF; 4598 STps->at_sm = 0; 4599 STps->last_block_valid = 0; 4600 STps->drv_block = 0; 4601 STps->drv_file = 0 ; 4602 } 4603 new_session = 1; 4604 STp->recover_count = 0; 4605 STp->abort_count = 0; 4606 } 4607 /* 4608 * if we have valid headers from before, and the drive/tape seem untouched, 4609 * open without reconfiguring and re-reading the headers 4610 */ 4611 if (!STp->buffer->syscall_result && STp->header_ok && 4612 !SRpnt->result && SRpnt->sense[0] == 0) { 4613 4614 memset(cmd, 0, MAX_COMMAND_SIZE); 4615 cmd[0] = MODE_SENSE; 4616 cmd[1] = 8; 4617 cmd[2] = VENDOR_IDENT_PAGE; 4618 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH; 4619 4620 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); 4621 4622 if (STp->buffer->syscall_result || 4623 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' || 4624 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' || 4625 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' || 4626 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) { 4627#if DEBUG 4628 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name, 4629 STp->buffer->b_data[MODE_HEADER_LENGTH + 2], 4630 STp->buffer->b_data[MODE_HEADER_LENGTH + 3], 4631 STp->buffer->b_data[MODE_HEADER_LENGTH + 4], 4632 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]); 4633#endif 4634 STp->header_ok = 0; 4635 } 4636 i = STp->first_frame_position; 4637 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) { 4638 if (STp->door_locked == ST_UNLOCKED) { 4639 if (do_door_lock(STp, 1)) 4640 printk(KERN_INFO "%s:I: Can't lock drive door\n", name); 4641 else 4642 STp->door_locked = ST_LOCKED_AUTO; 4643 } 4644 if (!STp->frame_in_buffer) { 4645 STp->block_size = (STm->default_blksize > 0) ? 4646 STm->default_blksize : OS_DATA_SIZE; 4647 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0; 4648 } 4649 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size; 4650 STp->fast_open = 1; 4651 osst_release_request(SRpnt); 4652 return 0; 4653 } 4654#if DEBUG 4655 if (i != STp->first_frame_position) 4656 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n", 4657 name, i, STp->first_frame_position); 4658#endif 4659 STp->header_ok = 0; 4660 } 4661 STp->fast_open = 0; 4662 4663 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */ 4664 (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) { 4665 4666 memset(cmd, 0, MAX_COMMAND_SIZE); 4667 cmd[0] = MODE_SELECT; 4668 cmd[1] = 0x10; 4669 cmd[4] = 4 + MODE_HEADER_LENGTH; 4670 4671 (STp->buffer)->b_data[0] = cmd[4] - 1; 4672 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */ 4673 (STp->buffer)->b_data[2] = 0; /* Reserved */ 4674 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */ 4675 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f; 4676 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1; 4677 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2; 4678 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3; 4679 4680#if DEBUG 4681 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name); 4682#endif 4683 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); 4684 4685 STp->header_ok = 0; 4686 4687 for (i=0; i < 10; i++) { 4688 4689 memset (cmd, 0, MAX_COMMAND_SIZE); 4690 cmd[0] = TEST_UNIT_READY; 4691 4692 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, 4693 STp->timeout, MAX_RETRIES, 1); 4694 if ((SRpnt->sense[0] & 0x70) != 0x70 || 4695 (SRpnt->sense[2] & 0x0f) == NOT_READY) 4696 break; 4697 4698 if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { 4699 STp->pos_unknown = 0; 4700 STp->partition = STp->new_partition = 0; 4701 if (STp->can_partitions) 4702 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */ 4703 for (i=0; i < ST_NBR_PARTITIONS; i++) { 4704 STps = &(STp->ps[i]); 4705 STps->rw = ST_IDLE; 4706 STps->eof = ST_NOEOF; 4707 STps->at_sm = 0; 4708 STps->last_block_valid = 0; 4709 STps->drv_block = 0; 4710 STps->drv_file = 0 ; 4711 } 4712 new_session = 1; 4713 } 4714 } 4715 } 4716 4717 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) 4718 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name); 4719 4720 if ((STp->buffer)->syscall_result != 0) { 4721 if ((STp->device)->scsi_level >= SCSI_2 && 4722 (SRpnt->sense[0] & 0x70) == 0x70 && 4723 (SRpnt->sense[2] & 0x0f) == NOT_READY && 4724 SRpnt->sense[12] == 0x3a) { /* Check ASC */ 4725 STp->ready = ST_NO_TAPE; 4726 } else 4727 STp->ready = ST_NOT_READY; 4728 osst_release_request(SRpnt); 4729 SRpnt = NULL; 4730 STp->density = 0; /* Clear the erroneous "residue" */ 4731 STp->write_prot = 0; 4732 STp->block_size = 0; 4733 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1); 4734 STp->partition = STp->new_partition = 0; 4735 STp->door_locked = ST_UNLOCKED; 4736 return 0; 4737 } 4738 4739 osst_configure_onstream(STp, &SRpnt); 4740 4741 STp->block_size = STp->raw ? OS_FRAME_SIZE : ( 4742 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE); 4743 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size; 4744 STp->buffer->buffer_bytes = 4745 STp->buffer->read_pointer = 4746 STp->frame_in_buffer = 0; 4747 4748#if DEBUG 4749 if (debugging) 4750 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n", 4751 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size, 4752 (STp->buffer)->buffer_blocks); 4753#endif 4754 4755 if (STp->drv_write_prot) { 4756 STp->write_prot = 1; 4757#if DEBUG 4758 if (debugging) 4759 printk(OSST_DEB_MSG "%s:D: Write protected\n", name); 4760#endif 4761 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) { 4762 retval = (-EROFS); 4763 goto err_out; 4764 } 4765 } 4766 4767 if (new_session) { /* Change the drive parameters for the new mode */ 4768#if DEBUG 4769 if (debugging) 4770 printk(OSST_DEB_MSG "%s:D: New Session\n", name); 4771#endif 4772 STp->density_changed = STp->blksize_changed = 0; 4773 STp->compression_changed = 0; 4774 } 4775 4776 /* 4777 * properly position the tape and check the ADR headers 4778 */ 4779 if (STp->door_locked == ST_UNLOCKED) { 4780 if (do_door_lock(STp, 1)) 4781 printk(KERN_INFO "%s:I: Can't lock drive door\n", name); 4782 else 4783 STp->door_locked = ST_LOCKED_AUTO; 4784 } 4785 4786 osst_analyze_headers(STp, &SRpnt); 4787 4788 osst_release_request(SRpnt); 4789 SRpnt = NULL; 4790 4791 return 0; 4792 4793err_out: 4794 if (SRpnt != NULL) 4795 osst_release_request(SRpnt); 4796 normalize_buffer(STp->buffer); 4797 STp->header_ok = 0; 4798 STp->in_use = 0; 4799 scsi_device_put(STp->device); 4800 4801 return retval; 4802} 4803 4804/* BKL pushdown: spaghetti avoidance wrapper */ 4805static int os_scsi_tape_open(struct inode * inode, struct file * filp) 4806{ 4807 int ret; 4808 4809 lock_kernel(); 4810 ret = __os_scsi_tape_open(inode, filp); 4811 unlock_kernel(); 4812 return ret; 4813} 4814 4815 4816 4817/* Flush the tape buffer before close */ 4818static int os_scsi_tape_flush(struct file * filp, fl_owner_t id) 4819{ 4820 int result = 0, result2; 4821 struct osst_tape * STp = filp->private_data; 4822 struct st_modedef * STm = &(STp->modes[STp->current_mode]); 4823 struct st_partstat * STps = &(STp->ps[STp->partition]); 4824 struct osst_request * SRpnt = NULL; 4825 char * name = tape_name(STp); 4826 4827 if (file_count(filp) > 1) 4828 return 0; 4829 4830 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) { 4831 STp->write_type = OS_WRITE_DATA; 4832 result = osst_flush_write_buffer(STp, &SRpnt); 4833 if (result != 0 && result != (-ENOSPC)) 4834 goto out; 4835 } 4836 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) { 4837 4838#if DEBUG 4839 if (debugging) { 4840 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n", 4841 name, (long)(filp->f_pos)); 4842 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n", 4843 name, STp->nbr_waits, STp->nbr_finished); 4844 } 4845#endif 4846 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close)); 4847#if DEBUG 4848 if (debugging) 4849 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n", 4850 name, 1+STp->two_fm); 4851#endif 4852 } 4853 else if (!STp->rew_at_close) { 4854 STps = &(STp->ps[STp->partition]); 4855 if (!STm->sysv || STps->rw != ST_READING) { 4856 if (STp->can_bsr) 4857 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */ 4858 else if (STps->eof == ST_FM_HIT) { 4859 result = cross_eof(STp, &SRpnt, 0); 4860 if (result) { 4861 if (STps->drv_file >= 0) 4862 STps->drv_file++; 4863 STps->drv_block = 0; 4864 STps->eof = ST_FM; 4865 } 4866 else 4867 STps->eof = ST_NOEOF; 4868 } 4869 } 4870 else if ((STps->eof == ST_NOEOF && 4871 !(result = cross_eof(STp, &SRpnt, 1))) || 4872 STps->eof == ST_FM_HIT) { 4873 if (STps->drv_file >= 0) 4874 STps->drv_file++; 4875 STps->drv_block = 0; 4876 STps->eof = ST_FM; 4877 } 4878 } 4879 4880out: 4881 if (STp->rew_at_close) { 4882 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos); 4883 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0; 4884 if (result == 0 && result2 < 0) 4885 result = result2; 4886 } 4887 if (SRpnt) osst_release_request(SRpnt); 4888 4889 if (STp->abort_count || STp->recover_count) { 4890 printk(KERN_INFO "%s:I:", name); 4891 if (STp->abort_count) 4892 printk(" %d unrecovered errors", STp->abort_count); 4893 if (STp->recover_count) 4894 printk(" %d recovered errors", STp->recover_count); 4895 if (STp->write_count) 4896 printk(" in %d frames written", STp->write_count); 4897 if (STp->read_count) 4898 printk(" in %d frames read", STp->read_count); 4899 printk("\n"); 4900 STp->recover_count = 0; 4901 STp->abort_count = 0; 4902 } 4903 STp->write_count = 0; 4904 STp->read_count = 0; 4905 4906 return result; 4907} 4908 4909 4910/* Close the device and release it */ 4911static int os_scsi_tape_close(struct inode * inode, struct file * filp) 4912{ 4913 int result = 0; 4914 struct osst_tape * STp = filp->private_data; 4915 4916 if (STp->door_locked == ST_LOCKED_AUTO) 4917 do_door_lock(STp, 0); 4918 4919 if (STp->raw) 4920 STp->header_ok = 0; 4921 4922 normalize_buffer(STp->buffer); 4923 write_lock(&os_scsi_tapes_lock); 4924 STp->in_use = 0; 4925 write_unlock(&os_scsi_tapes_lock); 4926 4927 scsi_device_put(STp->device); 4928 4929 return result; 4930} 4931 4932 4933/* The ioctl command */ 4934static long osst_ioctl(struct file * file, 4935 unsigned int cmd_in, unsigned long arg) 4936{ 4937 int i, cmd_nr, cmd_type, blk, retval = 0; 4938 struct st_modedef * STm; 4939 struct st_partstat * STps; 4940 struct osst_request * SRpnt = NULL; 4941 struct osst_tape * STp = file->private_data; 4942 char * name = tape_name(STp); 4943 void __user * p = (void __user *)arg; 4944 4945 lock_kernel(); 4946 if (mutex_lock_interruptible(&STp->lock)) { 4947 unlock_kernel(); 4948 return -ERESTARTSYS; 4949 } 4950 4951#if DEBUG 4952 if (debugging && !STp->in_use) { 4953 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name); 4954 retval = (-EIO); 4955 goto out; 4956 } 4957#endif 4958 STm = &(STp->modes[STp->current_mode]); 4959 STps = &(STp->ps[STp->partition]); 4960 4961 /* 4962 * If we are in the middle of error recovery, don't let anyone 4963 * else try and use this device. Also, if error recovery fails, it 4964 * may try and take the device offline, in which case all further 4965 * access to the device is prohibited. 4966 */ 4967 if( !scsi_block_when_processing_errors(STp->device) ) { 4968 retval = (-ENXIO); 4969 goto out; 4970 } 4971 4972 cmd_type = _IOC_TYPE(cmd_in); 4973 cmd_nr = _IOC_NR(cmd_in); 4974#if DEBUG 4975 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name, 4976 cmd_type, cmd_nr, STp->raw?"raw":"normal"); 4977#endif 4978 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) { 4979 struct mtop mtc; 4980 int auto_weof = 0; 4981 4982 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) { 4983 retval = (-EINVAL); 4984 goto out; 4985 } 4986 4987 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop)); 4988 if (i) { 4989 retval = (-EFAULT); 4990 goto out; 4991 } 4992 4993 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) { 4994 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name); 4995 retval = (-EPERM); 4996 goto out; 4997 } 4998 4999 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) { 5000 retval = (-ENXIO); 5001 goto out; 5002 } 5003 5004 if (!STp->pos_unknown) { 5005 5006 if (STps->eof == ST_FM_HIT) { 5007 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) { 5008 mtc.mt_count -= 1; 5009 if (STps->drv_file >= 0) 5010 STps->drv_file += 1; 5011 } 5012 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) { 5013 mtc.mt_count += 1; 5014 if (STps->drv_file >= 0) 5015 STps->drv_file += 1; 5016 } 5017 } 5018 5019 if (mtc.mt_op == MTSEEK) { 5020 /* Old position must be restored if partition will be changed */ 5021 i = !STp->can_partitions || (STp->new_partition != STp->partition); 5022 } 5023 else { 5024 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL || 5025 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM || 5026 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD || 5027 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM || 5028 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM || 5029 mtc.mt_op == MTCOMPRESSION; 5030 } 5031 i = osst_flush_buffer(STp, &SRpnt, i); 5032 if (i < 0) { 5033 retval = i; 5034 goto out; 5035 } 5036 } 5037 else { 5038 /* 5039 * If there was a bus reset, block further access 5040 * to this device. If the user wants to rewind the tape, 5041 * then reset the flag and allow access again. 5042 */ 5043 if(mtc.mt_op != MTREW && 5044 mtc.mt_op != MTOFFL && 5045 mtc.mt_op != MTRETEN && 5046 mtc.mt_op != MTERASE && 5047 mtc.mt_op != MTSEEK && 5048 mtc.mt_op != MTEOM) { 5049 retval = (-EIO); 5050 goto out; 5051 } 5052 reset_state(STp); 5053 /* remove this when the midlevel properly clears was_reset */ 5054 STp->device->was_reset = 0; 5055 } 5056 5057 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK && 5058 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK && 5059 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER && 5060 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART && 5061 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) { 5062 5063 /* 5064 * The user tells us to move to another position on the tape. 5065 * If we were appending to the tape content, that would leave 5066 * the tape without proper end, in that case write EOD and 5067 * update the header to reflect its position. 5068 */ 5069#if DEBUG 5070 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name, 5071 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle", 5072 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number, 5073 STp->logical_blk_num, STps->drv_file, STps->drv_block ); 5074#endif 5075 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) { 5076 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) && 5077 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL)); 5078 i = osst_write_trailer(STp, &SRpnt, 5079 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL)); 5080#if DEBUG 5081 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", 5082 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos, 5083 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block ); 5084#endif 5085 if (i < 0) { 5086 retval = i; 5087 goto out; 5088 } 5089 } 5090 STps->rw = ST_IDLE; 5091 } 5092 5093 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED) 5094 do_door_lock(STp, 0); /* Ignore result! */ 5095 5096 if (mtc.mt_op == MTSETDRVBUFFER && 5097 (mtc.mt_count & MT_ST_OPTIONS) != 0) { 5098 retval = osst_set_options(STp, mtc.mt_count); 5099 goto out; 5100 } 5101 5102 if (mtc.mt_op == MTSETPART) { 5103 if (mtc.mt_count >= STp->nbr_partitions) 5104 retval = -EINVAL; 5105 else { 5106 STp->new_partition = mtc.mt_count; 5107 retval = 0; 5108 } 5109 goto out; 5110 } 5111 5112 if (mtc.mt_op == MTMKPART) { 5113 if (!STp->can_partitions) { 5114 retval = (-EINVAL); 5115 goto out; 5116 } 5117 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*|| 5118 (i = partition_tape(inode, mtc.mt_count)) < 0*/) { 5119 retval = i; 5120 goto out; 5121 } 5122 for (i=0; i < ST_NBR_PARTITIONS; i++) { 5123 STp->ps[i].rw = ST_IDLE; 5124 STp->ps[i].at_sm = 0; 5125 STp->ps[i].last_block_valid = 0; 5126 } 5127 STp->partition = STp->new_partition = 0; 5128 STp->nbr_partitions = 1; /* Bad guess ?-) */ 5129 STps->drv_block = STps->drv_file = 0; 5130 retval = 0; 5131 goto out; 5132 } 5133 5134 if (mtc.mt_op == MTSEEK) { 5135 if (STp->raw) 5136 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0); 5137 else 5138 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count); 5139 if (!STp->can_partitions) 5140 STp->ps[0].rw = ST_IDLE; 5141 retval = i; 5142 goto out; 5143 } 5144 5145 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) { 5146 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK)); 5147 goto out; 5148 } 5149 5150 if (auto_weof) 5151 cross_eof(STp, &SRpnt, 0); 5152 5153 if (mtc.mt_op == MTCOMPRESSION) 5154 retval = -EINVAL; /* OnStream drives don't have compression hardware */ 5155 else 5156 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS 5157 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */ 5158 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count); 5159 goto out; 5160 } 5161 5162 if (!STm->defined) { 5163 retval = (-ENXIO); 5164 goto out; 5165 } 5166 5167 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) { 5168 retval = i; 5169 goto out; 5170 } 5171 5172 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) { 5173 struct mtget mt_status; 5174 5175 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) { 5176 retval = (-EINVAL); 5177 goto out; 5178 } 5179 5180 mt_status.mt_type = MT_ISONSTREAM_SC; 5181 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT; 5182 mt_status.mt_dsreg = 5183 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) | 5184 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK); 5185 mt_status.mt_blkno = STps->drv_block; 5186 mt_status.mt_fileno = STps->drv_file; 5187 if (STp->block_size != 0) { 5188 if (STps->rw == ST_WRITING) 5189 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size; 5190 else if (STps->rw == ST_READING) 5191 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes + 5192 STp->block_size - 1) / STp->block_size; 5193 } 5194 5195 mt_status.mt_gstat = 0; 5196 if (STp->drv_write_prot) 5197 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff); 5198 if (mt_status.mt_blkno == 0) { 5199 if (mt_status.mt_fileno == 0) 5200 mt_status.mt_gstat |= GMT_BOT(0xffffffff); 5201 else 5202 mt_status.mt_gstat |= GMT_EOF(0xffffffff); 5203 } 5204 mt_status.mt_resid = STp->partition; 5205 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR) 5206 mt_status.mt_gstat |= GMT_EOT(0xffffffff); 5207 else if (STps->eof >= ST_EOM_OK) 5208 mt_status.mt_gstat |= GMT_EOD(0xffffffff); 5209 if (STp->density == 1) 5210 mt_status.mt_gstat |= GMT_D_800(0xffffffff); 5211 else if (STp->density == 2) 5212 mt_status.mt_gstat |= GMT_D_1600(0xffffffff); 5213 else if (STp->density == 3) 5214 mt_status.mt_gstat |= GMT_D_6250(0xffffffff); 5215 if (STp->ready == ST_READY) 5216 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff); 5217 if (STp->ready == ST_NO_TAPE) 5218 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff); 5219 if (STps->at_sm) 5220 mt_status.mt_gstat |= GMT_SM(0xffffffff); 5221 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) || 5222 STp->drv_buffer != 0) 5223 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff); 5224 5225 i = copy_to_user(p, &mt_status, sizeof(struct mtget)); 5226 if (i) { 5227 retval = (-EFAULT); 5228 goto out; 5229 } 5230 5231 STp->recover_erreg = 0; /* Clear after read */ 5232 retval = 0; 5233 goto out; 5234 } /* End of MTIOCGET */ 5235 5236 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) { 5237 struct mtpos mt_pos; 5238 5239 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) { 5240 retval = (-EINVAL); 5241 goto out; 5242 } 5243 if (STp->raw) 5244 blk = osst_get_frame_position(STp, &SRpnt); 5245 else 5246 blk = osst_get_sector(STp, &SRpnt); 5247 if (blk < 0) { 5248 retval = blk; 5249 goto out; 5250 } 5251 mt_pos.mt_blkno = blk; 5252 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos)); 5253 if (i) 5254 retval = -EFAULT; 5255 goto out; 5256 } 5257 if (SRpnt) osst_release_request(SRpnt); 5258 5259 mutex_unlock(&STp->lock); 5260 5261 retval = scsi_ioctl(STp->device, cmd_in, p); 5262 unlock_kernel(); 5263 return retval; 5264 5265out: 5266 if (SRpnt) osst_release_request(SRpnt); 5267 5268 mutex_unlock(&STp->lock); 5269 unlock_kernel(); 5270 5271 return retval; 5272} 5273 5274#ifdef CONFIG_COMPAT 5275static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg) 5276{ 5277 struct osst_tape *STp = file->private_data; 5278 struct scsi_device *sdev = STp->device; 5279 int ret = -ENOIOCTLCMD; 5280 if (sdev->host->hostt->compat_ioctl) { 5281 5282 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg); 5283 5284 } 5285 return ret; 5286} 5287#endif 5288 5289 5290 5291/* Memory handling routines */ 5292 5293/* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */ 5294static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg ) 5295{ 5296 int i; 5297 gfp_t priority; 5298 struct osst_buffer *tb; 5299 5300 if (from_initialization) 5301 priority = GFP_ATOMIC; 5302 else 5303 priority = GFP_KERNEL; 5304 5305 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); 5306 tb = kzalloc(i, priority); 5307 if (!tb) { 5308 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n"); 5309 return NULL; 5310 } 5311 5312 tb->sg_segs = tb->orig_sg_segs = 0; 5313 tb->use_sg = max_sg; 5314 tb->in_use = 1; 5315 tb->dma = need_dma; 5316 tb->buffer_size = 0; 5317#if DEBUG 5318 if (debugging) 5319 printk(OSST_DEB_MSG 5320 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n", 5321 i, max_sg, need_dma); 5322#endif 5323 return tb; 5324} 5325 5326/* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */ 5327static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma) 5328{ 5329 int segs, nbr, max_segs, b_size, order, got; 5330 gfp_t priority; 5331 5332 if (STbuffer->buffer_size >= OS_FRAME_SIZE) 5333 return 1; 5334 5335 if (STbuffer->sg_segs) { 5336 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n"); 5337 normalize_buffer(STbuffer); 5338 } 5339 /* See how many segments we can use -- need at least two */ 5340 nbr = max_segs = STbuffer->use_sg; 5341 if (nbr <= 2) 5342 return 0; 5343 5344 priority = GFP_KERNEL /* | __GFP_NOWARN */; 5345 if (need_dma) 5346 priority |= GFP_DMA; 5347 5348 /* Try to allocate the first segment up to OS_DATA_SIZE and the others 5349 big enough to reach the goal (code assumes no segments in place) */ 5350 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) { 5351 struct page *page = alloc_pages(priority, order); 5352 5353 STbuffer->sg[0].offset = 0; 5354 if (page != NULL) { 5355 sg_set_page(&STbuffer->sg[0], page, b_size, 0); 5356 STbuffer->b_data = page_address(page); 5357 break; 5358 } 5359 } 5360 if (sg_page(&STbuffer->sg[0]) == NULL) { 5361 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n"); 5362 return 0; 5363 } 5364 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */ 5365 for (segs=STbuffer->sg_segs=1, got=b_size; 5366 segs < max_segs && got < OS_FRAME_SIZE; ) { 5367 struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order); 5368 STbuffer->sg[segs].offset = 0; 5369 if (page == NULL) { 5370 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n", 5371 OS_FRAME_SIZE); 5372#if DEBUG 5373 STbuffer->buffer_size = got; 5374#endif 5375 normalize_buffer(STbuffer); 5376 return 0; 5377 } 5378 sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0); 5379 got += STbuffer->sg[segs].length; 5380 STbuffer->buffer_size = got; 5381 STbuffer->sg_segs = ++segs; 5382 } 5383#if DEBUG 5384 if (debugging) { 5385 printk(OSST_DEB_MSG 5386 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n", 5387 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data); 5388 printk(OSST_DEB_MSG 5389 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n", 5390 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page), 5391 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page)); 5392 } 5393#endif 5394 5395 return 1; 5396} 5397 5398 5399/* Release the segments */ 5400static void normalize_buffer(struct osst_buffer *STbuffer) 5401{ 5402 int i, order, b_size; 5403 5404 for (i=0; i < STbuffer->sg_segs; i++) { 5405 5406 for (b_size = PAGE_SIZE, order = 0; 5407 b_size < STbuffer->sg[i].length; 5408 b_size *= 2, order++); 5409 5410 __free_pages(sg_page(&STbuffer->sg[i]), order); 5411 STbuffer->buffer_size -= STbuffer->sg[i].length; 5412 } 5413#if DEBUG 5414 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs) 5415 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n", 5416 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs); 5417#endif 5418 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0; 5419} 5420 5421 5422/* Move data from the user buffer to the tape buffer. Returns zero (success) or 5423 negative error code. */ 5424static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count) 5425{ 5426 int i, cnt, res, offset; 5427 5428 for (i=0, offset=st_bp->buffer_bytes; 5429 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) 5430 offset -= st_bp->sg[i].length; 5431 if (i == st_bp->sg_segs) { /* Should never happen */ 5432 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n"); 5433 return (-EIO); 5434 } 5435 for ( ; i < st_bp->sg_segs && do_count > 0; i++) { 5436 cnt = st_bp->sg[i].length - offset < do_count ? 5437 st_bp->sg[i].length - offset : do_count; 5438 res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt); 5439 if (res) 5440 return (-EFAULT); 5441 do_count -= cnt; 5442 st_bp->buffer_bytes += cnt; 5443 ubp += cnt; 5444 offset = 0; 5445 } 5446 if (do_count) { /* Should never happen */ 5447 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n", 5448 do_count); 5449 return (-EIO); 5450 } 5451 return 0; 5452} 5453 5454 5455/* Move data from the tape buffer to the user buffer. Returns zero (success) or 5456 negative error code. */ 5457static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count) 5458{ 5459 int i, cnt, res, offset; 5460 5461 for (i=0, offset=st_bp->read_pointer; 5462 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) 5463 offset -= st_bp->sg[i].length; 5464 if (i == st_bp->sg_segs) { /* Should never happen */ 5465 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n"); 5466 return (-EIO); 5467 } 5468 for ( ; i < st_bp->sg_segs && do_count > 0; i++) { 5469 cnt = st_bp->sg[i].length - offset < do_count ? 5470 st_bp->sg[i].length - offset : do_count; 5471 res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt); 5472 if (res) 5473 return (-EFAULT); 5474 do_count -= cnt; 5475 st_bp->buffer_bytes -= cnt; 5476 st_bp->read_pointer += cnt; 5477 ubp += cnt; 5478 offset = 0; 5479 } 5480 if (do_count) { /* Should never happen */ 5481 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count); 5482 return (-EIO); 5483 } 5484 return 0; 5485} 5486 5487/* Sets the tail of the buffer after fill point to zero. 5488 Returns zero (success) or negative error code. */ 5489static int osst_zero_buffer_tail(struct osst_buffer *st_bp) 5490{ 5491 int i, offset, do_count, cnt; 5492 5493 for (i = 0, offset = st_bp->buffer_bytes; 5494 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) 5495 offset -= st_bp->sg[i].length; 5496 if (i == st_bp->sg_segs) { /* Should never happen */ 5497 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n"); 5498 return (-EIO); 5499 } 5500 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes; 5501 i < st_bp->sg_segs && do_count > 0; i++) { 5502 cnt = st_bp->sg[i].length - offset < do_count ? 5503 st_bp->sg[i].length - offset : do_count ; 5504 memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt); 5505 do_count -= cnt; 5506 offset = 0; 5507 } 5508 if (do_count) { /* Should never happen */ 5509 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count); 5510 return (-EIO); 5511 } 5512 return 0; 5513} 5514 5515/* Copy a osst 32K chunk of memory into the buffer. 5516 Returns zero (success) or negative error code. */ 5517static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr) 5518{ 5519 int i, cnt, do_count = OS_DATA_SIZE; 5520 5521 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) { 5522 cnt = st_bp->sg[i].length < do_count ? 5523 st_bp->sg[i].length : do_count ; 5524 memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt); 5525 do_count -= cnt; 5526 ptr += cnt; 5527 } 5528 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */ 5529 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n", 5530 do_count, i); 5531 return (-EIO); 5532 } 5533 return 0; 5534} 5535 5536/* Copy a osst 32K chunk of memory from the buffer. 5537 Returns zero (success) or negative error code. */ 5538static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr) 5539{ 5540 int i, cnt, do_count = OS_DATA_SIZE; 5541 5542 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) { 5543 cnt = st_bp->sg[i].length < do_count ? 5544 st_bp->sg[i].length : do_count ; 5545 memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt); 5546 do_count -= cnt; 5547 ptr += cnt; 5548 } 5549 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */ 5550 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n", 5551 do_count, i); 5552 return (-EIO); 5553 } 5554 return 0; 5555} 5556 5557 5558/* Module housekeeping */ 5559 5560static void validate_options (void) 5561{ 5562 if (max_dev > 0) 5563 osst_max_dev = max_dev; 5564 if (write_threshold_kbs > 0) 5565 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE; 5566 if (osst_write_threshold > osst_buffer_size) 5567 osst_write_threshold = osst_buffer_size; 5568 if (max_sg_segs >= OSST_FIRST_SG) 5569 osst_max_sg_segs = max_sg_segs; 5570#if DEBUG 5571 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n", 5572 osst_max_dev, osst_write_threshold, osst_max_sg_segs); 5573#endif 5574} 5575 5576#ifndef MODULE 5577static int __init osst_setup (char *str) 5578{ 5579 int i, ints[5]; 5580 char *stp; 5581 5582 stp = get_options(str, ARRAY_SIZE(ints), ints); 5583 5584 if (ints[0] > 0) { 5585 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++) 5586 *parms[i].val = ints[i + 1]; 5587 } else { 5588 while (stp != NULL) { 5589 for (i = 0; i < ARRAY_SIZE(parms); i++) { 5590 int len = strlen(parms[i].name); 5591 if (!strncmp(stp, parms[i].name, len) && 5592 (*(stp + len) == ':' || *(stp + len) == '=')) { 5593 *parms[i].val = 5594 simple_strtoul(stp + len + 1, NULL, 0); 5595 break; 5596 } 5597 } 5598 if (i >= ARRAY_SIZE(parms)) 5599 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n", 5600 stp); 5601 stp = strchr(stp, ','); 5602 if (stp) 5603 stp++; 5604 } 5605 } 5606 5607 return 1; 5608} 5609 5610__setup("osst=", osst_setup); 5611 5612#endif 5613 5614static const struct file_operations osst_fops = { 5615 .owner = THIS_MODULE, 5616 .read = osst_read, 5617 .write = osst_write, 5618 .unlocked_ioctl = osst_ioctl, 5619#ifdef CONFIG_COMPAT 5620 .compat_ioctl = osst_compat_ioctl, 5621#endif 5622 .open = os_scsi_tape_open, 5623 .flush = os_scsi_tape_flush, 5624 .release = os_scsi_tape_close, 5625 .llseek = noop_llseek, 5626}; 5627 5628static int osst_supports(struct scsi_device * SDp) 5629{ 5630 struct osst_support_data { 5631 char *vendor; 5632 char *model; 5633 char *rev; 5634 char *driver_hint; /* Name of the correct driver, NULL if unknown */ 5635 }; 5636 5637static struct osst_support_data support_list[] = { 5638 SIGS_FROM_OSST, 5639 {NULL, }}; 5640 5641 struct osst_support_data *rp; 5642 5643 /* We are willing to drive OnStream SC-x0 as well as the 5644 * * IDE, ParPort, FireWire, USB variants, if accessible by 5645 * * emulation layer (ide-scsi, usb-storage, ...) */ 5646 5647 for (rp=&(support_list[0]); rp->vendor != NULL; rp++) 5648 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) && 5649 !strncmp(rp->model, SDp->model, strlen(rp->model)) && 5650 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) 5651 return 1; 5652 return 0; 5653} 5654 5655/* 5656 * sysfs support for osst driver parameter information 5657 */ 5658 5659static ssize_t osst_version_show(struct device_driver *ddd, char *buf) 5660{ 5661 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version); 5662} 5663 5664static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL); 5665 5666static int osst_create_sysfs_files(struct device_driver *sysfs) 5667{ 5668 return driver_create_file(sysfs, &driver_attr_version); 5669} 5670 5671static void osst_remove_sysfs_files(struct device_driver *sysfs) 5672{ 5673 driver_remove_file(sysfs, &driver_attr_version); 5674} 5675 5676/* 5677 * sysfs support for accessing ADR header information 5678 */ 5679 5680static ssize_t osst_adr_rev_show(struct device *dev, 5681 struct device_attribute *attr, char *buf) 5682{ 5683 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5684 ssize_t l = 0; 5685 5686 if (STp && STp->header_ok && STp->linux_media) 5687 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev); 5688 return l; 5689} 5690 5691DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL); 5692 5693static ssize_t osst_linux_media_version_show(struct device *dev, 5694 struct device_attribute *attr, 5695 char *buf) 5696{ 5697 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5698 ssize_t l = 0; 5699 5700 if (STp && STp->header_ok && STp->linux_media) 5701 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version); 5702 return l; 5703} 5704 5705DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL); 5706 5707static ssize_t osst_capacity_show(struct device *dev, 5708 struct device_attribute *attr, char *buf) 5709{ 5710 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5711 ssize_t l = 0; 5712 5713 if (STp && STp->header_ok && STp->linux_media) 5714 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity); 5715 return l; 5716} 5717 5718DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL); 5719 5720static ssize_t osst_first_data_ppos_show(struct device *dev, 5721 struct device_attribute *attr, 5722 char *buf) 5723{ 5724 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5725 ssize_t l = 0; 5726 5727 if (STp && STp->header_ok && STp->linux_media) 5728 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos); 5729 return l; 5730} 5731 5732DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL); 5733 5734static ssize_t osst_eod_frame_ppos_show(struct device *dev, 5735 struct device_attribute *attr, 5736 char *buf) 5737{ 5738 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5739 ssize_t l = 0; 5740 5741 if (STp && STp->header_ok && STp->linux_media) 5742 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos); 5743 return l; 5744} 5745 5746DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL); 5747 5748static ssize_t osst_filemark_cnt_show(struct device *dev, 5749 struct device_attribute *attr, char *buf) 5750{ 5751 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5752 ssize_t l = 0; 5753 5754 if (STp && STp->header_ok && STp->linux_media) 5755 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt); 5756 return l; 5757} 5758 5759DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL); 5760 5761static struct class *osst_sysfs_class; 5762 5763static int osst_sysfs_init(void) 5764{ 5765 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape"); 5766 if (IS_ERR(osst_sysfs_class)) { 5767 printk(KERN_ERR "osst :W: Unable to register sysfs class\n"); 5768 return PTR_ERR(osst_sysfs_class); 5769 } 5770 5771 return 0; 5772} 5773 5774static void osst_sysfs_destroy(dev_t dev) 5775{ 5776 device_destroy(osst_sysfs_class, dev); 5777} 5778 5779static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name) 5780{ 5781 struct device *osst_member; 5782 int err; 5783 5784 osst_member = device_create(osst_sysfs_class, device, dev, STp, 5785 "%s", name); 5786 if (IS_ERR(osst_member)) { 5787 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); 5788 return PTR_ERR(osst_member); 5789 } 5790 5791 err = device_create_file(osst_member, &dev_attr_ADR_rev); 5792 if (err) 5793 goto err_out; 5794 err = device_create_file(osst_member, &dev_attr_media_version); 5795 if (err) 5796 goto err_out; 5797 err = device_create_file(osst_member, &dev_attr_capacity); 5798 if (err) 5799 goto err_out; 5800 err = device_create_file(osst_member, &dev_attr_BOT_frame); 5801 if (err) 5802 goto err_out; 5803 err = device_create_file(osst_member, &dev_attr_EOD_frame); 5804 if (err) 5805 goto err_out; 5806 err = device_create_file(osst_member, &dev_attr_file_count); 5807 if (err) 5808 goto err_out; 5809 5810 return 0; 5811 5812err_out: 5813 osst_sysfs_destroy(dev); 5814 return err; 5815} 5816 5817static void osst_sysfs_cleanup(void) 5818{ 5819 class_destroy(osst_sysfs_class); 5820} 5821 5822/* 5823 * osst startup / cleanup code 5824 */ 5825 5826static int osst_probe(struct device *dev) 5827{ 5828 struct scsi_device * SDp = to_scsi_device(dev); 5829 struct osst_tape * tpnt; 5830 struct st_modedef * STm; 5831 struct st_partstat * STps; 5832 struct osst_buffer * buffer; 5833 struct gendisk * drive; 5834 int i, dev_num, err = -ENODEV; 5835 5836 if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) 5837 return -ENODEV; 5838 5839 drive = alloc_disk(1); 5840 if (!drive) { 5841 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n"); 5842 return -ENODEV; 5843 } 5844 5845 /* if this is the first attach, build the infrastructure */ 5846 write_lock(&os_scsi_tapes_lock); 5847 if (os_scsi_tapes == NULL) { 5848 os_scsi_tapes = 5849 (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *), 5850 GFP_ATOMIC); 5851 if (os_scsi_tapes == NULL) { 5852 write_unlock(&os_scsi_tapes_lock); 5853 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n"); 5854 goto out_put_disk; 5855 } 5856 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL; 5857 } 5858 5859 if (osst_nr_dev >= osst_max_dev) { 5860 write_unlock(&os_scsi_tapes_lock); 5861 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev); 5862 goto out_put_disk; 5863 } 5864 5865 /* find a free minor number */ 5866 for (i = 0; i < osst_max_dev && os_scsi_tapes[i]; i++) 5867 ; 5868 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)"); 5869 dev_num = i; 5870 5871 /* allocate a struct osst_tape for this device */ 5872 tpnt = kzalloc(sizeof(struct osst_tape), GFP_ATOMIC); 5873 if (!tpnt) { 5874 write_unlock(&os_scsi_tapes_lock); 5875 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n"); 5876 goto out_put_disk; 5877 } 5878 5879 /* allocate a buffer for this device */ 5880 i = SDp->host->sg_tablesize; 5881 if (osst_max_sg_segs < i) 5882 i = osst_max_sg_segs; 5883 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i); 5884 if (buffer == NULL) { 5885 write_unlock(&os_scsi_tapes_lock); 5886 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n"); 5887 kfree(tpnt); 5888 goto out_put_disk; 5889 } 5890 os_scsi_tapes[dev_num] = tpnt; 5891 tpnt->buffer = buffer; 5892 tpnt->device = SDp; 5893 drive->private_data = &tpnt->driver; 5894 sprintf(drive->disk_name, "osst%d", dev_num); 5895 tpnt->driver = &osst_template; 5896 tpnt->drive = drive; 5897 tpnt->in_use = 0; 5898 tpnt->capacity = 0xfffff; 5899 tpnt->dirty = 0; 5900 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */ 5901 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma; 5902 tpnt->density = 0; 5903 tpnt->do_auto_lock = OSST_AUTO_LOCK; 5904 tpnt->can_bsr = OSST_IN_FILE_POS; 5905 tpnt->can_partitions = 0; 5906 tpnt->two_fm = OSST_TWO_FM; 5907 tpnt->fast_mteom = OSST_FAST_MTEOM; 5908 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; 5909 tpnt->write_threshold = osst_write_threshold; 5910 tpnt->default_drvbuffer = 0xff; /* No forced buffering */ 5911 tpnt->partition = 0; 5912 tpnt->new_partition = 0; 5913 tpnt->nbr_partitions = 0; 5914 tpnt->min_block = 512; 5915 tpnt->max_block = OS_DATA_SIZE; 5916 tpnt->timeout = OSST_TIMEOUT; 5917 tpnt->long_timeout = OSST_LONG_TIMEOUT; 5918 5919 /* Recognize OnStream tapes */ 5920 /* We don't need to test for OnStream, as this has been done in detect () */ 5921 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev); 5922 tpnt->omit_blklims = 1; 5923 5924 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || 5925 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp); 5926 tpnt->frame_in_buffer = 0; 5927 tpnt->header_ok = 0; 5928 tpnt->linux_media = 0; 5929 tpnt->header_cache = NULL; 5930 5931 for (i=0; i < ST_NBR_MODES; i++) { 5932 STm = &(tpnt->modes[i]); 5933 STm->defined = 0; 5934 STm->sysv = OSST_SYSV; 5935 STm->defaults_for_writes = 0; 5936 STm->do_async_writes = OSST_ASYNC_WRITES; 5937 STm->do_buffer_writes = OSST_BUFFER_WRITES; 5938 STm->do_read_ahead = OSST_READ_AHEAD; 5939 STm->default_compression = ST_DONT_TOUCH; 5940 STm->default_blksize = 512; 5941 STm->default_density = (-1); /* No forced density */ 5942 } 5943 5944 for (i=0; i < ST_NBR_PARTITIONS; i++) { 5945 STps = &(tpnt->ps[i]); 5946 STps->rw = ST_IDLE; 5947 STps->eof = ST_NOEOF; 5948 STps->at_sm = 0; 5949 STps->last_block_valid = 0; 5950 STps->drv_block = (-1); 5951 STps->drv_file = (-1); 5952 } 5953 5954 tpnt->current_mode = 0; 5955 tpnt->modes[0].defined = 1; 5956 tpnt->modes[2].defined = 1; 5957 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0; 5958 5959 mutex_init(&tpnt->lock); 5960 osst_nr_dev++; 5961 write_unlock(&os_scsi_tapes_lock); 5962 5963 { 5964 char name[8]; 5965 5966 /* Rewind entry */ 5967 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt)); 5968 if (err) 5969 goto out_free_buffer; 5970 5971 /* No-rewind entry */ 5972 snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); 5973 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); 5974 if (err) 5975 goto out_free_sysfs1; 5976 } 5977 5978 sdev_printk(KERN_INFO, SDp, 5979 "osst :I: Attached OnStream %.5s tape as %s\n", 5980 SDp->model, tape_name(tpnt)); 5981 5982 return 0; 5983 5984out_free_sysfs1: 5985 osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num)); 5986out_free_buffer: 5987 kfree(buffer); 5988out_put_disk: 5989 put_disk(drive); 5990 return err; 5991}; 5992 5993static int osst_remove(struct device *dev) 5994{ 5995 struct scsi_device * SDp = to_scsi_device(dev); 5996 struct osst_tape * tpnt; 5997 int i; 5998 5999 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0)) 6000 return 0; 6001 6002 write_lock(&os_scsi_tapes_lock); 6003 for(i=0; i < osst_max_dev; i++) { 6004 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) { 6005 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i)); 6006 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128)); 6007 tpnt->device = NULL; 6008 put_disk(tpnt->drive); 6009 os_scsi_tapes[i] = NULL; 6010 osst_nr_dev--; 6011 write_unlock(&os_scsi_tapes_lock); 6012 vfree(tpnt->header_cache); 6013 if (tpnt->buffer) { 6014 normalize_buffer(tpnt->buffer); 6015 kfree(tpnt->buffer); 6016 } 6017 kfree(tpnt); 6018 return 0; 6019 } 6020 } 6021 write_unlock(&os_scsi_tapes_lock); 6022 return 0; 6023} 6024 6025static int __init init_osst(void) 6026{ 6027 int err; 6028 6029 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid); 6030 6031 validate_options(); 6032 6033 err = osst_sysfs_init(); 6034 if (err) 6035 return err; 6036 6037 err = register_chrdev(OSST_MAJOR, "osst", &osst_fops); 6038 if (err < 0) { 6039 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR); 6040 goto err_out; 6041 } 6042 6043 err = scsi_register_driver(&osst_template.gendrv); 6044 if (err) 6045 goto err_out_chrdev; 6046 6047 err = osst_create_sysfs_files(&osst_template.gendrv); 6048 if (err) 6049 goto err_out_scsidrv; 6050 6051 return 0; 6052 6053err_out_scsidrv: 6054 scsi_unregister_driver(&osst_template.gendrv); 6055err_out_chrdev: 6056 unregister_chrdev(OSST_MAJOR, "osst"); 6057err_out: 6058 osst_sysfs_cleanup(); 6059 return err; 6060} 6061 6062static void __exit exit_osst (void) 6063{ 6064 int i; 6065 struct osst_tape * STp; 6066 6067 osst_remove_sysfs_files(&osst_template.gendrv); 6068 scsi_unregister_driver(&osst_template.gendrv); 6069 unregister_chrdev(OSST_MAJOR, "osst"); 6070 osst_sysfs_cleanup(); 6071 6072 if (os_scsi_tapes) { 6073 for (i=0; i < osst_max_dev; ++i) { 6074 if (!(STp = os_scsi_tapes[i])) continue; 6075 /* This is defensive, supposed to happen during detach */ 6076 vfree(STp->header_cache); 6077 if (STp->buffer) { 6078 normalize_buffer(STp->buffer); 6079 kfree(STp->buffer); 6080 } 6081 put_disk(STp->drive); 6082 kfree(STp); 6083 } 6084 kfree(os_scsi_tapes); 6085 } 6086 printk(KERN_INFO "osst :I: Unloaded.\n"); 6087} 6088 6089module_init(init_osst); 6090module_exit(exit_osst); 6091