Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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