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