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.18-rc2 5949 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, retval = 0; 4847 unsigned int blk; 4848 struct st_modedef * STm; 4849 struct st_partstat * STps; 4850 struct osst_request * SRpnt = NULL; 4851 struct osst_tape * STp = file->private_data; 4852 char * name = tape_name(STp); 4853 void __user * p = (void __user *)arg; 4854 4855 if (down_interruptible(&STp->lock)) 4856 return -ERESTARTSYS; 4857 4858#if DEBUG 4859 if (debugging && !STp->in_use) { 4860 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name); 4861 retval = (-EIO); 4862 goto out; 4863 } 4864#endif 4865 STm = &(STp->modes[STp->current_mode]); 4866 STps = &(STp->ps[STp->partition]); 4867 4868 /* 4869 * If we are in the middle of error recovery, don't let anyone 4870 * else try and use this device. Also, if error recovery fails, it 4871 * may try and take the device offline, in which case all further 4872 * access to the device is prohibited. 4873 */ 4874 if( !scsi_block_when_processing_errors(STp->device) ) { 4875 retval = (-ENXIO); 4876 goto out; 4877 } 4878 4879 cmd_type = _IOC_TYPE(cmd_in); 4880 cmd_nr = _IOC_NR(cmd_in); 4881#if DEBUG 4882 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name, 4883 cmd_type, cmd_nr, STp->raw?"raw":"normal"); 4884#endif 4885 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) { 4886 struct mtop mtc; 4887 int auto_weof = 0; 4888 4889 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) { 4890 retval = (-EINVAL); 4891 goto out; 4892 } 4893 4894 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop)); 4895 if (i) { 4896 retval = (-EFAULT); 4897 goto out; 4898 } 4899 4900 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) { 4901 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name); 4902 retval = (-EPERM); 4903 goto out; 4904 } 4905 4906 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) { 4907 retval = (-ENXIO); 4908 goto out; 4909 } 4910 4911 if (!STp->pos_unknown) { 4912 4913 if (STps->eof == ST_FM_HIT) { 4914 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) { 4915 mtc.mt_count -= 1; 4916 if (STps->drv_file >= 0) 4917 STps->drv_file += 1; 4918 } 4919 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) { 4920 mtc.mt_count += 1; 4921 if (STps->drv_file >= 0) 4922 STps->drv_file += 1; 4923 } 4924 } 4925 4926 if (mtc.mt_op == MTSEEK) { 4927 /* Old position must be restored if partition will be changed */ 4928 i = !STp->can_partitions || (STp->new_partition != STp->partition); 4929 } 4930 else { 4931 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL || 4932 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM || 4933 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD || 4934 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM || 4935 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM || 4936 mtc.mt_op == MTCOMPRESSION; 4937 } 4938 i = osst_flush_buffer(STp, &SRpnt, i); 4939 if (i < 0) { 4940 retval = i; 4941 goto out; 4942 } 4943 } 4944 else { 4945 /* 4946 * If there was a bus reset, block further access 4947 * to this device. If the user wants to rewind the tape, 4948 * then reset the flag and allow access again. 4949 */ 4950 if(mtc.mt_op != MTREW && 4951 mtc.mt_op != MTOFFL && 4952 mtc.mt_op != MTRETEN && 4953 mtc.mt_op != MTERASE && 4954 mtc.mt_op != MTSEEK && 4955 mtc.mt_op != MTEOM) { 4956 retval = (-EIO); 4957 goto out; 4958 } 4959 reset_state(STp); 4960 /* remove this when the midlevel properly clears was_reset */ 4961 STp->device->was_reset = 0; 4962 } 4963 4964 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK && 4965 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK && 4966 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER && 4967 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART && 4968 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) { 4969 4970 /* 4971 * The user tells us to move to another position on the tape. 4972 * If we were appending to the tape content, that would leave 4973 * the tape without proper end, in that case write EOD and 4974 * update the header to reflect its position. 4975 */ 4976#if DEBUG 4977 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name, 4978 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle", 4979 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number, 4980 STp->logical_blk_num, STps->drv_file, STps->drv_block ); 4981#endif 4982 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) { 4983 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) && 4984 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL)); 4985 i = osst_write_trailer(STp, &SRpnt, 4986 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL)); 4987#if DEBUG 4988 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", 4989 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos, 4990 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block ); 4991#endif 4992 if (i < 0) { 4993 retval = i; 4994 goto out; 4995 } 4996 } 4997 STps->rw = ST_IDLE; 4998 } 4999 5000 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED) 5001 do_door_lock(STp, 0); /* Ignore result! */ 5002 5003 if (mtc.mt_op == MTSETDRVBUFFER && 5004 (mtc.mt_count & MT_ST_OPTIONS) != 0) { 5005 retval = osst_set_options(STp, mtc.mt_count); 5006 goto out; 5007 } 5008 5009 if (mtc.mt_op == MTSETPART) { 5010 if (mtc.mt_count >= STp->nbr_partitions) 5011 retval = -EINVAL; 5012 else { 5013 STp->new_partition = mtc.mt_count; 5014 retval = 0; 5015 } 5016 goto out; 5017 } 5018 5019 if (mtc.mt_op == MTMKPART) { 5020 if (!STp->can_partitions) { 5021 retval = (-EINVAL); 5022 goto out; 5023 } 5024 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*|| 5025 (i = partition_tape(inode, mtc.mt_count)) < 0*/) { 5026 retval = i; 5027 goto out; 5028 } 5029 for (i=0; i < ST_NBR_PARTITIONS; i++) { 5030 STp->ps[i].rw = ST_IDLE; 5031 STp->ps[i].at_sm = 0; 5032 STp->ps[i].last_block_valid = 0; 5033 } 5034 STp->partition = STp->new_partition = 0; 5035 STp->nbr_partitions = 1; /* Bad guess ?-) */ 5036 STps->drv_block = STps->drv_file = 0; 5037 retval = 0; 5038 goto out; 5039 } 5040 5041 if (mtc.mt_op == MTSEEK) { 5042 if (STp->raw) 5043 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0); 5044 else 5045 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count); 5046 if (!STp->can_partitions) 5047 STp->ps[0].rw = ST_IDLE; 5048 retval = i; 5049 goto out; 5050 } 5051 5052 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) { 5053 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK)); 5054 goto out; 5055 } 5056 5057 if (auto_weof) 5058 cross_eof(STp, &SRpnt, 0); 5059 5060 if (mtc.mt_op == MTCOMPRESSION) 5061 retval = -EINVAL; /* OnStream drives don't have compression hardware */ 5062 else 5063 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS 5064 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */ 5065 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count); 5066 goto out; 5067 } 5068 5069 if (!STm->defined) { 5070 retval = (-ENXIO); 5071 goto out; 5072 } 5073 5074 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) { 5075 retval = i; 5076 goto out; 5077 } 5078 5079 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) { 5080 struct mtget mt_status; 5081 5082 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) { 5083 retval = (-EINVAL); 5084 goto out; 5085 } 5086 5087 mt_status.mt_type = MT_ISONSTREAM_SC; 5088 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT; 5089 mt_status.mt_dsreg = 5090 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) | 5091 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK); 5092 mt_status.mt_blkno = STps->drv_block; 5093 mt_status.mt_fileno = STps->drv_file; 5094 if (STp->block_size != 0) { 5095 if (STps->rw == ST_WRITING) 5096 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size; 5097 else if (STps->rw == ST_READING) 5098 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes + 5099 STp->block_size - 1) / STp->block_size; 5100 } 5101 5102 mt_status.mt_gstat = 0; 5103 if (STp->drv_write_prot) 5104 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff); 5105 if (mt_status.mt_blkno == 0) { 5106 if (mt_status.mt_fileno == 0) 5107 mt_status.mt_gstat |= GMT_BOT(0xffffffff); 5108 else 5109 mt_status.mt_gstat |= GMT_EOF(0xffffffff); 5110 } 5111 mt_status.mt_resid = STp->partition; 5112 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR) 5113 mt_status.mt_gstat |= GMT_EOT(0xffffffff); 5114 else if (STps->eof >= ST_EOM_OK) 5115 mt_status.mt_gstat |= GMT_EOD(0xffffffff); 5116 if (STp->density == 1) 5117 mt_status.mt_gstat |= GMT_D_800(0xffffffff); 5118 else if (STp->density == 2) 5119 mt_status.mt_gstat |= GMT_D_1600(0xffffffff); 5120 else if (STp->density == 3) 5121 mt_status.mt_gstat |= GMT_D_6250(0xffffffff); 5122 if (STp->ready == ST_READY) 5123 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff); 5124 if (STp->ready == ST_NO_TAPE) 5125 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff); 5126 if (STps->at_sm) 5127 mt_status.mt_gstat |= GMT_SM(0xffffffff); 5128 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) || 5129 STp->drv_buffer != 0) 5130 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff); 5131 5132 i = copy_to_user(p, &mt_status, sizeof(struct mtget)); 5133 if (i) { 5134 retval = (-EFAULT); 5135 goto out; 5136 } 5137 5138 STp->recover_erreg = 0; /* Clear after read */ 5139 retval = 0; 5140 goto out; 5141 } /* End of MTIOCGET */ 5142 5143 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) { 5144 struct mtpos mt_pos; 5145 5146 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) { 5147 retval = (-EINVAL); 5148 goto out; 5149 } 5150 if (STp->raw) 5151 blk = osst_get_frame_position(STp, &SRpnt); 5152 else 5153 blk = osst_get_sector(STp, &SRpnt); 5154 if (blk < 0) { 5155 retval = blk; 5156 goto out; 5157 } 5158 mt_pos.mt_blkno = blk; 5159 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos)); 5160 if (i) 5161 retval = -EFAULT; 5162 goto out; 5163 } 5164 if (SRpnt) osst_release_request(SRpnt); 5165 5166 up(&STp->lock); 5167 5168 return scsi_ioctl(STp->device, cmd_in, p); 5169 5170out: 5171 if (SRpnt) osst_release_request(SRpnt); 5172 5173 up(&STp->lock); 5174 5175 return retval; 5176} 5177 5178#ifdef CONFIG_COMPAT 5179static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg) 5180{ 5181 struct osst_tape *STp = file->private_data; 5182 struct scsi_device *sdev = STp->device; 5183 int ret = -ENOIOCTLCMD; 5184 if (sdev->host->hostt->compat_ioctl) { 5185 5186 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg); 5187 5188 } 5189 return ret; 5190} 5191#endif 5192 5193 5194 5195/* Memory handling routines */ 5196 5197/* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */ 5198static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg ) 5199{ 5200 int i; 5201 gfp_t priority; 5202 struct osst_buffer *tb; 5203 5204 if (from_initialization) 5205 priority = GFP_ATOMIC; 5206 else 5207 priority = GFP_KERNEL; 5208 5209 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); 5210 tb = (struct osst_buffer *)kmalloc(i, priority); 5211 if (!tb) { 5212 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n"); 5213 return NULL; 5214 } 5215 memset(tb, 0, i); 5216 tb->sg_segs = tb->orig_sg_segs = 0; 5217 tb->use_sg = max_sg; 5218 tb->in_use = 1; 5219 tb->dma = need_dma; 5220 tb->buffer_size = 0; 5221#if DEBUG 5222 if (debugging) 5223 printk(OSST_DEB_MSG 5224 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n", 5225 i, max_sg, need_dma); 5226#endif 5227 return tb; 5228} 5229 5230/* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */ 5231static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma) 5232{ 5233 int segs, nbr, max_segs, b_size, order, got; 5234 gfp_t priority; 5235 5236 if (STbuffer->buffer_size >= OS_FRAME_SIZE) 5237 return 1; 5238 5239 if (STbuffer->sg_segs) { 5240 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n"); 5241 normalize_buffer(STbuffer); 5242 } 5243 /* See how many segments we can use -- need at least two */ 5244 nbr = max_segs = STbuffer->use_sg; 5245 if (nbr <= 2) 5246 return 0; 5247 5248 priority = GFP_KERNEL /* | __GFP_NOWARN */; 5249 if (need_dma) 5250 priority |= GFP_DMA; 5251 5252 /* Try to allocate the first segment up to OS_DATA_SIZE and the others 5253 big enough to reach the goal (code assumes no segments in place) */ 5254 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) { 5255 STbuffer->sg[0].page = alloc_pages(priority, order); 5256 STbuffer->sg[0].offset = 0; 5257 if (STbuffer->sg[0].page != NULL) { 5258 STbuffer->sg[0].length = b_size; 5259 STbuffer->b_data = page_address(STbuffer->sg[0].page); 5260 break; 5261 } 5262 } 5263 if (STbuffer->sg[0].page == NULL) { 5264 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n"); 5265 return 0; 5266 } 5267 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */ 5268 for (segs=STbuffer->sg_segs=1, got=b_size; 5269 segs < max_segs && got < OS_FRAME_SIZE; ) { 5270 STbuffer->sg[segs].page = 5271 alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order); 5272 STbuffer->sg[segs].offset = 0; 5273 if (STbuffer->sg[segs].page == NULL) { 5274 if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) { 5275 b_size /= 2; /* Large enough for the rest of the buffers */ 5276 order--; 5277 continue; 5278 } 5279 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n", 5280 OS_FRAME_SIZE); 5281#if DEBUG 5282 STbuffer->buffer_size = got; 5283#endif 5284 normalize_buffer(STbuffer); 5285 return 0; 5286 } 5287 STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size; 5288 got += STbuffer->sg[segs].length; 5289 STbuffer->buffer_size = got; 5290 STbuffer->sg_segs = ++segs; 5291 } 5292#if DEBUG 5293 if (debugging) { 5294 printk(OSST_DEB_MSG 5295 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n", 5296 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data); 5297 printk(OSST_DEB_MSG 5298 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n", 5299 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page), 5300 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page)); 5301 } 5302#endif 5303 5304 return 1; 5305} 5306 5307 5308/* Release the segments */ 5309static void normalize_buffer(struct osst_buffer *STbuffer) 5310{ 5311 int i, order, b_size; 5312 5313 for (i=0; i < STbuffer->sg_segs; i++) { 5314 5315 for (b_size = PAGE_SIZE, order = 0; 5316 b_size < STbuffer->sg[i].length; 5317 b_size *= 2, order++); 5318 5319 __free_pages(STbuffer->sg[i].page, order); 5320 STbuffer->buffer_size -= STbuffer->sg[i].length; 5321 } 5322#if DEBUG 5323 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs) 5324 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n", 5325 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs); 5326#endif 5327 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0; 5328} 5329 5330 5331/* Move data from the user buffer to the tape buffer. Returns zero (success) or 5332 negative error code. */ 5333static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count) 5334{ 5335 int i, cnt, res, offset; 5336 5337 for (i=0, offset=st_bp->buffer_bytes; 5338 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) 5339 offset -= st_bp->sg[i].length; 5340 if (i == st_bp->sg_segs) { /* Should never happen */ 5341 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n"); 5342 return (-EIO); 5343 } 5344 for ( ; i < st_bp->sg_segs && do_count > 0; i++) { 5345 cnt = st_bp->sg[i].length - offset < do_count ? 5346 st_bp->sg[i].length - offset : do_count; 5347 res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt); 5348 if (res) 5349 return (-EFAULT); 5350 do_count -= cnt; 5351 st_bp->buffer_bytes += cnt; 5352 ubp += cnt; 5353 offset = 0; 5354 } 5355 if (do_count) { /* Should never happen */ 5356 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n", 5357 do_count); 5358 return (-EIO); 5359 } 5360 return 0; 5361} 5362 5363 5364/* Move data from the tape buffer to the user buffer. Returns zero (success) or 5365 negative error code. */ 5366static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count) 5367{ 5368 int i, cnt, res, offset; 5369 5370 for (i=0, offset=st_bp->read_pointer; 5371 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) 5372 offset -= st_bp->sg[i].length; 5373 if (i == st_bp->sg_segs) { /* Should never happen */ 5374 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n"); 5375 return (-EIO); 5376 } 5377 for ( ; i < st_bp->sg_segs && do_count > 0; i++) { 5378 cnt = st_bp->sg[i].length - offset < do_count ? 5379 st_bp->sg[i].length - offset : do_count; 5380 res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt); 5381 if (res) 5382 return (-EFAULT); 5383 do_count -= cnt; 5384 st_bp->buffer_bytes -= cnt; 5385 st_bp->read_pointer += cnt; 5386 ubp += cnt; 5387 offset = 0; 5388 } 5389 if (do_count) { /* Should never happen */ 5390 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count); 5391 return (-EIO); 5392 } 5393 return 0; 5394} 5395 5396/* Sets the tail of the buffer after fill point to zero. 5397 Returns zero (success) or negative error code. */ 5398static int osst_zero_buffer_tail(struct osst_buffer *st_bp) 5399{ 5400 int i, offset, do_count, cnt; 5401 5402 for (i = 0, offset = st_bp->buffer_bytes; 5403 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) 5404 offset -= st_bp->sg[i].length; 5405 if (i == st_bp->sg_segs) { /* Should never happen */ 5406 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n"); 5407 return (-EIO); 5408 } 5409 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes; 5410 i < st_bp->sg_segs && do_count > 0; i++) { 5411 cnt = st_bp->sg[i].length - offset < do_count ? 5412 st_bp->sg[i].length - offset : do_count ; 5413 memset(page_address(st_bp->sg[i].page) + offset, 0, cnt); 5414 do_count -= cnt; 5415 offset = 0; 5416 } 5417 if (do_count) { /* Should never happen */ 5418 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count); 5419 return (-EIO); 5420 } 5421 return 0; 5422} 5423 5424/* Copy a osst 32K chunk of memory into the buffer. 5425 Returns zero (success) or negative error code. */ 5426static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr) 5427{ 5428 int i, cnt, do_count = OS_DATA_SIZE; 5429 5430 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) { 5431 cnt = st_bp->sg[i].length < do_count ? 5432 st_bp->sg[i].length : do_count ; 5433 memcpy(page_address(st_bp->sg[i].page), ptr, cnt); 5434 do_count -= cnt; 5435 ptr += cnt; 5436 } 5437 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */ 5438 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n", 5439 do_count, i); 5440 return (-EIO); 5441 } 5442 return 0; 5443} 5444 5445/* Copy a osst 32K chunk of memory from the buffer. 5446 Returns zero (success) or negative error code. */ 5447static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr) 5448{ 5449 int i, cnt, do_count = OS_DATA_SIZE; 5450 5451 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) { 5452 cnt = st_bp->sg[i].length < do_count ? 5453 st_bp->sg[i].length : do_count ; 5454 memcpy(ptr, page_address(st_bp->sg[i].page), cnt); 5455 do_count -= cnt; 5456 ptr += cnt; 5457 } 5458 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */ 5459 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n", 5460 do_count, i); 5461 return (-EIO); 5462 } 5463 return 0; 5464} 5465 5466 5467/* Module housekeeping */ 5468 5469static void validate_options (void) 5470{ 5471 if (max_dev > 0) 5472 osst_max_dev = max_dev; 5473 if (write_threshold_kbs > 0) 5474 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE; 5475 if (osst_write_threshold > osst_buffer_size) 5476 osst_write_threshold = osst_buffer_size; 5477 if (max_sg_segs >= OSST_FIRST_SG) 5478 osst_max_sg_segs = max_sg_segs; 5479#if DEBUG 5480 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n", 5481 osst_max_dev, osst_write_threshold, osst_max_sg_segs); 5482#endif 5483} 5484 5485#ifndef MODULE 5486/* Set the boot options. Syntax: osst=xxx,yyy,... 5487 where xxx is write threshold in 1024 byte blocks, 5488 and yyy is number of s/g segments to use. */ 5489static int __init osst_setup (char *str) 5490{ 5491 int i, ints[5]; 5492 char *stp; 5493 5494 stp = get_options(str, ARRAY_SIZE(ints), ints); 5495 5496 if (ints[0] > 0) { 5497 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++) 5498 *parms[i].val = ints[i + 1]; 5499 } else { 5500 while (stp != NULL) { 5501 for (i = 0; i < ARRAY_SIZE(parms); i++) { 5502 int len = strlen(parms[i].name); 5503 if (!strncmp(stp, parms[i].name, len) && 5504 (*(stp + len) == ':' || *(stp + len) == '=')) { 5505 *parms[i].val = 5506 simple_strtoul(stp + len + 1, NULL, 0); 5507 break; 5508 } 5509 } 5510 if (i >= ARRAY_SIZE(parms)) 5511 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n", 5512 stp); 5513 stp = strchr(stp, ','); 5514 if (stp) 5515 stp++; 5516 } 5517 } 5518 5519 return 1; 5520} 5521 5522__setup("osst=", osst_setup); 5523 5524#endif 5525 5526static struct file_operations osst_fops = { 5527 .owner = THIS_MODULE, 5528 .read = osst_read, 5529 .write = osst_write, 5530 .ioctl = osst_ioctl, 5531#ifdef CONFIG_COMPAT 5532 .compat_ioctl = osst_compat_ioctl, 5533#endif 5534 .open = os_scsi_tape_open, 5535 .flush = os_scsi_tape_flush, 5536 .release = os_scsi_tape_close, 5537}; 5538 5539static int osst_supports(struct scsi_device * SDp) 5540{ 5541 struct osst_support_data { 5542 char *vendor; 5543 char *model; 5544 char *rev; 5545 char *driver_hint; /* Name of the correct driver, NULL if unknown */ 5546 }; 5547 5548static struct osst_support_data support_list[] = { 5549 /* {"XXX", "Yy-", "", NULL}, example */ 5550 SIGS_FROM_OSST, 5551 {NULL, }}; 5552 5553 struct osst_support_data *rp; 5554 5555 /* We are willing to drive OnStream SC-x0 as well as the 5556 * * IDE, ParPort, FireWire, USB variants, if accessible by 5557 * * emulation layer (ide-scsi, usb-storage, ...) */ 5558 5559 for (rp=&(support_list[0]); rp->vendor != NULL; rp++) 5560 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) && 5561 !strncmp(rp->model, SDp->model, strlen(rp->model)) && 5562 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) 5563 return 1; 5564 return 0; 5565} 5566 5567/* 5568 * sysfs support for osst driver parameter information 5569 */ 5570 5571static ssize_t osst_version_show(struct device_driver *ddd, char *buf) 5572{ 5573 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version); 5574} 5575 5576static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL); 5577 5578static void osst_create_driverfs_files(struct device_driver *driverfs) 5579{ 5580 driver_create_file(driverfs, &driver_attr_version); 5581} 5582 5583static void osst_remove_driverfs_files(struct device_driver *driverfs) 5584{ 5585 driver_remove_file(driverfs, &driver_attr_version); 5586} 5587 5588/* 5589 * sysfs support for accessing ADR header information 5590 */ 5591 5592static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf) 5593{ 5594 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); 5595 ssize_t l = 0; 5596 5597 if (STp && STp->header_ok && STp->linux_media) 5598 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev); 5599 return l; 5600} 5601 5602CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL); 5603 5604static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf) 5605{ 5606 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); 5607 ssize_t l = 0; 5608 5609 if (STp && STp->header_ok && STp->linux_media) 5610 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version); 5611 return l; 5612} 5613 5614CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL); 5615 5616static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf) 5617{ 5618 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); 5619 ssize_t l = 0; 5620 5621 if (STp && STp->header_ok && STp->linux_media) 5622 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity); 5623 return l; 5624} 5625 5626CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL); 5627 5628static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf) 5629{ 5630 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); 5631 ssize_t l = 0; 5632 5633 if (STp && STp->header_ok && STp->linux_media) 5634 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos); 5635 return l; 5636} 5637 5638CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL); 5639 5640static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf) 5641{ 5642 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); 5643 ssize_t l = 0; 5644 5645 if (STp && STp->header_ok && STp->linux_media) 5646 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos); 5647 return l; 5648} 5649 5650CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL); 5651 5652static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf) 5653{ 5654 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); 5655 ssize_t l = 0; 5656 5657 if (STp && STp->header_ok && STp->linux_media) 5658 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt); 5659 return l; 5660} 5661 5662CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL); 5663 5664static struct class *osst_sysfs_class; 5665 5666static int osst_sysfs_valid = 0; 5667 5668static void osst_sysfs_init(void) 5669{ 5670 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape"); 5671 if ( IS_ERR(osst_sysfs_class) ) 5672 printk(KERN_WARNING "osst :W: Unable to register sysfs class\n"); 5673 else 5674 osst_sysfs_valid = 1; 5675} 5676 5677static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name) 5678{ 5679 struct class_device *osst_class_member; 5680 5681 if (!osst_sysfs_valid) return; 5682 5683 osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name); 5684 if (IS_ERR(osst_class_member)) { 5685 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); 5686 return; 5687 } 5688 class_set_devdata(osst_class_member, STp); 5689 class_device_create_file(osst_class_member, &class_device_attr_ADR_rev); 5690 class_device_create_file(osst_class_member, &class_device_attr_media_version); 5691 class_device_create_file(osst_class_member, &class_device_attr_capacity); 5692 class_device_create_file(osst_class_member, &class_device_attr_BOT_frame); 5693 class_device_create_file(osst_class_member, &class_device_attr_EOD_frame); 5694 class_device_create_file(osst_class_member, &class_device_attr_file_count); 5695} 5696 5697static void osst_sysfs_destroy(dev_t dev) 5698{ 5699 if (!osst_sysfs_valid) return; 5700 5701 class_device_destroy(osst_sysfs_class, dev); 5702} 5703 5704static void osst_sysfs_cleanup(void) 5705{ 5706 if (osst_sysfs_valid) { 5707 class_destroy(osst_sysfs_class); 5708 osst_sysfs_valid = 0; 5709 } 5710} 5711 5712/* 5713 * osst startup / cleanup code 5714 */ 5715 5716static int osst_probe(struct device *dev) 5717{ 5718 struct scsi_device * SDp = to_scsi_device(dev); 5719 struct osst_tape * tpnt; 5720 struct st_modedef * STm; 5721 struct st_partstat * STps; 5722 struct osst_buffer * buffer; 5723 struct gendisk * drive; 5724 int i, dev_num; 5725 5726 if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) 5727 return -ENODEV; 5728 5729 drive = alloc_disk(1); 5730 if (!drive) { 5731 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n"); 5732 return -ENODEV; 5733 } 5734 5735 /* if this is the first attach, build the infrastructure */ 5736 write_lock(&os_scsi_tapes_lock); 5737 if (os_scsi_tapes == NULL) { 5738 os_scsi_tapes = 5739 (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *), 5740 GFP_ATOMIC); 5741 if (os_scsi_tapes == NULL) { 5742 write_unlock(&os_scsi_tapes_lock); 5743 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n"); 5744 goto out_put_disk; 5745 } 5746 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL; 5747 } 5748 5749 if (osst_nr_dev >= osst_max_dev) { 5750 write_unlock(&os_scsi_tapes_lock); 5751 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev); 5752 goto out_put_disk; 5753 } 5754 5755 /* find a free minor number */ 5756 for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++); 5757 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)"); 5758 dev_num = i; 5759 5760 /* allocate a struct osst_tape for this device */ 5761 tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC); 5762 if (tpnt == NULL) { 5763 write_unlock(&os_scsi_tapes_lock); 5764 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n"); 5765 goto out_put_disk; 5766 } 5767 memset(tpnt, 0, sizeof(struct osst_tape)); 5768 5769 /* allocate a buffer for this device */ 5770 i = SDp->host->sg_tablesize; 5771 if (osst_max_sg_segs < i) 5772 i = osst_max_sg_segs; 5773 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i); 5774 if (buffer == NULL) { 5775 write_unlock(&os_scsi_tapes_lock); 5776 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n"); 5777 kfree(tpnt); 5778 goto out_put_disk; 5779 } 5780 os_scsi_tapes[dev_num] = tpnt; 5781 tpnt->buffer = buffer; 5782 tpnt->device = SDp; 5783 drive->private_data = &tpnt->driver; 5784 sprintf(drive->disk_name, "osst%d", dev_num); 5785 tpnt->driver = &osst_template; 5786 tpnt->drive = drive; 5787 tpnt->in_use = 0; 5788 tpnt->capacity = 0xfffff; 5789 tpnt->dirty = 0; 5790 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */ 5791 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma; 5792 tpnt->density = 0; 5793 tpnt->do_auto_lock = OSST_AUTO_LOCK; 5794 tpnt->can_bsr = OSST_IN_FILE_POS; 5795 tpnt->can_partitions = 0; 5796 tpnt->two_fm = OSST_TWO_FM; 5797 tpnt->fast_mteom = OSST_FAST_MTEOM; 5798 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */ 5799 tpnt->write_threshold = osst_write_threshold; 5800 tpnt->default_drvbuffer = 0xff; /* No forced buffering */ 5801 tpnt->partition = 0; 5802 tpnt->new_partition = 0; 5803 tpnt->nbr_partitions = 0; 5804 tpnt->min_block = 512; 5805 tpnt->max_block = OS_DATA_SIZE; 5806 tpnt->timeout = OSST_TIMEOUT; 5807 tpnt->long_timeout = OSST_LONG_TIMEOUT; 5808 5809 /* Recognize OnStream tapes */ 5810 /* We don't need to test for OnStream, as this has been done in detect () */ 5811 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev); 5812 tpnt->omit_blklims = 1; 5813 5814 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || 5815 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp); 5816 tpnt->frame_in_buffer = 0; 5817 tpnt->header_ok = 0; 5818 tpnt->linux_media = 0; 5819 tpnt->header_cache = NULL; 5820 5821 for (i=0; i < ST_NBR_MODES; i++) { 5822 STm = &(tpnt->modes[i]); 5823 STm->defined = 0; 5824 STm->sysv = OSST_SYSV; 5825 STm->defaults_for_writes = 0; 5826 STm->do_async_writes = OSST_ASYNC_WRITES; 5827 STm->do_buffer_writes = OSST_BUFFER_WRITES; 5828 STm->do_read_ahead = OSST_READ_AHEAD; 5829 STm->default_compression = ST_DONT_TOUCH; 5830 STm->default_blksize = 512; 5831 STm->default_density = (-1); /* No forced density */ 5832 } 5833 5834 for (i=0; i < ST_NBR_PARTITIONS; i++) { 5835 STps = &(tpnt->ps[i]); 5836 STps->rw = ST_IDLE; 5837 STps->eof = ST_NOEOF; 5838 STps->at_sm = 0; 5839 STps->last_block_valid = 0; 5840 STps->drv_block = (-1); 5841 STps->drv_file = (-1); 5842 } 5843 5844 tpnt->current_mode = 0; 5845 tpnt->modes[0].defined = 1; 5846 tpnt->modes[2].defined = 1; 5847 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0; 5848 5849 init_MUTEX(&tpnt->lock); 5850 osst_nr_dev++; 5851 write_unlock(&os_scsi_tapes_lock); 5852 { 5853 char name[8]; 5854 /* Rewind entry */ 5855 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt)); 5856 /* No-rewind entry */ 5857 snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); 5858 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); 5859 } 5860 5861 sdev_printk(KERN_INFO, SDp, 5862 "osst :I: Attached OnStream %.5s tape as %s\n", 5863 SDp->model, tape_name(tpnt)); 5864 5865 return 0; 5866 5867out_put_disk: 5868 put_disk(drive); 5869 return -ENODEV; 5870}; 5871 5872static int osst_remove(struct device *dev) 5873{ 5874 struct scsi_device * SDp = to_scsi_device(dev); 5875 struct osst_tape * tpnt; 5876 int i; 5877 5878 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0)) 5879 return 0; 5880 5881 write_lock(&os_scsi_tapes_lock); 5882 for(i=0; i < osst_max_dev; i++) { 5883 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) { 5884 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i)); 5885 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128)); 5886 tpnt->device = NULL; 5887 put_disk(tpnt->drive); 5888 os_scsi_tapes[i] = NULL; 5889 osst_nr_dev--; 5890 write_unlock(&os_scsi_tapes_lock); 5891 vfree(tpnt->header_cache); 5892 if (tpnt->buffer) { 5893 normalize_buffer(tpnt->buffer); 5894 kfree(tpnt->buffer); 5895 } 5896 kfree(tpnt); 5897 return 0; 5898 } 5899 } 5900 write_unlock(&os_scsi_tapes_lock); 5901 return 0; 5902} 5903 5904static int __init init_osst(void) 5905{ 5906 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid); 5907 5908 validate_options(); 5909 osst_sysfs_init(); 5910 5911 if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) { 5912 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR); 5913 osst_sysfs_cleanup(); 5914 return 1; 5915 } 5916 osst_create_driverfs_files(&osst_template.gendrv); 5917 5918 return 0; 5919} 5920 5921static void __exit exit_osst (void) 5922{ 5923 int i; 5924 struct osst_tape * STp; 5925 5926 osst_remove_driverfs_files(&osst_template.gendrv); 5927 scsi_unregister_driver(&osst_template.gendrv); 5928 unregister_chrdev(OSST_MAJOR, "osst"); 5929 osst_sysfs_cleanup(); 5930 5931 if (os_scsi_tapes) { 5932 for (i=0; i < osst_max_dev; ++i) { 5933 if (!(STp = os_scsi_tapes[i])) continue; 5934 /* This is defensive, supposed to happen during detach */ 5935 vfree(STp->header_cache); 5936 if (STp->buffer) { 5937 normalize_buffer(STp->buffer); 5938 kfree(STp->buffer); 5939 } 5940 put_disk(STp->drive); 5941 kfree(STp); 5942 } 5943 kfree(os_scsi_tapes); 5944 } 5945 printk(KERN_INFO "osst :I: Unloaded.\n"); 5946} 5947 5948module_init(init_osst); 5949module_exit(exit_osst);