2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
3 file Documentation/scsi/st.txt for more information.
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
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.
16 Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede
19 $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
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
26 static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $";
27 static const char * osst_version = "0.99.4";
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)
34 #include <linux/module.h>
37 #include <linux/kernel.h>
38 #include <linux/sched.h>
39 #include <linux/proc_fs.h>
41 #include <linux/init.h>
42 #include <linux/string.h>
43 #include <linux/errno.h>
44 #include <linux/mtio.h>
45 #include <linux/ioctl.h>
46 #include <linux/fcntl.h>
47 #include <linux/spinlock.h>
48 #include <linux/vmalloc.h>
49 #include <linux/blkdev.h>
50 #include <linux/moduleparam.h>
51 #include <linux/delay.h>
52 #include <asm/uaccess.h>
54 #include <asm/system.h>
56 /* The driver prints some debugging information on the console if DEBUG
57 is defined and non-zero. */
60 /* The message level for the debug messages is currently set to KERN_NOTICE
61 so that people can easily see the messages. Later when the debugging messages
62 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
63 #define OSST_DEB_MSG KERN_NOTICE
65 #include <scsi/scsi.h>
66 #include <scsi/scsi_dbg.h>
67 #include <scsi/scsi_device.h>
68 #include <scsi/scsi_driver.h>
69 #include <scsi/scsi_eh.h>
70 #include <scsi/scsi_host.h>
71 #include <scsi/scsi_ioctl.h>
73 #define ST_KILOBYTE 1024
77 #include "osst_options.h"
78 #include "osst_detect.h"
80 static int max_dev = 0;
81 static int write_threshold_kbs = 0;
82 static int max_sg_segs = 0;
85 MODULE_AUTHOR("Willem Riede");
86 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
87 MODULE_LICENSE("GPL");
88 MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR);
90 module_param(max_dev, int, 0444);
91 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
93 module_param(write_threshold_kbs, int, 0644);
94 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
96 module_param(max_sg_segs, int, 0644);
97 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
99 static struct osst_dev_parm {
102 } parms[] __initdata = {
103 { "max_dev", &max_dev },
104 { "write_threshold_kbs", &write_threshold_kbs },
105 { "max_sg_segs", &max_sg_segs }
109 /* Some default definitions have been moved to osst_options.h */
110 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
111 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
113 /* The buffer size should fit into the 24 bits for length in the
114 6-byte SCSI read and write commands. */
115 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
116 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
120 static int debugging = 1;
121 /* uncomment define below to test error recovery */
122 // #define OSST_INJECT_ERRORS 1
125 /* Do not retry! The drive firmware already retries when appropriate,
126 and when it tries to tell us something, we had better listen... */
127 #define MAX_RETRIES 0
129 #define NO_TAPE NOT_READY
131 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
132 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
133 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
135 #define OSST_TIMEOUT (200 * HZ)
136 #define OSST_LONG_TIMEOUT (1800 * HZ)
138 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
139 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
140 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
141 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
143 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
145 #define SET_DENS_AND_BLK 0x10001
147 static int osst_buffer_size = OSST_BUFFER_SIZE;
148 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
149 static int osst_max_sg_segs = OSST_MAX_SG;
150 static int osst_max_dev = OSST_MAX_TAPES;
151 static int osst_nr_dev;
153 static struct osst_tape **os_scsi_tapes = NULL;
154 static DEFINE_RWLOCK(os_scsi_tapes_lock);
156 static int modes_defined = 0;
158 static struct osst_buffer *new_tape_buffer(int, int, int);
159 static int enlarge_buffer(struct osst_buffer *, int);
160 static void normalize_buffer(struct osst_buffer *);
161 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
162 static int from_buffer(struct osst_buffer *, char __user *, int);
163 static int osst_zero_buffer_tail(struct osst_buffer *);
164 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
165 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
167 static int osst_probe(struct device *);
168 static int osst_remove(struct device *);
170 static struct scsi_driver osst_template = {
171 .owner = THIS_MODULE,
175 .remove = osst_remove,
179 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt,
180 unsigned int cmd_in, unsigned long arg);
182 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip);
184 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt);
186 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt);
188 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending);
190 static inline char *tape_name(struct osst_tape *tape)
192 return tape->drive->disk_name;
195 /* Routines that handle the interaction with mid-layer SCSI routines */
198 /* Normalize Sense */
199 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s)
202 const u8 *sense = SRpnt->sense;
204 s->have_sense = scsi_normalize_sense(SRpnt->sense,
205 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
211 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
212 switch (sense[0] & 0x7f) {
217 s->flags = sense[2] & 0xe0;
223 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
224 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
230 /* Convert the result to success code */
231 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
233 char *name = tape_name(STp);
234 int result = SRpnt->result;
235 u8 * sense = SRpnt->sense, scode;
239 struct st_cmdstatus *cmdstatp;
244 cmdstatp = &STp->buffer->cmdstat;
245 osst_analyze_sense(SRpnt, cmdstatp);
247 if (cmdstatp->have_sense)
248 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
253 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
255 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
256 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
257 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
258 name, scode, sense[12], sense[13]);
259 if (cmdstatp->have_sense)
260 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
264 if (cmdstatp->have_sense && (
266 scode != RECOVERED_ERROR &&
267 /* scode != UNIT_ATTENTION && */
268 scode != BLANK_CHECK &&
269 scode != VOLUME_OVERFLOW &&
270 SRpnt->cmd[0] != MODE_SENSE &&
271 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
272 if (cmdstatp->have_sense) {
273 printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
274 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
277 static int notyetprinted = 1;
280 "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
281 name, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
286 "%s:I: This warning may be caused by your scsi controller,\n", name);
288 "%s:I: it has been reported with some Buslogic cards.\n", name);
292 STp->pos_unknown |= STp->device->was_reset;
294 if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
295 STp->recover_count++;
296 STp->recover_erreg++;
299 if (SRpnt->cmd[0] == READ_6)
301 else if (SRpnt->cmd[0] == WRITE_6)
305 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
309 if ((sense[2] & 0xe0) == 0)
316 /* Wakeup from interrupt */
317 static void osst_sleep_done(void *data, char *sense, int result, int resid)
319 struct osst_request *SRpnt = data;
320 struct osst_tape *STp = SRpnt->stp;
322 memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
323 STp->buffer->cmdstat.midlevel_result = SRpnt->result = result;
325 STp->write_pending = 0;
328 complete(SRpnt->waiting);
331 /* osst_request memory management */
332 static struct osst_request *osst_allocate_request(void)
334 return kzalloc(sizeof(struct osst_request), GFP_KERNEL);
337 static void osst_release_request(struct osst_request *streq)
342 /* Do the scsi command. Waits until command performed if do_wait is true.
343 Otherwise osst_write_behind_check() is used to check that the command
345 static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp,
346 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
349 unsigned short use_sg;
350 #ifdef OSST_INJECT_ERRORS
351 static int inject = 0;
352 static int repeat = 0;
354 struct completion *waiting;
356 /* if async, make sure there's no command outstanding */
357 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
358 printk(KERN_ERR "%s: Async command already active.\n",
360 if (signal_pending(current))
361 (STp->buffer)->syscall_result = (-EINTR);
363 (STp->buffer)->syscall_result = (-EBUSY);
368 SRpnt = osst_allocate_request();
370 printk(KERN_ERR "%s: Can't allocate SCSI request.\n",
372 if (signal_pending(current))
373 (STp->buffer)->syscall_result = (-EINTR);
375 (STp->buffer)->syscall_result = (-EBUSY);
381 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
382 which IO is outstanding. It's nulled out when the IO completes. */
384 (STp->buffer)->last_SRpnt = SRpnt;
386 waiting = &STp->wait;
387 init_completion(waiting);
388 SRpnt->waiting = waiting;
390 use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0;
392 bp = (char *)&(STp->buffer->sg[0]);
393 if (STp->buffer->sg_segs < use_sg)
394 use_sg = STp->buffer->sg_segs;
397 bp = (STp->buffer)->b_data;
399 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
400 STp->buffer->cmdstat.have_sense = 0;
401 STp->buffer->syscall_result = 0;
403 if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
404 use_sg, timeout, retries, SRpnt, osst_sleep_done, GFP_KERNEL))
405 /* could not allocate the buffer or request was too large */
406 (STp->buffer)->syscall_result = (-EBUSY);
408 wait_for_completion(waiting);
409 SRpnt->waiting = NULL;
410 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
411 #ifdef OSST_INJECT_ERRORS
412 if (STp->buffer->syscall_result == 0 &&
415 ( (++ inject % 83) == 29 ||
416 (STp->first_frame_position == 240
417 /* or STp->read_error_frame to fail again on the block calculated above */ &&
419 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
420 STp->buffer->last_result_fatal = 1;
428 /* Handle the write-behind checking (downs the semaphore) */
429 static void osst_write_behind_check(struct osst_tape *STp)
431 struct osst_buffer * STbuffer;
433 STbuffer = STp->buffer;
436 if (STp->write_pending)
441 wait_for_completion(&(STp->wait));
442 STp->buffer->last_SRpnt->waiting = NULL;
444 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
446 if (STp->buffer->syscall_result)
447 STp->buffer->syscall_result =
448 osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1);
450 STp->first_frame_position++;
452 osst_release_request(STp->buffer->last_SRpnt);
454 if (STbuffer->writing < STbuffer->buffer_bytes)
455 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
457 STbuffer->last_SRpnt = NULL;
458 STbuffer->buffer_bytes -= STbuffer->writing;
459 STbuffer->writing = 0;
466 /* Onstream specific Routines */
468 * Initialize the OnStream AUX
470 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
471 int logical_blk_num, int blk_sz, int blk_cnt)
473 os_aux_t *aux = STp->buffer->aux;
474 os_partition_t *par = &aux->partition;
475 os_dat_t *dat = &aux->dat;
477 if (STp->raw) return;
479 memset(aux, 0, sizeof(*aux));
480 aux->format_id = htonl(0);
481 memcpy(aux->application_sig, "LIN4", 4);
482 aux->hdwr = htonl(0);
483 aux->frame_type = frame_type;
485 switch (frame_type) {
486 case OS_FRAME_TYPE_HEADER:
487 aux->update_frame_cntr = htonl(STp->update_frame_cntr);
488 par->partition_num = OS_CONFIG_PARTITION;
489 par->par_desc_ver = OS_PARTITION_VERSION;
490 par->wrt_pass_cntr = htons(0xffff);
491 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
492 par->first_frame_ppos = htonl(0);
493 par->last_frame_ppos = htonl(0xbb7);
494 aux->frame_seq_num = htonl(0);
495 aux->logical_blk_num_high = htonl(0);
496 aux->logical_blk_num = htonl(0);
497 aux->next_mark_ppos = htonl(STp->first_mark_ppos);
499 case OS_FRAME_TYPE_DATA:
500 case OS_FRAME_TYPE_MARKER:
505 dat->dat_list[0].blk_sz = htonl(blk_sz);
506 dat->dat_list[0].blk_cnt = htons(blk_cnt);
507 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
508 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
509 dat->dat_list[0].reserved = 0;
510 case OS_FRAME_TYPE_EOD:
511 aux->update_frame_cntr = htonl(0);
512 par->partition_num = OS_DATA_PARTITION;
513 par->par_desc_ver = OS_PARTITION_VERSION;
514 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
515 par->first_frame_ppos = htonl(STp->first_data_ppos);
516 par->last_frame_ppos = htonl(STp->capacity);
517 aux->frame_seq_num = htonl(frame_seq_number);
518 aux->logical_blk_num_high = htonl(0);
519 aux->logical_blk_num = htonl(logical_blk_num);
521 default: ; /* probably FILL */
523 aux->filemark_cnt = ntohl(STp->filemark_cnt);
524 aux->phys_fm = ntohl(0xffffffff);
525 aux->last_mark_ppos = ntohl(STp->last_mark_ppos);
526 aux->last_mark_lbn = ntohl(STp->last_mark_lbn);
530 * Verify that we have the correct tape frame
532 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
534 char * name = tape_name(STp);
535 os_aux_t * aux = STp->buffer->aux;
536 os_partition_t * par = &(aux->partition);
537 struct st_partstat * STps = &(STp->ps[STp->partition]);
538 int blk_cnt, blk_sz, i;
541 if (STp->buffer->syscall_result) {
542 for (i=0; i < STp->buffer->sg_segs; i++)
543 memset(page_address(STp->buffer->sg[i].page),
544 0, STp->buffer->sg[i].length);
545 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
547 STp->buffer->buffer_bytes = OS_FRAME_SIZE;
550 if (STp->buffer->syscall_result) {
552 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
556 if (ntohl(aux->format_id) != 0) {
558 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
562 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
563 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
565 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
569 if (par->partition_num != OS_DATA_PARTITION) {
570 if (!STp->linux_media || STp->linux_media_version != 2) {
572 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
573 name, par->partition_num);
578 if (par->par_desc_ver != OS_PARTITION_VERSION) {
580 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
584 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
586 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
587 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
591 if (aux->frame_type != OS_FRAME_TYPE_DATA &&
592 aux->frame_type != OS_FRAME_TYPE_EOD &&
593 aux->frame_type != OS_FRAME_TYPE_MARKER) {
596 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
600 if (aux->frame_type == OS_FRAME_TYPE_EOD &&
601 STp->first_frame_position < STp->eod_frame_ppos) {
602 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
603 STp->first_frame_position);
606 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
609 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
610 name, ntohl(aux->frame_seq_num), frame_seq_number);
614 if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
615 STps->eof = ST_FM_HIT;
617 i = ntohl(aux->filemark_cnt);
618 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
619 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
621 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
622 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
623 i, STp->first_frame_position - 1);
625 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
626 if (i >= STp->filemark_cnt)
627 STp->filemark_cnt = i+1;
630 if (aux->frame_type == OS_FRAME_TYPE_EOD) {
631 STps->eof = ST_EOD_1;
632 STp->frame_in_buffer = 1;
634 if (aux->frame_type == OS_FRAME_TYPE_DATA) {
635 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
636 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
637 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
638 STp->buffer->read_pointer = 0;
639 STp->frame_in_buffer = 1;
641 /* See what block size was used to write file */
642 if (STp->block_size != blk_sz && blk_sz > 0) {
644 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
645 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
646 STp->block_size<1024?STp->block_size:STp->block_size/1024,
647 STp->block_size<1024?'b':'k');
648 STp->block_size = blk_sz;
649 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
651 STps->eof = ST_NOEOF;
653 STp->frame_seq_number = ntohl(aux->frame_seq_num);
654 STp->logical_blk_num = ntohl(aux->logical_blk_num);
658 if (STp->read_error_frame == 0)
659 STp->read_error_frame = STp->first_frame_position - 1;
664 * Wait for the unit to become Ready
666 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
667 unsigned timeout, int initial_delay)
669 unsigned char cmd[MAX_COMMAND_SIZE];
670 struct osst_request * SRpnt;
671 unsigned long startwait = jiffies;
674 char * name = tape_name(STp);
676 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
679 if (initial_delay > 0)
680 msleep(jiffies_to_msecs(initial_delay));
682 memset(cmd, 0, MAX_COMMAND_SIZE);
683 cmd[0] = TEST_UNIT_READY;
685 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
687 if (!SRpnt) return (-EBUSY);
689 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
690 (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
691 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) ||
692 ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 &&
693 SRpnt->sense[13] == 0 ) )) {
696 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
697 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
703 memset(cmd, 0, MAX_COMMAND_SIZE);
704 cmd[0] = TEST_UNIT_READY;
706 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
712 if ( STp->buffer->syscall_result &&
713 osst_write_error_recovery(STp, aSRpnt, 0) ) {
715 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
716 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
717 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
718 SRpnt->sense[12], SRpnt->sense[13]);
723 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
729 * Wait for a tape to be inserted in the unit
731 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
733 unsigned char cmd[MAX_COMMAND_SIZE];
734 struct osst_request * SRpnt;
735 unsigned long startwait = jiffies;
738 char * name = tape_name(STp);
740 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
743 memset(cmd, 0, MAX_COMMAND_SIZE);
744 cmd[0] = TEST_UNIT_READY;
746 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
748 if (!SRpnt) return (-EBUSY);
750 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
751 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) {
754 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
755 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
761 memset(cmd, 0, MAX_COMMAND_SIZE);
762 cmd[0] = TEST_UNIT_READY;
764 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
770 if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 &&
771 SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) {
773 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
774 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
775 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
776 SRpnt->sense[12], SRpnt->sense[13]);
781 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
786 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame)
790 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
791 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
792 if (retval) return (retval);
793 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
794 return (osst_get_frame_position(STp, aSRpnt));
798 * Wait for write(s) to complete
800 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
802 unsigned char cmd[MAX_COMMAND_SIZE];
803 struct osst_request * SRpnt;
805 int delay = OSST_WAIT_WRITE_COMPLETE;
807 char * name = tape_name(STp);
809 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
812 memset(cmd, 0, MAX_COMMAND_SIZE);
813 cmd[0] = WRITE_FILEMARKS;
816 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
818 if (!SRpnt) return (-EBUSY);
819 if (STp->buffer->syscall_result) {
820 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) {
821 if (SRpnt->sense[13] == 8) {
822 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
825 result = osst_write_error_recovery(STp, aSRpnt, 0);
827 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
828 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
833 #define OSST_POLL_PER_SEC 10
834 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to)
836 unsigned long startwait = jiffies;
837 char * name = tape_name(STp);
839 char notyetprinted = 1;
841 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
842 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
844 while (time_before (jiffies, startwait + to*HZ))
847 result = osst_get_frame_position(STp, aSRpnt);
849 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
850 return 0; /* successful recovery leaves drive ready for frame */
851 if (result < 0) break;
852 if (STp->first_frame_position == curr &&
854 (signed)STp->last_frame_position > (signed)curr + minlast) ||
855 (minlast >= 0 && STp->cur_frames > minlast)
859 if (debugging || jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC)
861 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
862 name, curr, curr+minlast, STp->first_frame_position,
863 STp->last_frame_position, STp->cur_frames,
864 result, (jiffies-startwait)/HZ,
865 (((jiffies-startwait)%HZ)*10)/HZ);
870 if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted)
872 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
873 name, curr, curr+minlast, STp->first_frame_position,
874 STp->last_frame_position, STp->cur_frames, result);
878 msleep(1000 / OSST_POLL_PER_SEC);
881 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
882 name, curr, curr+minlast, STp->first_frame_position,
883 STp->last_frame_position, STp->cur_frames,
884 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
889 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
891 struct osst_request * SRpnt;
892 unsigned char cmd[MAX_COMMAND_SIZE];
893 unsigned long startwait = jiffies;
895 char * name = tape_name(STp);
899 char * olddata = STp->buffer->b_data;
900 int oldsize = STp->buffer->buffer_size;
902 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
904 memset(cmd, 0, MAX_COMMAND_SIZE);
905 cmd[0] = WRITE_FILEMARKS;
907 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
910 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
912 if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) {
914 /* some failure - not just not-ready */
915 retval = osst_write_error_recovery(STp, aSRpnt, 0);
918 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
920 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
921 memset(cmd, 0, MAX_COMMAND_SIZE);
922 cmd[0] = READ_POSITION;
924 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
927 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
928 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
931 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
933 /* TODO - figure out which error conditions can be handled */
934 if (STp->buffer->syscall_result)
936 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
937 (*aSRpnt)->sense[ 2] & 0x0f,
938 (*aSRpnt)->sense[12],
939 (*aSRpnt)->sense[13]);
945 * Read the next OnStream tape frame at the current location
947 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
949 unsigned char cmd[MAX_COMMAND_SIZE];
950 struct osst_request * SRpnt;
953 os_aux_t * aux = STp->buffer->aux;
954 char * name = tape_name(STp);
958 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
959 retval = osst_recover_wait_frame(STp, aSRpnt, 0);
961 memset(cmd, 0, MAX_COMMAND_SIZE);
968 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
970 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
971 STp->timeout, MAX_RETRIES, 1);
976 if ((STp->buffer)->syscall_result) {
978 if (STp->read_error_frame == 0) {
979 STp->read_error_frame = STp->first_frame_position;
981 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
986 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
988 SRpnt->sense[0], SRpnt->sense[1],
989 SRpnt->sense[2], SRpnt->sense[3],
990 SRpnt->sense[4], SRpnt->sense[5],
991 SRpnt->sense[6], SRpnt->sense[7]);
995 STp->first_frame_position++;
1000 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
1003 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
1004 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
1005 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
1006 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
1007 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
1008 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
1009 if (aux->frame_type==2)
1010 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
1011 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
1012 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
1018 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
1020 struct st_partstat * STps = &(STp->ps[STp->partition]);
1021 struct osst_request * SRpnt ;
1022 unsigned char cmd[MAX_COMMAND_SIZE];
1024 char * name = tape_name(STp);
1026 if (STps->rw != ST_READING) { /* Initialize read operation */
1027 if (STps->rw == ST_WRITING || STp->dirty) {
1028 STp->write_type = OS_WRITE_DATA;
1029 osst_flush_write_buffer(STp, aSRpnt);
1030 osst_flush_drive_buffer(STp, aSRpnt);
1032 STps->rw = ST_READING;
1033 STp->frame_in_buffer = 0;
1036 * Issue a read 0 command to get the OnStream drive
1037 * read frames into its buffer.
1039 memset(cmd, 0, MAX_COMMAND_SIZE);
1044 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
1046 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
1048 if ((retval = STp->buffer->syscall_result))
1049 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
1055 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt,
1056 int frame_seq_number, int quiet)
1058 struct st_partstat * STps = &(STp->ps[STp->partition]);
1059 char * name = tape_name(STp);
1067 * If we want just any frame (-1) and there is a frame in the buffer, return it
1069 if (frame_seq_number == -1 && STp->frame_in_buffer) {
1071 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1076 * Search and wait for the next logical tape frame
1080 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1081 name, frame_seq_number);
1082 if (STp->read_error_frame) {
1083 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1085 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1086 name, STp->read_error_frame);
1088 STp->read_error_frame = 0;
1095 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1096 name, frame_seq_number, cnt);
1098 if ( osst_initiate_read(STp, aSRpnt)
1099 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1102 position = osst_get_frame_position(STp, aSRpnt);
1103 if (position >= 0xbae && position < 0xbb8)
1105 else if (position > STp->eod_frame_ppos || ++bad == 10) {
1106 position = STp->read_error_frame - 1;
1114 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1117 osst_set_frame_position(STp, aSRpnt, position, 0);
1120 if (osst_verify_frame(STp, frame_seq_number, quiet))
1122 if (osst_verify_frame(STp, -1, quiet)) {
1123 x = ntohl(STp->buffer->aux->frame_seq_num);
1124 if (STp->fast_open) {
1126 "%s:W: Found logical frame %d instead of %d after fast open\n",
1127 name, x, frame_seq_number);
1129 STp->read_error_frame = 0;
1132 if (x > frame_seq_number) {
1134 /* positioning backwards did not bring us to the desired frame */
1135 position = STp->read_error_frame - 1;
1138 position = osst_get_frame_position(STp, aSRpnt)
1139 + frame_seq_number - x - 1;
1141 if (STp->first_frame_position >= 3000 && position < 3000)
1146 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1147 name, x, frame_seq_number,
1148 STp->first_frame_position - position);
1150 osst_set_frame_position(STp, aSRpnt, position, 0);
1156 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1158 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1160 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1163 STp->frame_in_buffer = 0;
1166 STp->recover_count++;
1167 STp->recover_erreg++;
1168 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1169 name, STp->read_error_frame);
1174 if (debugging || STps->eof)
1176 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1177 name, frame_seq_number, STp->frame_seq_number, STps->eof);
1180 STp->read_error_frame = 0;
1184 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num)
1186 struct st_partstat * STps = &(STp->ps[STp->partition]);
1187 char * name = tape_name(STp);
1189 int frame_seq_estimate, ppos_estimate, move;
1191 if (logical_blk_num < 0) logical_blk_num = 0;
1193 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1194 name, logical_blk_num, STp->logical_blk_num,
1195 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1196 STp->block_size<1024?'b':'k');
1198 /* Do we know where we are? */
1199 if (STps->drv_block >= 0) {
1200 move = logical_blk_num - STp->logical_blk_num;
1201 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1202 move /= (OS_DATA_SIZE / STp->block_size);
1203 frame_seq_estimate = STp->frame_seq_number + move;
1205 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1207 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1208 else ppos_estimate = frame_seq_estimate + 20;
1209 while (++retries < 10) {
1210 if (ppos_estimate > STp->eod_frame_ppos-2) {
1211 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1212 ppos_estimate = STp->eod_frame_ppos - 2;
1214 if (frame_seq_estimate < 0) {
1215 frame_seq_estimate = 0;
1218 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1219 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1220 /* we've located the estimated frame, now does it have our block? */
1221 if (logical_blk_num < STp->logical_blk_num ||
1222 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1223 if (STps->eof == ST_FM_HIT)
1224 move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1226 move = logical_blk_num - STp->logical_blk_num;
1227 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1228 move /= (OS_DATA_SIZE / STp->block_size);
1230 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1233 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1234 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1235 STp->logical_blk_num, logical_blk_num, move);
1237 frame_seq_estimate += move;
1238 ppos_estimate += move;
1241 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1242 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1243 STp->logical_blk_num = logical_blk_num;
1246 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1247 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1248 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1251 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1252 if (STps->eof == ST_FM_HIT) {
1254 STps->drv_block = 0;
1256 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1257 STp->logical_blk_num -
1258 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1261 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1265 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1267 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1269 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1270 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1271 STp->logical_blk_num, logical_blk_num);
1273 if (frame_seq_estimate != STp->frame_seq_number)
1274 ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1279 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1280 name, logical_blk_num, STp->logical_blk_num, retries);
1284 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1285 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1286 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1287 * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1289 #define OSST_FRAME_SHIFT 6
1290 #define OSST_SECTOR_SHIFT 9
1291 #define OSST_SECTOR_MASK 0x03F
1293 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt)
1297 char * name = tape_name(STp);
1300 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1301 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1302 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1303 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1304 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1305 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1307 /* do we know where we are inside a file? */
1308 if (STp->ps[STp->partition].drv_block >= 0) {
1309 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1310 STp->first_frame_position) << OSST_FRAME_SHIFT;
1311 if (STp->ps[STp->partition].rw == ST_WRITING)
1312 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1314 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1316 sector = osst_get_frame_position(STp, aSRpnt);
1318 sector <<= OSST_FRAME_SHIFT;
1323 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector)
1325 struct st_partstat * STps = &(STp->ps[STp->partition]);
1326 int frame = sector >> OSST_FRAME_SHIFT,
1327 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1330 char * name = tape_name(STp);
1332 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1333 name, sector, frame, offset);
1335 if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1337 if (frame <= STp->first_data_ppos) {
1338 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1339 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1341 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1342 if (r < 0) return r;
1344 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1345 if (r < 0) return r;
1347 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1350 STp->logical_blk_num += offset / STp->block_size;
1351 STp->buffer->read_pointer = offset;
1352 STp->buffer->buffer_bytes -= offset;
1354 STp->frame_seq_number++;
1355 STp->frame_in_buffer = 0;
1356 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1357 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1359 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1360 if (STps->eof == ST_FM_HIT) {
1362 STps->drv_block = 0;
1364 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1365 STp->logical_blk_num -
1366 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1369 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1372 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1373 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1374 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1380 * Read back the drive's internal buffer contents, as a part
1381 * of the write error recovery mechanism for old OnStream
1382 * firmware revisions.
1383 * Precondition for this function to work: all frames in the
1384 * drive's buffer must be of one type (DATA, MARK or EOD)!
1386 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
1387 unsigned int frame, unsigned int skip, int pending)
1389 struct osst_request * SRpnt = * aSRpnt;
1390 unsigned char * buffer, * p;
1391 unsigned char cmd[MAX_COMMAND_SIZE];
1392 int flag, new_frame, i;
1393 int nframes = STp->cur_frames;
1394 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1395 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1396 - (nframes + pending - 1);
1397 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1398 - (nframes + pending - 1) * blks_per_frame;
1399 char * name = tape_name(STp);
1400 unsigned long startwait = jiffies;
1402 int dbg = debugging;
1405 if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
1408 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1409 name, nframes, pending?" and one that was pending":"");
1411 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1413 if (pending && debugging)
1414 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1415 name, frame_seq_number + nframes,
1416 logical_blk_num + nframes * blks_per_frame,
1417 p[0], p[1], p[2], p[3]);
1419 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1421 memset(cmd, 0, MAX_COMMAND_SIZE);
1422 cmd[0] = 0x3C; /* Buffer Read */
1423 cmd[1] = 6; /* Retrieve Faulty Block */
1424 cmd[7] = 32768 >> 8;
1425 cmd[8] = 32768 & 0xff;
1427 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1428 STp->timeout, MAX_RETRIES, 1);
1430 if ((STp->buffer)->syscall_result || !SRpnt) {
1431 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1436 osst_copy_from_buffer(STp->buffer, p);
1439 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1440 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1444 osst_get_frame_position(STp, aSRpnt);
1447 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1449 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1450 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1452 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1455 if (STp->write_type == OS_WRITE_HEADER) {
1457 p += skip * OS_DATA_SIZE;
1459 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1464 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1465 name, new_frame+i, frame_seq_number+i);
1467 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1468 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1469 osst_get_frame_position(STp, aSRpnt);
1472 if (new_frame > frame + 1000) {
1473 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1477 if ( i >= nframes + pending ) break;
1480 osst_copy_to_buffer(STp->buffer, p);
1482 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1484 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1485 logical_blk_num + i*blks_per_frame,
1486 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1487 memset(cmd, 0, MAX_COMMAND_SIZE);
1495 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1496 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1497 p[0], p[1], p[2], p[3]);
1499 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1500 STp->timeout, MAX_RETRIES, 1);
1502 if (STp->buffer->syscall_result)
1505 p += OS_DATA_SIZE; i++;
1507 /* if we just sent the last frame, wait till all successfully written */
1508 if ( i == nframes + pending ) {
1510 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1512 memset(cmd, 0, MAX_COMMAND_SIZE);
1513 cmd[0] = WRITE_FILEMARKS;
1515 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1516 STp->timeout, MAX_RETRIES, 1);
1519 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1520 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1524 flag = STp->buffer->syscall_result;
1525 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1527 memset(cmd, 0, MAX_COMMAND_SIZE);
1528 cmd[0] = TEST_UNIT_READY;
1530 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1533 if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
1534 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
1535 /* in the process of becoming ready */
1539 if (STp->buffer->syscall_result)
1545 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1551 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1552 SRpnt->sense[12] == 0 &&
1553 SRpnt->sense[13] == 2) {
1554 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1556 return (-EIO); /* hit end of tape = fail */
1558 i = ((SRpnt->sense[3] << 24) |
1559 (SRpnt->sense[4] << 16) |
1560 (SRpnt->sense[5] << 8) |
1561 SRpnt->sense[6] ) - new_frame;
1562 p = &buffer[i * OS_DATA_SIZE];
1564 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1566 osst_get_frame_position(STp, aSRpnt);
1568 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1569 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1574 /* error recovery did not successfully complete */
1575 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1576 STp->write_type == OS_WRITE_HEADER?"header":"body");
1579 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1584 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
1585 unsigned int frame, unsigned int skip, int pending)
1587 unsigned char cmd[MAX_COMMAND_SIZE];
1588 struct osst_request * SRpnt;
1589 char * name = tape_name(STp);
1591 int attempts = 1000 / skip;
1593 unsigned long startwait = jiffies;
1595 int dbg = debugging;
1598 while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1603 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1605 expected = frame+skip+STp->cur_frames+pending;
1607 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1608 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1610 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1613 schedule_timeout_interruptible(msecs_to_jiffies(100));
1615 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1617 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1618 name, STp->first_frame_position,
1619 STp->last_frame_position, STp->cur_frames);
1621 frame = STp->last_frame_position;
1625 if (pending && STp->cur_frames < 50) {
1627 memset(cmd, 0, MAX_COMMAND_SIZE);
1632 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1633 name, STp->frame_seq_number-1, STp->first_frame_position);
1635 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1636 STp->timeout, MAX_RETRIES, 1);
1639 if (STp->buffer->syscall_result) { /* additional write error */
1640 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1641 SRpnt->sense[12] == 0 &&
1642 SRpnt->sense[13] == 2) {
1644 "%s:E: Volume overflow in write error recovery\n",
1646 break; /* hit end of tape = fail */
1655 if (STp->cur_frames == 0) {
1658 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1660 if (STp->first_frame_position != expected) {
1661 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1662 name, STp->first_frame_position, expected);
1669 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1670 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1674 schedule_timeout_interruptible(msecs_to_jiffies(100));
1676 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1684 * Error recovery algorithm for the OnStream tape.
1687 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending)
1689 struct osst_request * SRpnt = * aSRpnt;
1690 struct st_partstat * STps = & STp->ps[STp->partition];
1691 char * name = tape_name(STp);
1694 unsigned int frame, skip;
1696 rw_state = STps->rw;
1698 if ((SRpnt->sense[ 2] & 0x0f) != 3
1699 || SRpnt->sense[12] != 12
1700 || SRpnt->sense[13] != 0) {
1702 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1703 SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]);
1707 frame = (SRpnt->sense[3] << 24) |
1708 (SRpnt->sense[4] << 16) |
1709 (SRpnt->sense[5] << 8) |
1711 skip = SRpnt->sense[9];
1714 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1716 osst_get_frame_position(STp, aSRpnt);
1718 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1719 name, STp->first_frame_position, STp->last_frame_position);
1721 switch (STp->write_type) {
1724 case OS_WRITE_NEW_MARK:
1726 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1727 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1728 if (STp->os_fw_rev >= 10600)
1729 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1731 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1732 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1734 retval?"" :"Don't worry, ",
1735 retval?" not ":" ");
1737 case OS_WRITE_LAST_MARK:
1738 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1739 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1742 case OS_WRITE_HEADER:
1743 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1744 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1747 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1748 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1750 osst_get_frame_position(STp, aSRpnt);
1752 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1753 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1754 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1757 STp->recover_count++;
1758 STp->recover_erreg++;
1762 STps->rw = rw_state;
1766 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt,
1767 int mt_op, int mt_count)
1769 char * name = tape_name(STp);
1771 int last_mark_ppos = -1;
1774 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1776 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1778 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1782 if (STp->linux_media_version >= 4) {
1784 * direct lookup in header filemark list
1786 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1787 if (STp->header_ok &&
1788 STp->header_cache != NULL &&
1789 (cnt - mt_count) >= 0 &&
1790 (cnt - mt_count) < OS_FM_TAB_MAX &&
1791 (cnt - mt_count) < STp->filemark_cnt &&
1792 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1794 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1796 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1797 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1798 STp->header_cache == NULL?"lack of header cache":"count out of range");
1800 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1802 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1803 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1804 STp->buffer->aux->last_mark_ppos))?"match":"error",
1805 mt_count, last_mark_ppos);
1807 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1808 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1809 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1812 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1816 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1817 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1818 name, last_mark_ppos);
1824 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1828 while (cnt != mt_count) {
1829 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1830 if (last_mark_ppos == -1)
1833 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1835 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1837 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1839 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1843 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1844 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1845 name, last_mark_ppos);
1850 if (mt_op == MTBSFM) {
1851 STp->frame_seq_number++;
1852 STp->frame_in_buffer = 0;
1853 STp->buffer->buffer_bytes = 0;
1854 STp->buffer->read_pointer = 0;
1855 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1861 * ADRL 1.1 compatible "slow" space filemarks fwd version
1863 * Just scans for the filemark sequentially.
1865 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt,
1866 int mt_op, int mt_count)
1870 char * name = tape_name(STp);
1872 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1874 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1876 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1881 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1883 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1887 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1889 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1891 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1893 if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1895 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1896 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1898 STp->eod_frame_ppos = STp->first_frame_position-1;
1902 if (cnt == mt_count)
1904 STp->frame_in_buffer = 0;
1906 if (mt_op == MTFSF) {
1907 STp->frame_seq_number++;
1908 STp->frame_in_buffer = 0;
1909 STp->buffer->buffer_bytes = 0;
1910 STp->buffer->read_pointer = 0;
1911 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1917 * Fast linux specific version of OnStream FSF
1919 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt,
1920 int mt_op, int mt_count)
1922 char * name = tape_name(STp);
1924 next_mark_ppos = -1;
1927 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
1929 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1931 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1936 if (STp->linux_media_version >= 4) {
1938 * direct lookup in header filemark list
1940 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
1941 if (STp->header_ok &&
1942 STp->header_cache != NULL &&
1943 (cnt + mt_count) < OS_FM_TAB_MAX &&
1944 (cnt + mt_count) < STp->filemark_cnt &&
1945 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1946 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
1948 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
1950 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
1951 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1952 STp->header_cache == NULL?"lack of header cache":"count out of range");
1954 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1956 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1957 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
1958 STp->buffer->aux->last_mark_ppos))?"match":"error",
1959 mt_count, next_mark_ppos);
1961 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
1963 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1965 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1967 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
1968 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1970 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
1975 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1976 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1977 name, next_mark_ppos);
1980 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
1981 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
1982 name, cnt+mt_count, next_mark_ppos,
1983 ntohl(STp->buffer->aux->filemark_cnt));
1989 * Find nearest (usually previous) marker, then jump from marker to marker
1992 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1994 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1996 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
2000 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
2001 if (STp->first_mark_ppos == -1) {
2003 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2005 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2007 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
2008 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2011 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2016 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2017 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
2018 name, STp->first_mark_ppos);
2022 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
2028 while (cnt != mt_count) {
2029 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
2030 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
2032 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2034 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
2037 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
2039 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2041 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2043 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2048 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2049 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2050 name, next_mark_ppos);
2055 if (mt_op == MTFSF) {
2056 STp->frame_seq_number++;
2057 STp->frame_in_buffer = 0;
2058 STp->buffer->buffer_bytes = 0;
2059 STp->buffer->read_pointer = 0;
2060 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2066 * In debug mode, we want to see as many errors as possible
2067 * to test the error recovery mechanism.
2070 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries)
2072 unsigned char cmd[MAX_COMMAND_SIZE];
2073 struct osst_request * SRpnt = * aSRpnt;
2074 char * name = tape_name(STp);
2076 memset(cmd, 0, MAX_COMMAND_SIZE);
2077 cmd[0] = MODE_SELECT;
2079 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2081 (STp->buffer)->b_data[0] = cmd[4] - 1;
2082 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
2083 (STp->buffer)->b_data[2] = 0; /* Reserved */
2084 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
2085 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2086 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2087 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2088 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2091 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2093 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2096 if ((STp->buffer)->syscall_result)
2097 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2102 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt)
2105 int this_mark_ppos = STp->first_frame_position;
2106 int this_mark_lbn = STp->logical_blk_num;
2108 char * name = tape_name(STp);
2111 if (STp->raw) return 0;
2113 STp->write_type = OS_WRITE_NEW_MARK;
2115 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2116 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2119 result = osst_flush_write_buffer(STp, aSRpnt);
2120 result |= osst_flush_drive_buffer(STp, aSRpnt);
2121 STp->last_mark_ppos = this_mark_ppos;
2122 STp->last_mark_lbn = this_mark_lbn;
2123 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2124 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2125 if (STp->filemark_cnt++ == 0)
2126 STp->first_mark_ppos = this_mark_ppos;
2130 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt)
2134 char * name = tape_name(STp);
2137 if (STp->raw) return 0;
2139 STp->write_type = OS_WRITE_EOD;
2140 STp->eod_frame_ppos = STp->first_frame_position;
2142 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2143 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2147 result = osst_flush_write_buffer(STp, aSRpnt);
2148 result |= osst_flush_drive_buffer(STp, aSRpnt);
2149 STp->eod_frame_lfa = --(STp->frame_seq_number);
2153 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2155 char * name = tape_name(STp);
2158 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2160 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2161 osst_set_frame_position(STp, aSRpnt, where, 0);
2162 STp->write_type = OS_WRITE_FILLER;
2164 memcpy(STp->buffer->b_data, "Filler", 6);
2165 STp->buffer->buffer_bytes = 6;
2167 if (osst_flush_write_buffer(STp, aSRpnt)) {
2168 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2173 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2175 return osst_flush_drive_buffer(STp, aSRpnt);
2178 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2180 char * name = tape_name(STp);
2184 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2186 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2187 osst_set_frame_position(STp, aSRpnt, where, 0);
2188 STp->write_type = OS_WRITE_HEADER;
2190 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2191 STp->buffer->buffer_bytes = sizeof(os_header_t);
2193 if (osst_flush_write_buffer(STp, aSRpnt)) {
2194 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2198 result = osst_flush_drive_buffer(STp, aSRpnt);
2200 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2205 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod)
2207 os_header_t * header;
2209 char * name = tape_name(STp);
2212 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2214 if (STp->raw) return 0;
2216 if (STp->header_cache == NULL) {
2217 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2218 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2221 memset(STp->header_cache, 0, sizeof(os_header_t));
2223 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2226 if (STp->header_ok) STp->update_frame_cntr++;
2227 else STp->update_frame_cntr = 0;
2229 header = STp->header_cache;
2230 strcpy(header->ident_str, "ADR_SEQ");
2231 header->major_rev = 1;
2232 header->minor_rev = 4;
2233 header->ext_trk_tb_off = htons(17192);
2234 header->pt_par_num = 1;
2235 header->partition[0].partition_num = OS_DATA_PARTITION;
2236 header->partition[0].par_desc_ver = OS_PARTITION_VERSION;
2237 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2238 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2239 header->partition[0].last_frame_ppos = htonl(STp->capacity);
2240 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2241 header->cfg_col_width = htonl(20);
2242 header->dat_col_width = htonl(1500);
2243 header->qfa_col_width = htonl(0);
2244 header->ext_track_tb.nr_stream_part = 1;
2245 header->ext_track_tb.et_ent_sz = 32;
2246 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2247 header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2248 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2249 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2250 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa);
2251 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
2252 header->dat_fm_tab.fm_part_num = 0;
2253 header->dat_fm_tab.fm_tab_ent_sz = 4;
2254 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2255 STp->filemark_cnt:OS_FM_TAB_MAX);
2257 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2258 if (STp->update_frame_cntr == 0)
2259 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2260 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2264 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2266 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2269 printk(KERN_ERR "%s:E: Write header failed\n", name);
2271 memcpy(STp->application_sig, "LIN4", 4);
2272 STp->linux_media = 1;
2273 STp->linux_media_version = 4;
2279 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt)
2281 if (STp->header_cache != NULL)
2282 memset(STp->header_cache, 0, sizeof(os_header_t));
2284 STp->logical_blk_num = STp->frame_seq_number = 0;
2285 STp->frame_in_buffer = 0;
2286 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2287 STp->filemark_cnt = 0;
2288 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2289 return osst_write_header(STp, aSRpnt, 1);
2292 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos)
2294 char * name = tape_name(STp);
2295 os_header_t * header;
2298 int linux_media_version,
2304 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2305 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2306 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2307 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2308 if (osst_initiate_read (STp, aSRpnt)) {
2309 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2313 if (osst_read_frame(STp, aSRpnt, 180)) {
2315 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2319 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2320 aux = STp->buffer->aux;
2321 if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2323 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2327 if (ntohl(aux->frame_seq_num) != 0 ||
2328 ntohl(aux->logical_blk_num) != 0 ||
2329 aux->partition.partition_num != OS_CONFIG_PARTITION ||
2330 ntohl(aux->partition.first_frame_ppos) != 0 ||
2331 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2333 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2334 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2335 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2336 ntohl(aux->partition.last_frame_ppos));
2340 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2341 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2342 strlcpy(id_string, header->ident_str, 8);
2344 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2348 update_frame_cntr = ntohl(aux->update_frame_cntr);
2349 if (update_frame_cntr < STp->update_frame_cntr) {
2351 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2352 name, ppos, update_frame_cntr, STp->update_frame_cntr);
2356 if (header->major_rev != 1 || header->minor_rev != 4 ) {
2358 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2359 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2360 header->minor_rev > 4 )? "Invalid" : "Warning:",
2361 header->major_rev, header->minor_rev);
2363 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2367 if (header->pt_par_num != 1)
2368 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2369 name, header->pt_par_num);
2371 memcpy(id_string, aux->application_sig, 4);
2373 if (memcmp(id_string, "LIN", 3) == 0) {
2374 STp->linux_media = 1;
2375 linux_media_version = id_string[3] - '0';
2376 if (linux_media_version != 4)
2377 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2378 name, linux_media_version);
2380 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2383 if (linux_media_version < STp->linux_media_version) {
2385 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2386 name, ppos, linux_media_version);
2390 if (linux_media_version > STp->linux_media_version) {
2392 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2393 name, ppos, linux_media_version);
2395 memcpy(STp->application_sig, id_string, 5);
2396 STp->linux_media_version = linux_media_version;
2397 STp->update_frame_cntr = -1;
2399 if (update_frame_cntr > STp->update_frame_cntr) {
2401 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2402 name, ppos, update_frame_cntr);
2404 if (STp->header_cache == NULL) {
2405 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2406 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2410 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2413 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2414 header = STp->header_cache; /* further accesses from cached (full) copy */
2416 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2417 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2418 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2419 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2420 STp->filemark_cnt = ntohl(aux->filemark_cnt);
2421 STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2422 STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2423 STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2424 STp->update_frame_cntr = update_frame_cntr;
2426 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2427 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2428 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2429 STp->first_data_ppos,
2430 ntohl(header->partition[0].last_frame_ppos),
2431 ntohl(header->partition[0].eod_frame_ppos));
2432 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2433 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2435 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2437 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2439 memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2440 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2441 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2443 if (header->minor_rev == 4 &&
2444 (header->ext_trk_tb_off != htons(17192) ||
2445 header->partition[0].partition_num != OS_DATA_PARTITION ||
2446 header->partition[0].par_desc_ver != OS_PARTITION_VERSION ||
2447 header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2448 header->cfg_col_width != htonl(20) ||
2449 header->dat_col_width != htonl(1500) ||
2450 header->qfa_col_width != htonl(0) ||
2451 header->ext_track_tb.nr_stream_part != 1 ||
2452 header->ext_track_tb.et_ent_sz != 32 ||
2453 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION ||
2454 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2455 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2456 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2457 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) ||
2458 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION ||
2459 header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2460 header->dat_fm_tab.fm_tab_ent_cnt !=
2461 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2462 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2469 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt)
2474 char * name = tape_name(STp);
2476 position = osst_get_frame_position(STp, aSRpnt);
2479 STp->header_ok = STp->linux_media = 1;
2480 STp->linux_media_version = 0;
2483 STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2484 STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2485 STp->eod_frame_ppos = STp->first_data_ppos = -1;
2486 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2488 printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2491 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2492 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2494 first = position==10?0xbae: 5;
2495 last = position==10?0xbb3:10;
2497 for (ppos = first; ppos < last; ppos++)
2498 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2501 first = position==10? 5:0xbae;
2502 last = position==10?10:0xbb3;
2504 for (ppos = first; ppos < last; ppos++)
2505 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2509 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2510 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2511 osst_set_frame_position(STp, aSRpnt, 10, 0);
2514 if (position <= STp->first_data_ppos) {
2515 position = STp->first_data_ppos;
2516 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2518 osst_set_frame_position(STp, aSRpnt, position, 0);
2524 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt)
2526 int frame_position = STp->first_frame_position;
2527 int frame_seq_numbr = STp->frame_seq_number;
2528 int logical_blk_num = STp->logical_blk_num;
2529 int halfway_frame = STp->frame_in_buffer;
2530 int read_pointer = STp->buffer->read_pointer;
2531 int prev_mark_ppos = -1;
2532 int actual_mark_ppos, i, n;
2534 char * name = tape_name(STp);
2536 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2538 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2539 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2541 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2545 if (STp->linux_media_version >= 4) {
2546 for (i=0; i<STp->filemark_cnt; i++)
2547 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2550 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2551 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2552 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2553 if (frame_position != STp->first_frame_position ||
2554 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2555 prev_mark_ppos != actual_mark_ppos ) {
2557 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2558 STp->first_frame_position, frame_position,
2559 STp->frame_seq_number + (halfway_frame?0:1),
2560 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2564 if (halfway_frame) {
2565 /* prepare buffer for append and rewrite on top of original */
2566 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2567 STp->buffer->buffer_bytes = read_pointer;
2568 STp->ps[STp->partition].rw = ST_WRITING;
2571 STp->frame_in_buffer = halfway_frame;
2572 STp->frame_seq_number = frame_seq_numbr;
2573 STp->logical_blk_num = logical_blk_num;
2577 /* Acc. to OnStream, the vers. numbering is the following:
2578 * X.XX for released versions (X=digit),
2579 * XXXY for unreleased versions (Y=letter)
2580 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2581 * This fn makes monoton numbers out of this scheme ...
2583 static unsigned int osst_parse_firmware_rev (const char * str)
2585 if (str[1] == '.') {
2586 return (str[0]-'0')*10000
2590 return (str[0]-'0')*10000
2592 +(str[2]-'0')*100 - 100
2598 * Configure the OnStream SCII tape drive for default operation
2600 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
2602 unsigned char cmd[MAX_COMMAND_SIZE];
2603 char * name = tape_name(STp);
2604 struct osst_request * SRpnt = * aSRpnt;
2605 osst_mode_parameter_header_t * header;
2606 osst_block_size_page_t * bs;
2607 osst_capabilities_page_t * cp;
2608 osst_tape_paramtr_page_t * prm;
2609 int drive_buffer_size;
2611 if (STp->ready != ST_READY) {
2613 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2618 if (STp->os_fw_rev < 10600) {
2619 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2620 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2624 * Configure 32.5KB (data+aux) frame size.
2625 * Get the current frame size from the block size mode page
2627 memset(cmd, 0, MAX_COMMAND_SIZE);
2628 cmd[0] = MODE_SENSE;
2630 cmd[2] = BLOCK_SIZE_PAGE;
2631 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2633 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2634 if (SRpnt == NULL) {
2636 printk(OSST_DEB_MSG "osst :D: Busy\n");
2641 if ((STp->buffer)->syscall_result != 0) {
2642 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2646 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2647 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2650 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2651 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No");
2652 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2653 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2657 * Configure default auto columns mode, 32.5KB transfer mode
2665 memset(cmd, 0, MAX_COMMAND_SIZE);
2666 cmd[0] = MODE_SELECT;
2668 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2670 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2672 if ((STp->buffer)->syscall_result != 0) {
2673 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2678 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2680 * In debug mode, we want to see as many errors as possible
2681 * to test the error recovery mechanism.
2683 osst_set_retries(STp, aSRpnt, 0);
2688 * Set vendor name to 'LIN4' for "Linux support version 4".
2691 memset(cmd, 0, MAX_COMMAND_SIZE);
2692 cmd[0] = MODE_SELECT;
2694 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2696 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2697 header->medium_type = 0; /* Medium Type - ignoring */
2698 header->dsp = 0; /* Reserved */
2699 header->bdl = 0; /* Block Descriptor Length */
2701 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2702 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2703 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2704 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2705 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2706 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2707 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2708 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2710 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2713 if ((STp->buffer)->syscall_result != 0) {
2714 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2715 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2719 memset(cmd, 0, MAX_COMMAND_SIZE);
2720 cmd[0] = MODE_SENSE;
2722 cmd[2] = CAPABILITIES_PAGE;
2723 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2725 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2728 if ((STp->buffer)->syscall_result != 0) {
2729 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2733 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2734 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2735 sizeof(osst_mode_parameter_header_t) + header->bdl);
2737 drive_buffer_size = ntohs(cp->buffer_size) / 2;
2739 memset(cmd, 0, MAX_COMMAND_SIZE);
2740 cmd[0] = MODE_SENSE;
2742 cmd[2] = TAPE_PARAMTR_PAGE;
2743 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2745 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2748 if ((STp->buffer)->syscall_result != 0) {
2749 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2753 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2754 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2755 sizeof(osst_mode_parameter_header_t) + header->bdl);
2757 STp->density = prm->density;
2758 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2760 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2761 name, STp->density, STp->capacity / 32, drive_buffer_size);
2769 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2770 it messes up the block number). */
2771 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward)
2774 char * name = tape_name(STp);
2778 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2779 name, forward ? "forward" : "backward");
2783 /* assumes that the filemark is already read by the drive, so this is low cost */
2784 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2787 /* assumes this is only called if we just read the filemark! */
2788 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2791 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2792 name, forward ? "forward" : "backward");
2798 /* Get the tape position. */
2800 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
2802 unsigned char scmd[MAX_COMMAND_SIZE];
2803 struct osst_request * SRpnt;
2805 char * name = tape_name(STp);
2807 /* KG: We want to be able to use it for checking Write Buffer availability
2808 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2810 char * olddata = STp->buffer->b_data;
2811 int oldsize = STp->buffer->buffer_size;
2813 if (STp->ready != ST_READY) return (-EIO);
2815 memset (scmd, 0, MAX_COMMAND_SIZE);
2816 scmd[0] = READ_POSITION;
2818 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2819 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2820 STp->timeout, MAX_RETRIES, 1);
2822 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2827 if (STp->buffer->syscall_result)
2828 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */
2830 if (result == -EINVAL)
2831 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2833 if (result == -EIO) { /* re-read position - this needs to preserve media errors */
2834 unsigned char mysense[16];
2835 memcpy (mysense, SRpnt->sense, 16);
2836 memset (scmd, 0, MAX_COMMAND_SIZE);
2837 scmd[0] = READ_POSITION;
2838 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2839 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2840 STp->timeout, MAX_RETRIES, 1);
2842 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2843 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2844 SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]);
2846 if (!STp->buffer->syscall_result)
2847 memcpy (SRpnt->sense, mysense, 16);
2849 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2851 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2852 + ((STp->buffer)->b_data[5] << 16)
2853 + ((STp->buffer)->b_data[6] << 8)
2854 + (STp->buffer)->b_data[7];
2855 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2856 + ((STp->buffer)->b_data[ 9] << 16)
2857 + ((STp->buffer)->b_data[10] << 8)
2858 + (STp->buffer)->b_data[11];
2859 STp->cur_frames = (STp->buffer)->b_data[15];
2862 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2863 STp->first_frame_position, STp->last_frame_position,
2864 ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2865 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2869 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2871 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2872 STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2874 STp->first_frame_position = STp->last_frame_position;
2877 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2879 return (result == 0 ? STp->first_frame_position : result);
2883 /* Set the tape block */
2884 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip)
2886 unsigned char scmd[MAX_COMMAND_SIZE];
2887 struct osst_request * SRpnt;
2888 struct st_partstat * STps;
2890 int pp = (ppos == 3000 && !skip)? 0 : ppos;
2891 char * name = tape_name(STp);
2893 if (STp->ready != ST_READY) return (-EIO);
2895 STps = &(STp->ps[STp->partition]);
2897 if (ppos < 0 || ppos > STp->capacity) {
2898 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2899 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2906 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2908 memset (scmd, 0, MAX_COMMAND_SIZE);
2911 scmd[3] = (pp >> 24);
2912 scmd[4] = (pp >> 16);
2913 scmd[5] = (pp >> 8);
2918 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
2924 if ((STp->buffer)->syscall_result != 0) {
2926 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
2927 name, STp->first_frame_position, pp);
2932 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
2933 } while ((pp != ppos) && (pp = ppos));
2934 STp->first_frame_position = STp->last_frame_position = ppos;
2935 STps->eof = ST_NOEOF;
2938 STp->frame_in_buffer = 0;
2942 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT)
2944 struct st_partstat * STps = &(STp->ps[STp->partition]);
2947 if (STp->write_type != OS_WRITE_NEW_MARK) {
2948 /* true unless the user wrote the filemark for us */
2949 result = osst_flush_drive_buffer(STp, aSRpnt);
2950 if (result < 0) goto out;
2951 result = osst_write_filemark(STp, aSRpnt);
2952 if (result < 0) goto out;
2954 if (STps->drv_file >= 0)
2956 STps->drv_block = 0;
2958 result = osst_write_eod(STp, aSRpnt);
2959 osst_write_header(STp, aSRpnt, leave_at_EOT);
2966 /* osst versions of st functions - augmented and stripped to suit OnStream only */
2968 /* Flush the write buffer (never need to write if variable blocksize). */
2969 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt)
2971 int offset, transfer, blks = 0;
2973 unsigned char cmd[MAX_COMMAND_SIZE];
2974 struct osst_request * SRpnt = *aSRpnt;
2975 struct st_partstat * STps;
2976 char * name = tape_name(STp);
2978 if ((STp->buffer)->writing) {
2979 if (SRpnt == (STp->buffer)->last_SRpnt)
2981 { printk(OSST_DEB_MSG
2982 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name);
2984 *aSRpnt = SRpnt = NULL;
2988 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name);
2990 osst_write_behind_check(STp);
2991 if ((STp->buffer)->syscall_result) {
2994 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
2995 name, (STp->buffer)->midlevel_result);
2997 if ((STp->buffer)->midlevel_result == INT_MAX)
3004 if (STp->dirty == 1) {
3007 STps = &(STp->ps[STp->partition]);
3008 STps->rw = ST_WRITING;
3009 offset = STp->buffer->buffer_bytes;
3010 blks = (offset + STp->block_size - 1) / STp->block_size;
3011 transfer = OS_FRAME_SIZE;
3013 if (offset < OS_DATA_SIZE)
3014 osst_zero_buffer_tail(STp->buffer);
3017 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
3018 result = osst_recover_wait_frame(STp, aSRpnt, 1);
3020 memset(cmd, 0, MAX_COMMAND_SIZE);
3025 switch (STp->write_type) {
3029 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
3030 name, blks, STp->frame_seq_number,
3031 STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3033 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3034 STp->logical_blk_num - blks, STp->block_size, blks);
3037 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
3038 STp->logical_blk_num, 0, 0);
3040 case OS_WRITE_NEW_MARK:
3041 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
3042 STp->logical_blk_num++, 0, blks=1);
3044 case OS_WRITE_HEADER:
3045 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
3047 default: /* probably FILLER */
3048 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
3052 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
3053 name, offset, transfer, blks);
3056 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3057 STp->timeout, MAX_RETRIES, 1);
3062 if ((STp->buffer)->syscall_result != 0) {
3065 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3066 name, SRpnt->sense[0], SRpnt->sense[2],
3067 SRpnt->sense[12], SRpnt->sense[13]);
3069 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3070 (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3071 (SRpnt->sense[2] & 0x0f) == NO_SENSE) {
3073 (STp->buffer)->buffer_bytes = 0;
3077 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3078 printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3082 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
3085 STp->first_frame_position++;
3087 (STp->buffer)->buffer_bytes = 0;
3091 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3097 /* Flush the tape buffer. The tape will be positioned correctly unless
3098 seek_next is true. */
3099 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next)
3101 struct st_partstat * STps;
3102 int backspace = 0, result = 0;
3104 char * name = tape_name(STp);
3108 * If there was a bus reset, block further access
3111 if( STp->pos_unknown)
3114 if (STp->ready != ST_READY)
3117 STps = &(STp->ps[STp->partition]);
3118 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
3119 STp->write_type = OS_WRITE_DATA;
3120 return osst_flush_write_buffer(STp, aSRpnt);
3122 if (STp->block_size == 0)
3126 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3129 if (!STp->can_bsr) {
3130 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3131 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3132 (STp->buffer)->buffer_bytes = 0;
3133 (STp->buffer)->read_pointer = 0;
3134 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3138 if (STps->eof == ST_FM_HIT) {
3139 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3141 STps->eof = ST_NOEOF;
3143 if (STps->drv_file >= 0)
3145 STps->drv_block = 0;
3148 if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3149 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3151 else if (STps->eof == ST_FM_HIT) {
3152 if (STps->drv_file >= 0)
3154 STps->drv_block = 0;
3155 STps->eof = ST_NOEOF;
3161 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous)
3163 unsigned char cmd[MAX_COMMAND_SIZE];
3164 struct osst_request * SRpnt;
3167 char * name = tape_name(STp);
3170 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3172 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3174 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3177 /* error recovery may have bumped us past the header partition */
3178 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3180 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3182 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3187 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3188 if (osst_recover_wait_frame(STp, aSRpnt, 1))
3191 // osst_build_stats(STp, &SRpnt);
3193 STp->ps[STp->partition].rw = ST_WRITING;
3194 STp->write_type = OS_WRITE_DATA;
3196 memset(cmd, 0, MAX_COMMAND_SIZE);
3199 cmd[4] = 1; /* one frame at a time... */
3200 blks = STp->buffer->buffer_bytes / STp->block_size;
3203 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3204 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3206 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3207 STp->logical_blk_num - blks, STp->block_size, blks);
3211 STp->write_pending = 1;
3213 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3214 MAX_RETRIES, synchronous);
3220 if (STp->buffer->syscall_result != 0) {
3223 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3225 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3226 (SRpnt->sense[2] & 0x40)) {
3227 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW)
3231 if (osst_write_error_recovery(STp, aSRpnt, 1))
3236 STp->first_frame_position++;
3244 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */
3245 static int do_door_lock(struct osst_tape * STp, int do_lock)
3249 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
3251 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3253 retval = scsi_ioctl(STp->device, cmd, NULL);
3255 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3258 STp->door_locked = ST_LOCK_FAILS;
3263 /* Set the internal state after reset */
3264 static void reset_state(struct osst_tape *STp)
3267 struct st_partstat *STps;
3269 STp->pos_unknown = 0;
3270 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3271 STps = &(STp->ps[i]);
3273 STps->eof = ST_NOEOF;
3275 STps->last_block_valid = 0;
3276 STps->drv_block = -1;
3277 STps->drv_file = -1;
3282 /* Entry points to osst */
3285 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3287 ssize_t total, retval = 0;
3288 ssize_t i, do_count, blks, transfer;
3289 int write_threshold;
3290 int doing_write = 0;
3291 const char __user * b_point;
3292 struct osst_request * SRpnt = NULL;
3293 struct st_modedef * STm;
3294 struct st_partstat * STps;
3295 struct osst_tape * STp = filp->private_data;
3296 char * name = tape_name(STp);
3299 if (down_interruptible(&STp->lock))
3300 return (-ERESTARTSYS);
3303 * If we are in the middle of error recovery, don't let anyone
3304 * else try and use this device. Also, if error recovery fails, it
3305 * may try and take the device offline, in which case all further
3306 * access to the device is prohibited.
3308 if( !scsi_block_when_processing_errors(STp->device) ) {
3313 if (STp->ready != ST_READY) {
3314 if (STp->ready == ST_NO_TAPE)
3315 retval = (-ENOMEDIUM);
3320 STm = &(STp->modes[STp->current_mode]);
3321 if (!STm->defined) {
3329 * If there was a bus reset, block further access
3332 if (STp->pos_unknown) {
3339 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3345 if (STp->write_prot) {
3350 /* Write must be integral number of blocks */
3351 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3352 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3353 name, count, STp->block_size<1024?
3354 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3359 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3360 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3361 name, STp->first_frame_position);
3366 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3367 STp->door_locked = ST_LOCKED_AUTO;
3369 STps = &(STp->ps[STp->partition]);
3371 if (STps->rw == ST_READING) {
3373 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3374 STps->drv_file, STps->drv_block);
3376 retval = osst_flush_buffer(STp, &SRpnt, 0);
3381 if (STps->rw != ST_WRITING) {
3382 /* Are we totally rewriting this tape? */
3383 if (!STp->header_ok ||
3384 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3385 (STps->drv_file == 0 && STps->drv_block == 0)) {
3386 STp->wrt_pass_cntr++;
3388 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3389 name, STp->wrt_pass_cntr);
3391 osst_reset_header(STp, &SRpnt);
3392 STps->drv_file = STps->drv_block = 0;
3394 /* Do we know where we'll be writing on the tape? */
3396 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3397 STps->drv_file < 0 || STps->drv_block < 0) {
3398 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3399 STps->drv_file = STp->filemark_cnt;
3400 STps->drv_block = 0;
3403 /* We have no idea where the tape is positioned - give up */
3406 "%s:D: Cannot write at indeterminate position.\n", name);
3412 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3413 STp->filemark_cnt = STps->drv_file;
3414 STp->last_mark_ppos =
3415 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3417 "%s:W: Overwriting file %d with old write pass counter %d\n",
3418 name, STps->drv_file, STp->wrt_pass_cntr);
3420 "%s:W: may lead to stale data being accepted on reading back!\n",
3424 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3425 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3431 if (!STp->header_ok) {
3433 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3439 if ((STp->buffer)->writing) {
3440 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3441 osst_write_behind_check(STp);
3442 if ((STp->buffer)->syscall_result) {
3445 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3446 (STp->buffer)->midlevel_result);
3448 if ((STp->buffer)->midlevel_result == INT_MAX)
3449 STps->eof = ST_EOM_OK;
3451 STps->eof = ST_EOM_ERROR;
3454 if (STps->eof == ST_EOM_OK) {
3458 else if (STps->eof == ST_EOM_ERROR) {
3463 /* Check the buffer readability in cases where copy_user might catch
3464 the problems after some tape movement. */
3465 if ((copy_from_user(&i, buf, 1) != 0 ||
3466 copy_from_user(&i, buf + count - 1, 1) != 0)) {
3471 if (!STm->do_buffer_writes) {
3472 write_threshold = 1;
3475 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3476 if (!STm->do_async_writes)
3482 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3483 name, (int) count, STps->drv_file, STps->drv_block,
3484 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3487 while ((STp->buffer)->buffer_bytes + count > write_threshold)
3490 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3491 (STp->buffer)->buffer_bytes;
3492 if (do_count > count)
3495 i = append_to_buffer(b_point, STp->buffer, do_count);
3501 blks = do_count / STp->block_size;
3502 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3504 i = osst_write_frame(STp, &SRpnt, 1);
3506 if (i == (-ENOSPC)) {
3507 transfer = STp->buffer->writing; /* FIXME -- check this logic */
3508 if (transfer <= do_count) {
3509 filp->f_pos += do_count - transfer;
3510 count -= do_count - transfer;
3511 if (STps->drv_block >= 0) {
3512 STps->drv_block += (do_count - transfer) / STp->block_size;
3514 STps->eof = ST_EOM_OK;
3515 retval = (-ENOSPC); /* EOM within current request */
3518 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3519 name, (int) transfer);
3523 STps->eof = ST_EOM_ERROR;
3524 STps->drv_block = (-1); /* Too cautious? */
3525 retval = (-EIO); /* EOM for old data */
3528 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3536 if (SRpnt != NULL) {
3537 osst_release_request(SRpnt);
3540 STp->buffer->buffer_bytes = 0;
3543 retval = total - count;
3547 filp->f_pos += do_count;
3548 b_point += do_count;
3550 if (STps->drv_block >= 0) {
3551 STps->drv_block += blks;
3553 STp->buffer->buffer_bytes = 0;
3555 } /* end while write threshold exceeded */
3559 i = append_to_buffer(b_point, STp->buffer, count);
3564 blks = count / STp->block_size;
3565 STp->logical_blk_num += blks;
3566 if (STps->drv_block >= 0) {
3567 STps->drv_block += blks;
3569 filp->f_pos += count;
3573 if (doing_write && (STp->buffer)->syscall_result != 0) {
3574 retval = (STp->buffer)->syscall_result;
3578 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3579 /* Schedule an asynchronous write */
3580 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3581 STp->block_size) * STp->block_size;
3582 STp->dirty = !((STp->buffer)->writing ==
3583 (STp->buffer)->buffer_bytes);
3585 i = osst_write_frame(STp, &SRpnt, 0);
3590 SRpnt = NULL; /* Prevent releasing this request! */
3592 STps->at_sm &= (total == 0);
3594 STps->eof = ST_NOEOF;
3599 if (SRpnt != NULL) osst_release_request(SRpnt);
3608 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3610 ssize_t total, retval = 0;
3611 ssize_t i, transfer;
3613 struct st_modedef * STm;
3614 struct st_partstat * STps;
3615 struct osst_request * SRpnt = NULL;
3616 struct osst_tape * STp = filp->private_data;
3617 char * name = tape_name(STp);
3620 if (down_interruptible(&STp->lock))
3621 return (-ERESTARTSYS);
3624 * If we are in the middle of error recovery, don't let anyone
3625 * else try and use this device. Also, if error recovery fails, it
3626 * may try and take the device offline, in which case all further
3627 * access to the device is prohibited.
3629 if( !scsi_block_when_processing_errors(STp->device) ) {
3634 if (STp->ready != ST_READY) {
3635 if (STp->ready == ST_NO_TAPE)
3636 retval = (-ENOMEDIUM);
3641 STm = &(STp->modes[STp->current_mode]);
3642 if (!STm->defined) {
3648 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3653 /* Must have initialized medium */
3654 if (!STp->header_ok) {
3659 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3660 STp->door_locked = ST_LOCKED_AUTO;
3662 STps = &(STp->ps[STp->partition]);
3663 if (STps->rw == ST_WRITING) {
3664 retval = osst_flush_buffer(STp, &SRpnt, 0);
3668 /* FIXME -- this may leave the tape without EOD and up2date headers */
3671 if ((count % STp->block_size) != 0) {
3673 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3674 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3678 if (debugging && STps->eof != ST_NOEOF)
3679 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3680 STps->eof, (STp->buffer)->buffer_bytes);
3682 if ((STp->buffer)->buffer_bytes == 0 &&
3683 STps->eof >= ST_EOD_1) {
3684 if (STps->eof < ST_EOD) {
3689 retval = (-EIO); /* EOM or Blank Check */
3693 /* Check the buffer writability before any tape movement. Don't alter
3695 if (copy_from_user(&i, buf, 1) != 0 ||
3696 copy_to_user (buf, &i, 1) != 0 ||
3697 copy_from_user(&i, buf + count - 1, 1) != 0 ||
3698 copy_to_user (buf + count - 1, &i, 1) != 0) {
3703 /* Loop until enough data in buffer or a special condition found */
3704 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3706 /* Get new data if the buffer is empty */
3707 if ((STp->buffer)->buffer_bytes == 0) {
3708 if (STps->eof == ST_FM_HIT)
3710 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3711 if (special < 0) { /* No need to continue read */
3712 STp->frame_in_buffer = 0;
3718 /* Move the data from driver buffer to user buffer */
3719 if ((STp->buffer)->buffer_bytes > 0) {
3721 if (debugging && STps->eof != ST_NOEOF)
3722 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3723 STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total));
3725 /* force multiple of block size, note block_size may have been adjusted */
3726 transfer = (((STp->buffer)->buffer_bytes < count - total ?
3727 (STp->buffer)->buffer_bytes : count - total)/
3728 STp->block_size) * STp->block_size;
3730 if (transfer == 0) {
3732 "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
3733 name, count, STp->block_size < 1024?
3734 STp->block_size:STp->block_size/1024,
3735 STp->block_size<1024?'b':'k');
3738 i = from_buffer(STp->buffer, buf, transfer);
3743 STp->logical_blk_num += transfer / STp->block_size;
3744 STps->drv_block += transfer / STp->block_size;
3745 filp->f_pos += transfer;
3750 if ((STp->buffer)->buffer_bytes == 0) {
3753 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3754 name, STp->frame_seq_number);
3756 STp->frame_in_buffer = 0;
3757 STp->frame_seq_number++; /* frame to look for next time */
3759 } /* for (total = 0, special = 0; total < count && !special; ) */
3761 /* Change the eof state if no data from tape or buffer */
3763 if (STps->eof == ST_FM_HIT) {
3764 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3765 STps->drv_block = 0;
3766 if (STps->drv_file >= 0)
3769 else if (STps->eof == ST_EOD_1) {
3770 STps->eof = ST_EOD_2;
3771 if (STps->drv_block > 0 && STps->drv_file >= 0)
3773 STps->drv_block = 0;
3775 else if (STps->eof == ST_EOD_2)
3778 else if (STps->eof == ST_FM)
3779 STps->eof = ST_NOEOF;
3784 if (SRpnt != NULL) osst_release_request(SRpnt);
3792 /* Set the driver options */
3793 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3796 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3797 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3798 STm->do_read_ahead);
3800 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3801 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3803 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3804 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3805 STp->scsi2_logical);
3807 "%s:I: sysv: %d\n", name, STm->sysv);
3810 "%s:D: debugging: %d\n",
3816 static int osst_set_options(struct osst_tape *STp, long options)
3820 struct st_modedef * STm;
3821 char * name = tape_name(STp);
3823 STm = &(STp->modes[STp->current_mode]);
3824 if (!STm->defined) {
3825 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3829 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3830 name, STp->current_mode);
3834 code = options & MT_ST_OPTIONS;
3835 if (code == MT_ST_BOOLEANS) {
3836 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3837 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3838 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3839 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3840 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3841 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3842 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3843 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3844 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3845 if ((STp->device)->scsi_level >= SCSI_2)
3846 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3847 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3848 STm->sysv = (options & MT_ST_SYSV) != 0;
3850 debugging = (options & MT_ST_DEBUGGING) != 0;
3852 osst_log_options(STp, STm, name);
3854 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3855 value = (code == MT_ST_SETBOOLEANS);
3856 if ((options & MT_ST_BUFFER_WRITES) != 0)
3857 STm->do_buffer_writes = value;
3858 if ((options & MT_ST_ASYNC_WRITES) != 0)
3859 STm->do_async_writes = value;
3860 if ((options & MT_ST_DEF_WRITES) != 0)
3861 STm->defaults_for_writes = value;
3862 if ((options & MT_ST_READ_AHEAD) != 0)
3863 STm->do_read_ahead = value;
3864 if ((options & MT_ST_TWO_FM) != 0)
3865 STp->two_fm = value;
3866 if ((options & MT_ST_FAST_MTEOM) != 0)
3867 STp->fast_mteom = value;
3868 if ((options & MT_ST_AUTO_LOCK) != 0)
3869 STp->do_auto_lock = value;
3870 if ((options & MT_ST_CAN_BSR) != 0)
3871 STp->can_bsr = value;
3872 if ((options & MT_ST_NO_BLKLIMS) != 0)
3873 STp->omit_blklims = value;
3874 if ((STp->device)->scsi_level >= SCSI_2 &&
3875 (options & MT_ST_CAN_PARTITIONS) != 0)
3876 STp->can_partitions = value;
3877 if ((options & MT_ST_SCSI2LOGICAL) != 0)
3878 STp->scsi2_logical = value;
3879 if ((options & MT_ST_SYSV) != 0)
3882 if ((options & MT_ST_DEBUGGING) != 0)
3885 osst_log_options(STp, STm, name);
3887 else if (code == MT_ST_WRITE_THRESHOLD) {
3888 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3889 if (value < 1 || value > osst_buffer_size) {
3890 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3894 STp->write_threshold = value;
3895 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3898 else if (code == MT_ST_DEF_BLKSIZE) {
3899 value = (options & ~MT_ST_OPTIONS);
3900 if (value == ~MT_ST_OPTIONS) {
3901 STm->default_blksize = (-1);
3902 printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3905 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3906 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3910 STm->default_blksize = value;
3911 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
3912 name, STm->default_blksize);
3915 else if (code == MT_ST_TIMEOUTS) {
3916 value = (options & ~MT_ST_OPTIONS);
3917 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
3918 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
3919 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
3920 (value & ~MT_ST_SET_LONG_TIMEOUT));
3923 STp->timeout = value * HZ;
3924 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
3927 else if (code == MT_ST_DEF_OPTIONS) {
3928 code = (options & ~MT_ST_CLEAR_DEFAULT);
3929 value = (options & MT_ST_CLEAR_DEFAULT);
3930 if (code == MT_ST_DEF_DENSITY) {
3931 if (value == MT_ST_CLEAR_DEFAULT) {
3932 STm->default_density = (-1);
3933 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
3936 STm->default_density = value & 0xff;
3937 printk(KERN_INFO "%s:I: Density default set to %x\n",
3938 name, STm->default_density);
3941 else if (code == MT_ST_DEF_DRVBUFFER) {
3942 if (value == MT_ST_CLEAR_DEFAULT) {
3943 STp->default_drvbuffer = 0xff;
3944 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
3947 STp->default_drvbuffer = value & 7;
3948 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
3949 name, STp->default_drvbuffer);
3952 else if (code == MT_ST_DEF_COMPRESSION) {
3953 if (value == MT_ST_CLEAR_DEFAULT) {
3954 STm->default_compression = ST_DONT_TOUCH;
3955 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
3958 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
3959 printk(KERN_INFO "%s:I: Compression default set to %x\n",
3971 /* Internal ioctl function */
3972 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt,
3973 unsigned int cmd_in, unsigned long arg)
3977 int i, ioctl_result;
3979 unsigned char cmd[MAX_COMMAND_SIZE];
3980 struct osst_request * SRpnt = * aSRpnt;
3981 struct st_partstat * STps;
3982 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
3983 int datalen = 0, direction = DMA_NONE;
3984 char * name = tape_name(STp);
3986 if (STp->ready != ST_READY && cmd_in != MTLOAD) {
3987 if (STp->ready == ST_NO_TAPE)
3988 return (-ENOMEDIUM);
3992 timeout = STp->long_timeout;
3993 STps = &(STp->ps[STp->partition]);
3994 fileno = STps->drv_file;
3995 blkno = STps->drv_block;
3996 at_sm = STps->at_sm;
3997 frame_seq_numbr = STp->frame_seq_number;
3998 logical_blk_num = STp->logical_blk_num;
4000 memset(cmd, 0, MAX_COMMAND_SIZE);
4003 chg_eof = 0; /* Changed from the FSF after this */
4007 if (STp->linux_media)
4008 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
4010 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
4014 at_sm &= (arg == 0);
4018 chg_eof = 0; /* Changed from the FSF after this */
4022 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
4025 blkno = (-1); /* We can't know the block number */
4026 at_sm &= (arg == 0);
4033 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
4034 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
4036 if (cmd_in == MTFSR) {
4037 logical_blk_num += arg;
4038 if (blkno >= 0) blkno += arg;
4041 logical_blk_num -= arg;
4042 if (blkno >= 0) blkno -= arg;
4044 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
4045 fileno = STps->drv_file;
4046 blkno = STps->drv_block;
4047 at_sm &= (arg == 0);
4052 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4053 cmd[2] = (arg >> 16);
4054 cmd[3] = (arg >> 8);
4058 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4059 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4062 blkno = fileno = (-1);
4068 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4070 cmd[2] = (ltmp >> 16);
4071 cmd[3] = (ltmp >> 8);
4077 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4078 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4083 blkno = fileno = (-1);
4088 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4089 STp->write_type = OS_WRITE_DATA;
4090 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4095 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4097 for (i=0; i<arg; i++)
4098 ioctl_result |= osst_write_filemark(STp, &SRpnt);
4099 if (fileno >= 0) fileno += arg;
4100 if (blkno >= 0) blkno = 0;
4104 if (STp->write_prot)
4108 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
4109 if (cmd_in == MTWSM)
4111 cmd[2] = (arg >> 16);
4112 cmd[3] = (arg >> 8);
4114 timeout = STp->timeout;
4117 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4118 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4123 at_sm = (cmd_in == MTWSM);
4129 cmd[0] = START_STOP;
4130 cmd[1] = 1; /* Don't wait for completion */
4131 if (cmd_in == MTLOAD) {
4132 if (STp->ready == ST_NO_TAPE)
4133 cmd[4] = 4; /* open tray */
4135 cmd[4] = 1; /* load */
4137 if (cmd_in == MTRETEN)
4138 cmd[4] = 3; /* retension then mount */
4139 if (cmd_in == MTOFFL)
4140 cmd[4] = 4; /* rewind then eject */
4141 timeout = STp->timeout;
4146 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4149 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4152 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4155 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4160 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4165 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4167 return 0; /* Should do something ? */
4172 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4174 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4175 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4176 ioctl_result = -EIO;
4179 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4181 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4183 ioctl_result = -EIO;
4186 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4187 fileno = STp->filemark_cnt;
4192 if (STp->write_prot)
4194 ioctl_result = osst_reset_header(STp, &SRpnt);
4195 i = osst_write_eod(STp, &SRpnt);
4196 if (i < ioctl_result) ioctl_result = i;
4197 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4198 if (i < ioctl_result) ioctl_result = i;
4199 fileno = blkno = at_sm = 0 ;
4203 cmd[0] = REZERO_UNIT; /* rewind */
4207 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4209 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4212 case MTSETBLK: /* Set block length */
4213 if ((STps->drv_block == 0 ) &&
4215 ((STp->buffer)->buffer_bytes == 0) &&
4216 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4217 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4218 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4220 * Only allowed to change the block size if you opened the
4221 * device at the beginning of a file before writing anything.
4222 * Note, that when reading, changing block_size is futile,
4223 * as the size used when writing overrides it.
4225 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4226 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4227 name, STp->block_size);
4230 case MTSETDENSITY: /* Set tape density */
4231 case MTSETDRVBUFFER: /* Set drive buffering */
4232 case SET_DENS_AND_BLK: /* Set density and block size */
4234 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4235 return (-EIO); /* Not allowed if data in buffer */
4236 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4237 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4238 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4239 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4240 name, (int)(arg & MT_ST_BLKSIZE_MASK),
4241 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4244 return 0; /* FIXME silently ignore if block size didn't change */
4250 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4252 ioctl_result = (STp->buffer)->syscall_result;
4256 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4258 return ioctl_result;
4261 if (!ioctl_result) { /* SCSI command successful */
4262 STp->frame_seq_number = frame_seq_numbr;
4263 STp->logical_blk_num = logical_blk_num;
4269 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4272 if (!ioctl_result) { /* success */
4274 if (cmd_in == MTFSFM) {
4278 if (cmd_in == MTBSFM) {
4282 STps->drv_block = blkno;
4283 STps->drv_file = fileno;
4284 STps->at_sm = at_sm;
4286 if (cmd_in == MTEOM)
4288 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4289 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4291 STp->logical_blk_num++;
4292 STp->frame_seq_number++;
4293 STp->frame_in_buffer = 0;
4294 STp->buffer->read_pointer = 0;
4296 else if (cmd_in == MTFSF)
4297 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4299 STps->eof = ST_NOEOF;
4301 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4302 STp->rew_at_close = 0;
4303 else if (cmd_in == MTLOAD) {
4304 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4305 STp->ps[i].rw = ST_IDLE;
4306 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4311 if (cmd_in == MTREW) {
4312 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4313 if (ioctl_result > 0)
4317 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4318 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4319 STps->drv_file = STps->drv_block = -1;
4321 STps->drv_file = STps->drv_block = 0;
4322 STps->eof = ST_NOEOF;
4323 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4324 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4325 STps->drv_file = STps->drv_block = -1;
4327 STps->drv_file = STp->filemark_cnt;
4328 STps->drv_block = 0;
4331 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4332 STps->drv_file = STps->drv_block = (-1);
4333 STps->eof = ST_NOEOF;
4335 } else if (cmd_in == MTERASE) {
4337 } else if (SRpnt) { /* SCSI command was not completely successful. */
4338 if (SRpnt->sense[2] & 0x40) {
4339 STps->eof = ST_EOM_OK;
4340 STps->drv_block = 0;
4343 STps->eof = ST_NOEOF;
4345 if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK)
4348 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4349 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4353 return ioctl_result;
4357 /* Open the device */
4358 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4360 unsigned short flags;
4361 int i, b_size, new_session = 0, retval = 0;
4362 unsigned char cmd[MAX_COMMAND_SIZE];
4363 struct osst_request * SRpnt = NULL;
4364 struct osst_tape * STp;
4365 struct st_modedef * STm;
4366 struct st_partstat * STps;
4368 int dev = TAPE_NR(inode);
4369 int mode = TAPE_MODE(inode);
4372 * We really want to do nonseekable_open(inode, filp); here, but some
4373 * versions of tar incorrectly call lseek on tapes and bail out if that
4374 * fails. So we disallow pread() and pwrite(), but permit lseeks.
4376 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
4378 write_lock(&os_scsi_tapes_lock);
4379 if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4380 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4381 write_unlock(&os_scsi_tapes_lock);
4385 name = tape_name(STp);
4388 write_unlock(&os_scsi_tapes_lock);
4390 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4394 if (scsi_device_get(STp->device)) {
4395 write_unlock(&os_scsi_tapes_lock);
4397 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4401 filp->private_data = STp;
4403 write_unlock(&os_scsi_tapes_lock);
4404 STp->rew_at_close = TAPE_REWIND(inode);
4406 if( !scsi_block_when_processing_errors(STp->device) ) {
4410 if (mode != STp->current_mode) {
4413 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4414 name, STp->current_mode, mode);
4417 STp->current_mode = mode;
4419 STm = &(STp->modes[STp->current_mode]);
4421 flags = filp->f_flags;
4422 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4424 STp->raw = TAPE_IS_RAW(inode);
4428 /* Allocate data segments for this device's tape buffer */
4429 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4430 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4431 retval = (-EOVERFLOW);
4434 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4435 for (i = 0, b_size = 0;
4436 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4437 b_size += STp->buffer->sg[i++].length);
4438 STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
4440 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4441 STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4442 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4443 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4446 STp->buffer->aux = NULL; /* this had better never happen! */
4447 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4451 STp->buffer->writing = 0;
4452 STp->buffer->syscall_result = 0;
4454 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4455 STps = &(STp->ps[i]);
4458 STp->ready = ST_READY;
4460 STp->nbr_waits = STp->nbr_finished = 0;
4463 memset (cmd, 0, MAX_COMMAND_SIZE);
4464 cmd[0] = TEST_UNIT_READY;
4466 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4468 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
4471 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4472 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4473 SRpnt->sense[12] == 4 ) {
4475 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]);
4477 if (filp->f_flags & O_NONBLOCK) {
4481 if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */
4482 memset (cmd, 0, MAX_COMMAND_SIZE);
4483 cmd[0] = START_STOP;
4486 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4487 STp->timeout, MAX_RETRIES, 1);
4489 osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
4491 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4492 (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4494 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4498 for (i=0; i < 10; i++) {
4500 memset (cmd, 0, MAX_COMMAND_SIZE);
4501 cmd[0] = TEST_UNIT_READY;
4503 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4504 STp->timeout, MAX_RETRIES, 1);
4505 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4506 (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
4510 STp->pos_unknown = 0;
4511 STp->partition = STp->new_partition = 0;
4512 if (STp->can_partitions)
4513 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4514 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4515 STps = &(STp->ps[i]);
4516 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4517 STps->eof = ST_NOEOF;
4519 STps->last_block_valid = 0;
4520 STps->drv_block = 0;
4521 STps->drv_file = 0 ;
4524 STp->recover_count = 0;
4525 STp->abort_count = 0;
4528 * if we have valid headers from before, and the drive/tape seem untouched,
4529 * open without reconfiguring and re-reading the headers
4531 if (!STp->buffer->syscall_result && STp->header_ok &&
4532 !SRpnt->result && SRpnt->sense[0] == 0) {
4534 memset(cmd, 0, MAX_COMMAND_SIZE);
4535 cmd[0] = MODE_SENSE;
4537 cmd[2] = VENDOR_IDENT_PAGE;
4538 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4540 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4542 if (STp->buffer->syscall_result ||
4543 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4544 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4545 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4546 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4548 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4549 STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4550 STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4551 STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4552 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4556 i = STp->first_frame_position;
4557 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4558 if (STp->door_locked == ST_UNLOCKED) {
4559 if (do_door_lock(STp, 1))
4560 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4562 STp->door_locked = ST_LOCKED_AUTO;
4564 if (!STp->frame_in_buffer) {
4565 STp->block_size = (STm->default_blksize > 0) ?
4566 STm->default_blksize : OS_DATA_SIZE;
4567 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4569 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4571 osst_release_request(SRpnt);
4575 if (i != STp->first_frame_position)
4576 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4577 name, i, STp->first_frame_position);
4583 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4584 (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) {
4586 memset(cmd, 0, MAX_COMMAND_SIZE);
4587 cmd[0] = MODE_SELECT;
4589 cmd[4] = 4 + MODE_HEADER_LENGTH;
4591 (STp->buffer)->b_data[0] = cmd[4] - 1;
4592 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4593 (STp->buffer)->b_data[2] = 0; /* Reserved */
4594 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4595 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4596 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4597 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4598 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4601 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4603 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4607 for (i=0; i < 10; i++) {
4609 memset (cmd, 0, MAX_COMMAND_SIZE);
4610 cmd[0] = TEST_UNIT_READY;
4612 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4613 STp->timeout, MAX_RETRIES, 1);
4614 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4615 (SRpnt->sense[2] & 0x0f) == NOT_READY)
4618 if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
4619 STp->pos_unknown = 0;
4620 STp->partition = STp->new_partition = 0;
4621 if (STp->can_partitions)
4622 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4623 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4624 STps = &(STp->ps[i]);
4626 STps->eof = ST_NOEOF;
4628 STps->last_block_valid = 0;
4629 STps->drv_block = 0;
4630 STps->drv_file = 0 ;
4637 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4638 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4640 if ((STp->buffer)->syscall_result != 0) {
4641 if ((STp->device)->scsi_level >= SCSI_2 &&
4642 (SRpnt->sense[0] & 0x70) == 0x70 &&
4643 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4644 SRpnt->sense[12] == 0x3a) { /* Check ASC */
4645 STp->ready = ST_NO_TAPE;
4647 STp->ready = ST_NOT_READY;
4648 osst_release_request(SRpnt);
4650 STp->density = 0; /* Clear the erroneous "residue" */
4651 STp->write_prot = 0;
4652 STp->block_size = 0;
4653 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4654 STp->partition = STp->new_partition = 0;
4655 STp->door_locked = ST_UNLOCKED;
4659 osst_configure_onstream(STp, &SRpnt);
4661 STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4662 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4663 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4664 STp->buffer->buffer_bytes =
4665 STp->buffer->read_pointer =
4666 STp->frame_in_buffer = 0;
4670 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4671 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4672 (STp->buffer)->buffer_blocks);
4675 if (STp->drv_write_prot) {
4676 STp->write_prot = 1;
4679 printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4681 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4687 if (new_session) { /* Change the drive parameters for the new mode */
4690 printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4692 STp->density_changed = STp->blksize_changed = 0;
4693 STp->compression_changed = 0;
4697 * properly position the tape and check the ADR headers
4699 if (STp->door_locked == ST_UNLOCKED) {
4700 if (do_door_lock(STp, 1))
4701 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4703 STp->door_locked = ST_LOCKED_AUTO;
4706 osst_analyze_headers(STp, &SRpnt);
4708 osst_release_request(SRpnt);
4715 osst_release_request(SRpnt);
4716 normalize_buffer(STp->buffer);
4719 scsi_device_put(STp->device);
4725 /* Flush the tape buffer before close */
4726 static int os_scsi_tape_flush(struct file * filp)
4728 int result = 0, result2;
4729 struct osst_tape * STp = filp->private_data;
4730 struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4731 struct st_partstat * STps = &(STp->ps[STp->partition]);
4732 struct osst_request * SRpnt = NULL;
4733 char * name = tape_name(STp);
4735 if (file_count(filp) > 1)
4738 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4739 STp->write_type = OS_WRITE_DATA;
4740 result = osst_flush_write_buffer(STp, &SRpnt);
4741 if (result != 0 && result != (-ENOSPC))
4744 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4748 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4749 name, (long)(filp->f_pos));
4750 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4751 name, STp->nbr_waits, STp->nbr_finished);
4754 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4757 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4758 name, 1+STp->two_fm);
4761 else if (!STp->rew_at_close) {
4762 STps = &(STp->ps[STp->partition]);
4763 if (!STm->sysv || STps->rw != ST_READING) {
4765 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4766 else if (STps->eof == ST_FM_HIT) {
4767 result = cross_eof(STp, &SRpnt, 0);
4769 if (STps->drv_file >= 0)
4771 STps->drv_block = 0;
4775 STps->eof = ST_NOEOF;
4778 else if ((STps->eof == ST_NOEOF &&
4779 !(result = cross_eof(STp, &SRpnt, 1))) ||
4780 STps->eof == ST_FM_HIT) {
4781 if (STps->drv_file >= 0)
4783 STps->drv_block = 0;
4789 if (STp->rew_at_close) {
4790 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4791 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4792 if (result == 0 && result2 < 0)
4795 if (SRpnt) osst_release_request(SRpnt);
4797 if (STp->abort_count || STp->recover_count) {
4798 printk(KERN_INFO "%s:I:", name);
4799 if (STp->abort_count)
4800 printk(" %d unrecovered errors", STp->abort_count);
4801 if (STp->recover_count)
4802 printk(" %d recovered errors", STp->recover_count);
4803 if (STp->write_count)
4804 printk(" in %d frames written", STp->write_count);
4805 if (STp->read_count)
4806 printk(" in %d frames read", STp->read_count);
4808 STp->recover_count = 0;
4809 STp->abort_count = 0;
4811 STp->write_count = 0;
4812 STp->read_count = 0;
4818 /* Close the device and release it */
4819 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4822 struct osst_tape * STp = filp->private_data;
4824 if (STp->door_locked == ST_LOCKED_AUTO)
4825 do_door_lock(STp, 0);
4830 normalize_buffer(STp->buffer);
4831 write_lock(&os_scsi_tapes_lock);
4833 write_unlock(&os_scsi_tapes_lock);
4835 scsi_device_put(STp->device);
4841 /* The ioctl command */
4842 static int osst_ioctl(struct inode * inode,struct file * file,
4843 unsigned int cmd_in, unsigned long arg)
4845 int i, cmd_nr, cmd_type, retval = 0;
4847 struct st_modedef * STm;
4848 struct st_partstat * STps;
4849 struct osst_request * SRpnt = NULL;
4850 struct osst_tape * STp = file->private_data;
4851 char * name = tape_name(STp);
4852 void __user * p = (void __user *)arg;
4854 if (down_interruptible(&STp->lock))
4855 return -ERESTARTSYS;
4858 if (debugging && !STp->in_use) {
4859 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4864 STm = &(STp->modes[STp->current_mode]);
4865 STps = &(STp->ps[STp->partition]);
4868 * If we are in the middle of error recovery, don't let anyone
4869 * else try and use this device. Also, if error recovery fails, it
4870 * may try and take the device offline, in which case all further
4871 * access to the device is prohibited.
4873 if( !scsi_block_when_processing_errors(STp->device) ) {
4878 cmd_type = _IOC_TYPE(cmd_in);
4879 cmd_nr = _IOC_NR(cmd_in);
4881 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4882 cmd_type, cmd_nr, STp->raw?"raw":"normal");
4884 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4888 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
4893 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
4899 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
4900 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
4905 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
4910 if (!STp->pos_unknown) {
4912 if (STps->eof == ST_FM_HIT) {
4913 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
4915 if (STps->drv_file >= 0)
4916 STps->drv_file += 1;
4918 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
4920 if (STps->drv_file >= 0)
4921 STps->drv_file += 1;
4925 if (mtc.mt_op == MTSEEK) {
4926 /* Old position must be restored if partition will be changed */
4927 i = !STp->can_partitions || (STp->new_partition != STp->partition);
4930 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
4931 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
4932 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
4933 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
4934 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
4935 mtc.mt_op == MTCOMPRESSION;
4937 i = osst_flush_buffer(STp, &SRpnt, i);
4945 * If there was a bus reset, block further access
4946 * to this device. If the user wants to rewind the tape,
4947 * then reset the flag and allow access again.
4949 if(mtc.mt_op != MTREW &&
4950 mtc.mt_op != MTOFFL &&
4951 mtc.mt_op != MTRETEN &&
4952 mtc.mt_op != MTERASE &&
4953 mtc.mt_op != MTSEEK &&
4954 mtc.mt_op != MTEOM) {
4959 /* remove this when the midlevel properly clears was_reset */
4960 STp->device->was_reset = 0;
4963 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK &&
4964 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
4965 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER &&
4966 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART &&
4967 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) {
4970 * The user tells us to move to another position on the tape.
4971 * If we were appending to the tape content, that would leave
4972 * the tape without proper end, in that case write EOD and
4973 * update the header to reflect its position.
4976 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
4977 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
4978 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
4979 STp->logical_blk_num, STps->drv_file, STps->drv_block );
4981 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
4982 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
4983 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4984 i = osst_write_trailer(STp, &SRpnt,
4985 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4987 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
4988 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
4989 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
4999 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
5000 do_door_lock(STp, 0); /* Ignore result! */
5002 if (mtc.mt_op == MTSETDRVBUFFER &&
5003 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
5004 retval = osst_set_options(STp, mtc.mt_count);
5008 if (mtc.mt_op == MTSETPART) {
5009 if (mtc.mt_count >= STp->nbr_partitions)
5012 STp->new_partition = mtc.mt_count;
5018 if (mtc.mt_op == MTMKPART) {
5019 if (!STp->can_partitions) {
5023 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
5024 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
5028 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5029 STp->ps[i].rw = ST_IDLE;
5030 STp->ps[i].at_sm = 0;
5031 STp->ps[i].last_block_valid = 0;
5033 STp->partition = STp->new_partition = 0;
5034 STp->nbr_partitions = 1; /* Bad guess ?-) */
5035 STps->drv_block = STps->drv_file = 0;
5040 if (mtc.mt_op == MTSEEK) {
5042 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
5044 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
5045 if (!STp->can_partitions)
5046 STp->ps[0].rw = ST_IDLE;
5051 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
5052 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
5057 cross_eof(STp, &SRpnt, 0);
5059 if (mtc.mt_op == MTCOMPRESSION)
5060 retval = -EINVAL; /* OnStream drives don't have compression hardware */
5062 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5063 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5064 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5068 if (!STm->defined) {
5073 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5078 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
5079 struct mtget mt_status;
5081 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
5086 mt_status.mt_type = MT_ISONSTREAM_SC;
5087 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
5088 mt_status.mt_dsreg =
5089 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
5090 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
5091 mt_status.mt_blkno = STps->drv_block;
5092 mt_status.mt_fileno = STps->drv_file;
5093 if (STp->block_size != 0) {
5094 if (STps->rw == ST_WRITING)
5095 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
5096 else if (STps->rw == ST_READING)
5097 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
5098 STp->block_size - 1) / STp->block_size;
5101 mt_status.mt_gstat = 0;
5102 if (STp->drv_write_prot)
5103 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
5104 if (mt_status.mt_blkno == 0) {
5105 if (mt_status.mt_fileno == 0)
5106 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
5108 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
5110 mt_status.mt_resid = STp->partition;
5111 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
5112 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
5113 else if (STps->eof >= ST_EOM_OK)
5114 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
5115 if (STp->density == 1)
5116 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
5117 else if (STp->density == 2)
5118 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
5119 else if (STp->density == 3)
5120 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
5121 if (STp->ready == ST_READY)
5122 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
5123 if (STp->ready == ST_NO_TAPE)
5124 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
5126 mt_status.mt_gstat |= GMT_SM(0xffffffff);
5127 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
5128 STp->drv_buffer != 0)
5129 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
5131 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
5137 STp->recover_erreg = 0; /* Clear after read */
5140 } /* End of MTIOCGET */
5142 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5143 struct mtpos mt_pos;
5145 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5150 blk = osst_get_frame_position(STp, &SRpnt);
5152 blk = osst_get_sector(STp, &SRpnt);
5157 mt_pos.mt_blkno = blk;
5158 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5163 if (SRpnt) osst_release_request(SRpnt);
5167 return scsi_ioctl(STp->device, cmd_in, p);
5170 if (SRpnt) osst_release_request(SRpnt);
5177 #ifdef CONFIG_COMPAT
5178 static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg)
5180 struct osst_tape *STp = file->private_data;
5181 struct scsi_device *sdev = STp->device;
5182 int ret = -ENOIOCTLCMD;
5183 if (sdev->host->hostt->compat_ioctl) {
5185 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
5194 /* Memory handling routines */
5196 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5197 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5201 struct osst_buffer *tb;
5203 if (from_initialization)
5204 priority = GFP_ATOMIC;
5206 priority = GFP_KERNEL;
5208 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5209 tb = (struct osst_buffer *)kmalloc(i, priority);
5211 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5215 tb->sg_segs = tb->orig_sg_segs = 0;
5216 tb->use_sg = max_sg;
5219 tb->buffer_size = 0;
5223 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5224 i, max_sg, need_dma);
5229 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5230 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5232 int segs, nbr, max_segs, b_size, order, got;
5235 if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5238 if (STbuffer->sg_segs) {
5239 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5240 normalize_buffer(STbuffer);
5242 /* See how many segments we can use -- need at least two */
5243 nbr = max_segs = STbuffer->use_sg;
5247 priority = GFP_KERNEL /* | __GFP_NOWARN */;
5249 priority |= GFP_DMA;
5251 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5252 big enough to reach the goal (code assumes no segments in place) */
5253 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5254 STbuffer->sg[0].page = alloc_pages(priority, order);
5255 STbuffer->sg[0].offset = 0;
5256 if (STbuffer->sg[0].page != NULL) {
5257 STbuffer->sg[0].length = b_size;
5258 STbuffer->b_data = page_address(STbuffer->sg[0].page);
5262 if (STbuffer->sg[0].page == NULL) {
5263 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5266 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5267 for (segs=STbuffer->sg_segs=1, got=b_size;
5268 segs < max_segs && got < OS_FRAME_SIZE; ) {
5269 STbuffer->sg[segs].page =
5270 alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5271 STbuffer->sg[segs].offset = 0;
5272 if (STbuffer->sg[segs].page == NULL) {
5273 if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
5274 b_size /= 2; /* Large enough for the rest of the buffers */
5278 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5281 STbuffer->buffer_size = got;
5283 normalize_buffer(STbuffer);
5286 STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
5287 got += STbuffer->sg[segs].length;
5288 STbuffer->buffer_size = got;
5289 STbuffer->sg_segs = ++segs;
5294 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5295 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5297 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5298 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5299 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5307 /* Release the segments */
5308 static void normalize_buffer(struct osst_buffer *STbuffer)
5310 int i, order, b_size;
5312 for (i=0; i < STbuffer->sg_segs; i++) {
5314 for (b_size = PAGE_SIZE, order = 0;
5315 b_size < STbuffer->sg[i].length;
5316 b_size *= 2, order++);
5318 __free_pages(STbuffer->sg[i].page, order);
5319 STbuffer->buffer_size -= STbuffer->sg[i].length;
5322 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5323 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5324 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5326 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5330 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5331 negative error code. */
5332 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
5334 int i, cnt, res, offset;
5336 for (i=0, offset=st_bp->buffer_bytes;
5337 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5338 offset -= st_bp->sg[i].length;
5339 if (i == st_bp->sg_segs) { /* Should never happen */
5340 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5343 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5344 cnt = st_bp->sg[i].length - offset < do_count ?
5345 st_bp->sg[i].length - offset : do_count;
5346 res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
5350 st_bp->buffer_bytes += cnt;
5354 if (do_count) { /* Should never happen */
5355 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5363 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5364 negative error code. */
5365 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
5367 int i, cnt, res, offset;
5369 for (i=0, offset=st_bp->read_pointer;
5370 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5371 offset -= st_bp->sg[i].length;
5372 if (i == st_bp->sg_segs) { /* Should never happen */
5373 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5376 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5377 cnt = st_bp->sg[i].length - offset < do_count ?
5378 st_bp->sg[i].length - offset : do_count;
5379 res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
5383 st_bp->buffer_bytes -= cnt;
5384 st_bp->read_pointer += cnt;
5388 if (do_count) { /* Should never happen */
5389 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5395 /* Sets the tail of the buffer after fill point to zero.
5396 Returns zero (success) or negative error code. */
5397 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
5399 int i, offset, do_count, cnt;
5401 for (i = 0, offset = st_bp->buffer_bytes;
5402 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5403 offset -= st_bp->sg[i].length;
5404 if (i == st_bp->sg_segs) { /* Should never happen */
5405 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5408 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5409 i < st_bp->sg_segs && do_count > 0; i++) {
5410 cnt = st_bp->sg[i].length - offset < do_count ?
5411 st_bp->sg[i].length - offset : do_count ;
5412 memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
5416 if (do_count) { /* Should never happen */
5417 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5423 /* Copy a osst 32K chunk of memory into the buffer.
5424 Returns zero (success) or negative error code. */
5425 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5427 int i, cnt, do_count = OS_DATA_SIZE;
5429 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5430 cnt = st_bp->sg[i].length < do_count ?
5431 st_bp->sg[i].length : do_count ;
5432 memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
5436 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5437 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5444 /* Copy a osst 32K chunk of memory from the buffer.
5445 Returns zero (success) or negative error code. */
5446 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5448 int i, cnt, do_count = OS_DATA_SIZE;
5450 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5451 cnt = st_bp->sg[i].length < do_count ?
5452 st_bp->sg[i].length : do_count ;
5453 memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
5457 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5458 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5466 /* Module housekeeping */
5468 static void validate_options (void)
5471 osst_max_dev = max_dev;
5472 if (write_threshold_kbs > 0)
5473 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5474 if (osst_write_threshold > osst_buffer_size)
5475 osst_write_threshold = osst_buffer_size;
5476 if (max_sg_segs >= OSST_FIRST_SG)
5477 osst_max_sg_segs = max_sg_segs;
5479 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5480 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5485 /* Set the boot options. Syntax: osst=xxx,yyy,...
5486 where xxx is write threshold in 1024 byte blocks,
5487 and yyy is number of s/g segments to use. */
5488 static int __init osst_setup (char *str)
5493 stp = get_options(str, ARRAY_SIZE(ints), ints);
5496 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5497 *parms[i].val = ints[i + 1];
5499 while (stp != NULL) {
5500 for (i = 0; i < ARRAY_SIZE(parms); i++) {
5501 int len = strlen(parms[i].name);
5502 if (!strncmp(stp, parms[i].name, len) &&
5503 (*(stp + len) == ':' || *(stp + len) == '=')) {
5505 simple_strtoul(stp + len + 1, NULL, 0);
5509 if (i >= sizeof(parms) / sizeof(struct osst_dev_parm))
5510 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5512 stp = strchr(stp, ',');
5521 __setup("osst=", osst_setup);
5525 static struct file_operations osst_fops = {
5526 .owner = THIS_MODULE,
5528 .write = osst_write,
5529 .ioctl = osst_ioctl,
5530 #ifdef CONFIG_COMPAT
5531 .compat_ioctl = osst_compat_ioctl,
5533 .open = os_scsi_tape_open,
5534 .flush = os_scsi_tape_flush,
5535 .release = os_scsi_tape_close,
5538 static int osst_supports(struct scsi_device * SDp)
5540 struct osst_support_data {
5544 char *driver_hint; /* Name of the correct driver, NULL if unknown */
5547 static struct osst_support_data support_list[] = {
5548 /* {"XXX", "Yy-", "", NULL}, example */
5552 struct osst_support_data *rp;
5554 /* We are willing to drive OnStream SC-x0 as well as the
5555 * * IDE, ParPort, FireWire, USB variants, if accessible by
5556 * * emulation layer (ide-scsi, usb-storage, ...) */
5558 for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5559 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5560 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5561 !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5567 * sysfs support for osst driver parameter information
5570 static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
5572 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
5575 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
5577 static void osst_create_driverfs_files(struct device_driver *driverfs)
5579 driver_create_file(driverfs, &driver_attr_version);
5582 static void osst_remove_driverfs_files(struct device_driver *driverfs)
5584 driver_remove_file(driverfs, &driver_attr_version);
5588 * sysfs support for accessing ADR header information
5591 static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf)
5593 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5596 if (STp && STp->header_ok && STp->linux_media)
5597 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
5601 CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
5603 static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf)
5605 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5608 if (STp && STp->header_ok && STp->linux_media)
5609 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
5613 CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
5615 static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf)
5617 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5620 if (STp && STp->header_ok && STp->linux_media)
5621 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
5625 CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
5627 static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf)
5629 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5632 if (STp && STp->header_ok && STp->linux_media)
5633 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
5637 CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
5639 static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf)
5641 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5644 if (STp && STp->header_ok && STp->linux_media)
5645 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
5649 CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
5651 static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf)
5653 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5656 if (STp && STp->header_ok && STp->linux_media)
5657 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
5661 CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5663 static struct class *osst_sysfs_class;
5665 static int osst_sysfs_valid = 0;
5667 static void osst_sysfs_init(void)
5669 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
5670 if ( IS_ERR(osst_sysfs_class) )
5671 printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
5673 osst_sysfs_valid = 1;
5676 static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5678 struct class_device *osst_class_member;
5680 if (!osst_sysfs_valid) return;
5682 osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name);
5683 if (IS_ERR(osst_class_member)) {
5684 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5687 class_set_devdata(osst_class_member, STp);
5688 class_device_create_file(osst_class_member, &class_device_attr_ADR_rev);
5689 class_device_create_file(osst_class_member, &class_device_attr_media_version);
5690 class_device_create_file(osst_class_member, &class_device_attr_capacity);
5691 class_device_create_file(osst_class_member, &class_device_attr_BOT_frame);
5692 class_device_create_file(osst_class_member, &class_device_attr_EOD_frame);
5693 class_device_create_file(osst_class_member, &class_device_attr_file_count);
5696 static void osst_sysfs_destroy(dev_t dev)
5698 if (!osst_sysfs_valid) return;
5700 class_device_destroy(osst_sysfs_class, dev);
5703 static void osst_sysfs_cleanup(void)
5705 if (osst_sysfs_valid) {
5706 class_destroy(osst_sysfs_class);
5707 osst_sysfs_valid = 0;
5712 * osst startup / cleanup code
5715 static int osst_probe(struct device *dev)
5717 struct scsi_device * SDp = to_scsi_device(dev);
5718 struct osst_tape * tpnt;
5719 struct st_modedef * STm;
5720 struct st_partstat * STps;
5721 struct osst_buffer * buffer;
5722 struct gendisk * drive;
5725 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5728 drive = alloc_disk(1);
5730 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5734 /* if this is the first attach, build the infrastructure */
5735 write_lock(&os_scsi_tapes_lock);
5736 if (os_scsi_tapes == NULL) {
5738 (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *),
5740 if (os_scsi_tapes == NULL) {
5741 write_unlock(&os_scsi_tapes_lock);
5742 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5745 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5748 if (osst_nr_dev >= osst_max_dev) {
5749 write_unlock(&os_scsi_tapes_lock);
5750 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5754 /* find a free minor number */
5755 for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++);
5756 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5759 /* allocate a struct osst_tape for this device */
5760 tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
5762 write_unlock(&os_scsi_tapes_lock);
5763 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5766 memset(tpnt, 0, sizeof(struct osst_tape));
5768 /* allocate a buffer for this device */
5769 i = SDp->host->sg_tablesize;
5770 if (osst_max_sg_segs < i)
5771 i = osst_max_sg_segs;
5772 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
5773 if (buffer == NULL) {
5774 write_unlock(&os_scsi_tapes_lock);
5775 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5779 os_scsi_tapes[dev_num] = tpnt;
5780 tpnt->buffer = buffer;
5782 drive->private_data = &tpnt->driver;
5783 sprintf(drive->disk_name, "osst%d", dev_num);
5784 tpnt->driver = &osst_template;
5785 tpnt->drive = drive;
5787 tpnt->capacity = 0xfffff;
5789 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
5790 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5792 tpnt->do_auto_lock = OSST_AUTO_LOCK;
5793 tpnt->can_bsr = OSST_IN_FILE_POS;
5794 tpnt->can_partitions = 0;
5795 tpnt->two_fm = OSST_TWO_FM;
5796 tpnt->fast_mteom = OSST_FAST_MTEOM;
5797 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5798 tpnt->write_threshold = osst_write_threshold;
5799 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5800 tpnt->partition = 0;
5801 tpnt->new_partition = 0;
5802 tpnt->nbr_partitions = 0;
5803 tpnt->min_block = 512;
5804 tpnt->max_block = OS_DATA_SIZE;
5805 tpnt->timeout = OSST_TIMEOUT;
5806 tpnt->long_timeout = OSST_LONG_TIMEOUT;
5808 /* Recognize OnStream tapes */
5809 /* We don't need to test for OnStream, as this has been done in detect () */
5810 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5811 tpnt->omit_blklims = 1;
5813 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5814 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5815 tpnt->frame_in_buffer = 0;
5816 tpnt->header_ok = 0;
5817 tpnt->linux_media = 0;
5818 tpnt->header_cache = NULL;
5820 for (i=0; i < ST_NBR_MODES; i++) {
5821 STm = &(tpnt->modes[i]);
5823 STm->sysv = OSST_SYSV;
5824 STm->defaults_for_writes = 0;
5825 STm->do_async_writes = OSST_ASYNC_WRITES;
5826 STm->do_buffer_writes = OSST_BUFFER_WRITES;
5827 STm->do_read_ahead = OSST_READ_AHEAD;
5828 STm->default_compression = ST_DONT_TOUCH;
5829 STm->default_blksize = 512;
5830 STm->default_density = (-1); /* No forced density */
5833 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5834 STps = &(tpnt->ps[i]);
5836 STps->eof = ST_NOEOF;
5838 STps->last_block_valid = 0;
5839 STps->drv_block = (-1);
5840 STps->drv_file = (-1);
5843 tpnt->current_mode = 0;
5844 tpnt->modes[0].defined = 1;
5845 tpnt->modes[2].defined = 1;
5846 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
5848 init_MUTEX(&tpnt->lock);
5850 write_unlock(&os_scsi_tapes_lock);
5854 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5855 /* No-rewind entry */
5856 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5857 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5860 sdev_printk(KERN_INFO, SDp,
5861 "osst :I: Attached OnStream %.5s tape as %s\n",
5862 SDp->model, tape_name(tpnt));
5871 static int osst_remove(struct device *dev)
5873 struct scsi_device * SDp = to_scsi_device(dev);
5874 struct osst_tape * tpnt;
5877 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
5880 write_lock(&os_scsi_tapes_lock);
5881 for(i=0; i < osst_max_dev; i++) {
5882 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
5883 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
5884 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
5885 tpnt->device = NULL;
5886 put_disk(tpnt->drive);
5887 os_scsi_tapes[i] = NULL;
5889 write_unlock(&os_scsi_tapes_lock);
5890 vfree(tpnt->header_cache);
5892 normalize_buffer(tpnt->buffer);
5893 kfree(tpnt->buffer);
5899 write_unlock(&os_scsi_tapes_lock);
5903 static int __init init_osst(void)
5905 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
5910 if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
5911 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
5912 osst_sysfs_cleanup();
5915 osst_create_driverfs_files(&osst_template.gendrv);
5920 static void __exit exit_osst (void)
5923 struct osst_tape * STp;
5925 osst_remove_driverfs_files(&osst_template.gendrv);
5926 scsi_unregister_driver(&osst_template.gendrv);
5927 unregister_chrdev(OSST_MAJOR, "osst");
5928 osst_sysfs_cleanup();
5930 if (os_scsi_tapes) {
5931 for (i=0; i < osst_max_dev; ++i) {
5932 if (!(STp = os_scsi_tapes[i])) continue;
5933 /* This is defensive, supposed to happen during detach */
5934 vfree(STp->header_cache);
5936 normalize_buffer(STp->buffer);
5939 put_disk(STp->drive);
5942 kfree(os_scsi_tapes);
5944 printk(KERN_INFO "osst :I: Unloaded.\n");
5947 module_init(init_osst);
5948 module_exit(exit_osst);