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");
89 module_param(max_dev, int, 0444);
90 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
92 module_param(write_threshold_kbs, int, 0644);
93 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
95 module_param(max_sg_segs, int, 0644);
96 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
98 static struct osst_dev_parm {
101 } parms[] __initdata = {
102 { "max_dev", &max_dev },
103 { "write_threshold_kbs", &write_threshold_kbs },
104 { "max_sg_segs", &max_sg_segs }
108 /* Some default definitions have been moved to osst_options.h */
109 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
110 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
112 /* The buffer size should fit into the 24 bits for length in the
113 6-byte SCSI read and write commands. */
114 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
115 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
119 static int debugging = 1;
120 /* uncomment define below to test error recovery */
121 // #define OSST_INJECT_ERRORS 1
124 /* Do not retry! The drive firmware already retries when appropriate,
125 and when it tries to tell us something, we had better listen... */
126 #define MAX_RETRIES 0
128 #define NO_TAPE NOT_READY
130 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
131 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
132 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
134 #define OSST_TIMEOUT (200 * HZ)
135 #define OSST_LONG_TIMEOUT (1800 * HZ)
137 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
138 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
139 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
140 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
142 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
144 #define SET_DENS_AND_BLK 0x10001
146 static int osst_buffer_size = OSST_BUFFER_SIZE;
147 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
148 static int osst_max_sg_segs = OSST_MAX_SG;
149 static int osst_max_dev = OSST_MAX_TAPES;
150 static int osst_nr_dev;
152 static struct osst_tape **os_scsi_tapes = NULL;
153 static DEFINE_RWLOCK(os_scsi_tapes_lock);
155 static int modes_defined = 0;
157 static struct osst_buffer *new_tape_buffer(int, int, int);
158 static int enlarge_buffer(struct osst_buffer *, int);
159 static void normalize_buffer(struct osst_buffer *);
160 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
161 static int from_buffer(struct osst_buffer *, char __user *, int);
162 static int osst_zero_buffer_tail(struct osst_buffer *);
163 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
164 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
166 static int osst_probe(struct device *);
167 static int osst_remove(struct device *);
169 static struct scsi_driver osst_template = {
170 .owner = THIS_MODULE,
174 .remove = osst_remove,
178 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt,
179 unsigned int cmd_in, unsigned long arg);
181 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip);
183 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt);
185 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt);
187 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending);
189 static inline char *tape_name(struct osst_tape *tape)
191 return tape->drive->disk_name;
194 /* Routines that handle the interaction with mid-layer SCSI routines */
197 /* Normalize Sense */
198 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s)
201 const u8 *sense = SRpnt->sense;
203 s->have_sense = scsi_normalize_sense(SRpnt->sense,
204 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
210 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
211 switch (sense[0] & 0x7f) {
216 s->flags = sense[2] & 0xe0;
222 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
223 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
229 /* Convert the result to success code */
230 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
232 char *name = tape_name(STp);
233 int result = SRpnt->result;
234 u8 * sense = SRpnt->sense, scode;
238 struct st_cmdstatus *cmdstatp;
243 cmdstatp = &STp->buffer->cmdstat;
244 osst_analyze_sense(SRpnt, cmdstatp);
246 if (cmdstatp->have_sense)
247 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
252 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
254 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
255 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
256 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
257 name, scode, sense[12], sense[13]);
258 if (cmdstatp->have_sense)
259 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
263 if (cmdstatp->have_sense && (
265 scode != RECOVERED_ERROR &&
266 /* scode != UNIT_ATTENTION && */
267 scode != BLANK_CHECK &&
268 scode != VOLUME_OVERFLOW &&
269 SRpnt->cmd[0] != MODE_SENSE &&
270 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
271 if (cmdstatp->have_sense) {
272 printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
273 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
276 static int notyetprinted = 1;
279 "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
280 name, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
285 "%s:I: This warning may be caused by your scsi controller,\n", name);
287 "%s:I: it has been reported with some Buslogic cards.\n", name);
291 STp->pos_unknown |= STp->device->was_reset;
293 if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
294 STp->recover_count++;
295 STp->recover_erreg++;
298 if (SRpnt->cmd[0] == READ_6)
300 else if (SRpnt->cmd[0] == WRITE_6)
304 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
308 if ((sense[2] & 0xe0) == 0)
315 /* Wakeup from interrupt */
316 static void osst_sleep_done(void *data, char *sense, int result, int resid)
318 struct osst_request *SRpnt = data;
319 struct osst_tape *STp = SRpnt->stp;
321 memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
322 STp->buffer->cmdstat.midlevel_result = SRpnt->result = result;
324 STp->write_pending = 0;
327 complete(SRpnt->waiting);
330 /* osst_request memory management */
331 static struct osst_request *osst_allocate_request(void)
333 return kzalloc(sizeof(struct osst_request), GFP_KERNEL);
336 static void osst_release_request(struct osst_request *streq)
341 /* Do the scsi command. Waits until command performed if do_wait is true.
342 Otherwise osst_write_behind_check() is used to check that the command
344 static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp,
345 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
348 unsigned short use_sg;
349 #ifdef OSST_INJECT_ERRORS
350 static int inject = 0;
351 static int repeat = 0;
353 struct completion *waiting;
355 /* if async, make sure there's no command outstanding */
356 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
357 printk(KERN_ERR "%s: Async command already active.\n",
359 if (signal_pending(current))
360 (STp->buffer)->syscall_result = (-EINTR);
362 (STp->buffer)->syscall_result = (-EBUSY);
367 SRpnt = osst_allocate_request();
369 printk(KERN_ERR "%s: Can't allocate SCSI request.\n",
371 if (signal_pending(current))
372 (STp->buffer)->syscall_result = (-EINTR);
374 (STp->buffer)->syscall_result = (-EBUSY);
380 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
381 which IO is outstanding. It's nulled out when the IO completes. */
383 (STp->buffer)->last_SRpnt = SRpnt;
385 waiting = &STp->wait;
386 init_completion(waiting);
387 SRpnt->waiting = waiting;
389 use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0;
391 bp = (char *)&(STp->buffer->sg[0]);
392 if (STp->buffer->sg_segs < use_sg)
393 use_sg = STp->buffer->sg_segs;
396 bp = (STp->buffer)->b_data;
398 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
399 STp->buffer->cmdstat.have_sense = 0;
400 STp->buffer->syscall_result = 0;
402 if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
403 use_sg, timeout, retries, SRpnt, osst_sleep_done, GFP_KERNEL))
404 /* could not allocate the buffer or request was too large */
405 (STp->buffer)->syscall_result = (-EBUSY);
407 wait_for_completion(waiting);
408 SRpnt->waiting = NULL;
409 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
410 #ifdef OSST_INJECT_ERRORS
411 if (STp->buffer->syscall_result == 0 &&
414 ( (++ inject % 83) == 29 ||
415 (STp->first_frame_position == 240
416 /* or STp->read_error_frame to fail again on the block calculated above */ &&
418 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
419 STp->buffer->last_result_fatal = 1;
427 /* Handle the write-behind checking (downs the semaphore) */
428 static void osst_write_behind_check(struct osst_tape *STp)
430 struct osst_buffer * STbuffer;
432 STbuffer = STp->buffer;
435 if (STp->write_pending)
440 wait_for_completion(&(STp->wait));
441 STp->buffer->last_SRpnt->waiting = NULL;
443 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
445 if (STp->buffer->syscall_result)
446 STp->buffer->syscall_result =
447 osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1);
449 STp->first_frame_position++;
451 osst_release_request(STp->buffer->last_SRpnt);
453 if (STbuffer->writing < STbuffer->buffer_bytes)
454 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
456 STbuffer->last_SRpnt = NULL;
457 STbuffer->buffer_bytes -= STbuffer->writing;
458 STbuffer->writing = 0;
465 /* Onstream specific Routines */
467 * Initialize the OnStream AUX
469 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
470 int logical_blk_num, int blk_sz, int blk_cnt)
472 os_aux_t *aux = STp->buffer->aux;
473 os_partition_t *par = &aux->partition;
474 os_dat_t *dat = &aux->dat;
476 if (STp->raw) return;
478 memset(aux, 0, sizeof(*aux));
479 aux->format_id = htonl(0);
480 memcpy(aux->application_sig, "LIN4", 4);
481 aux->hdwr = htonl(0);
482 aux->frame_type = frame_type;
484 switch (frame_type) {
485 case OS_FRAME_TYPE_HEADER:
486 aux->update_frame_cntr = htonl(STp->update_frame_cntr);
487 par->partition_num = OS_CONFIG_PARTITION;
488 par->par_desc_ver = OS_PARTITION_VERSION;
489 par->wrt_pass_cntr = htons(0xffff);
490 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
491 par->first_frame_ppos = htonl(0);
492 par->last_frame_ppos = htonl(0xbb7);
493 aux->frame_seq_num = htonl(0);
494 aux->logical_blk_num_high = htonl(0);
495 aux->logical_blk_num = htonl(0);
496 aux->next_mark_ppos = htonl(STp->first_mark_ppos);
498 case OS_FRAME_TYPE_DATA:
499 case OS_FRAME_TYPE_MARKER:
504 dat->dat_list[0].blk_sz = htonl(blk_sz);
505 dat->dat_list[0].blk_cnt = htons(blk_cnt);
506 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
507 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
508 dat->dat_list[0].reserved = 0;
509 case OS_FRAME_TYPE_EOD:
510 aux->update_frame_cntr = htonl(0);
511 par->partition_num = OS_DATA_PARTITION;
512 par->par_desc_ver = OS_PARTITION_VERSION;
513 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
514 par->first_frame_ppos = htonl(STp->first_data_ppos);
515 par->last_frame_ppos = htonl(STp->capacity);
516 aux->frame_seq_num = htonl(frame_seq_number);
517 aux->logical_blk_num_high = htonl(0);
518 aux->logical_blk_num = htonl(logical_blk_num);
520 default: ; /* probably FILL */
522 aux->filemark_cnt = ntohl(STp->filemark_cnt);
523 aux->phys_fm = ntohl(0xffffffff);
524 aux->last_mark_ppos = ntohl(STp->last_mark_ppos);
525 aux->last_mark_lbn = ntohl(STp->last_mark_lbn);
529 * Verify that we have the correct tape frame
531 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
533 char * name = tape_name(STp);
534 os_aux_t * aux = STp->buffer->aux;
535 os_partition_t * par = &(aux->partition);
536 struct st_partstat * STps = &(STp->ps[STp->partition]);
537 int blk_cnt, blk_sz, i;
540 if (STp->buffer->syscall_result) {
541 for (i=0; i < STp->buffer->sg_segs; i++)
542 memset(page_address(STp->buffer->sg[i].page),
543 0, STp->buffer->sg[i].length);
544 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
546 STp->buffer->buffer_bytes = OS_FRAME_SIZE;
549 if (STp->buffer->syscall_result) {
551 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
555 if (ntohl(aux->format_id) != 0) {
557 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
561 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
562 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
564 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
568 if (par->partition_num != OS_DATA_PARTITION) {
569 if (!STp->linux_media || STp->linux_media_version != 2) {
571 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
572 name, par->partition_num);
577 if (par->par_desc_ver != OS_PARTITION_VERSION) {
579 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
583 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
585 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
586 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
590 if (aux->frame_type != OS_FRAME_TYPE_DATA &&
591 aux->frame_type != OS_FRAME_TYPE_EOD &&
592 aux->frame_type != OS_FRAME_TYPE_MARKER) {
595 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
599 if (aux->frame_type == OS_FRAME_TYPE_EOD &&
600 STp->first_frame_position < STp->eod_frame_ppos) {
601 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
602 STp->first_frame_position);
605 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
608 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
609 name, ntohl(aux->frame_seq_num), frame_seq_number);
613 if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
614 STps->eof = ST_FM_HIT;
616 i = ntohl(aux->filemark_cnt);
617 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
618 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
620 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
621 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
622 i, STp->first_frame_position - 1);
624 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
625 if (i >= STp->filemark_cnt)
626 STp->filemark_cnt = i+1;
629 if (aux->frame_type == OS_FRAME_TYPE_EOD) {
630 STps->eof = ST_EOD_1;
631 STp->frame_in_buffer = 1;
633 if (aux->frame_type == OS_FRAME_TYPE_DATA) {
634 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
635 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
636 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
637 STp->buffer->read_pointer = 0;
638 STp->frame_in_buffer = 1;
640 /* See what block size was used to write file */
641 if (STp->block_size != blk_sz && blk_sz > 0) {
643 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
644 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
645 STp->block_size<1024?STp->block_size:STp->block_size/1024,
646 STp->block_size<1024?'b':'k');
647 STp->block_size = blk_sz;
648 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
650 STps->eof = ST_NOEOF;
652 STp->frame_seq_number = ntohl(aux->frame_seq_num);
653 STp->logical_blk_num = ntohl(aux->logical_blk_num);
657 if (STp->read_error_frame == 0)
658 STp->read_error_frame = STp->first_frame_position - 1;
663 * Wait for the unit to become Ready
665 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
666 unsigned timeout, int initial_delay)
668 unsigned char cmd[MAX_COMMAND_SIZE];
669 struct osst_request * SRpnt;
670 unsigned long startwait = jiffies;
673 char * name = tape_name(STp);
675 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
678 if (initial_delay > 0)
679 msleep(jiffies_to_msecs(initial_delay));
681 memset(cmd, 0, MAX_COMMAND_SIZE);
682 cmd[0] = TEST_UNIT_READY;
684 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
686 if (!SRpnt) return (-EBUSY);
688 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
689 (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
690 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) ||
691 ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 &&
692 SRpnt->sense[13] == 0 ) )) {
695 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
696 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
702 memset(cmd, 0, MAX_COMMAND_SIZE);
703 cmd[0] = TEST_UNIT_READY;
705 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
711 if ( STp->buffer->syscall_result &&
712 osst_write_error_recovery(STp, aSRpnt, 0) ) {
714 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
715 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
716 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
717 SRpnt->sense[12], SRpnt->sense[13]);
722 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
728 * Wait for a tape to be inserted in the unit
730 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
732 unsigned char cmd[MAX_COMMAND_SIZE];
733 struct osst_request * SRpnt;
734 unsigned long startwait = jiffies;
737 char * name = tape_name(STp);
739 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
742 memset(cmd, 0, MAX_COMMAND_SIZE);
743 cmd[0] = TEST_UNIT_READY;
745 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
747 if (!SRpnt) return (-EBUSY);
749 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
750 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) {
753 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
754 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
760 memset(cmd, 0, MAX_COMMAND_SIZE);
761 cmd[0] = TEST_UNIT_READY;
763 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
769 if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 &&
770 SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) {
772 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
773 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
774 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
775 SRpnt->sense[12], SRpnt->sense[13]);
780 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
785 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame)
789 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
790 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
791 if (retval) return (retval);
792 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
793 return (osst_get_frame_position(STp, aSRpnt));
797 * Wait for write(s) to complete
799 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
801 unsigned char cmd[MAX_COMMAND_SIZE];
802 struct osst_request * SRpnt;
804 int delay = OSST_WAIT_WRITE_COMPLETE;
806 char * name = tape_name(STp);
808 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
811 memset(cmd, 0, MAX_COMMAND_SIZE);
812 cmd[0] = WRITE_FILEMARKS;
815 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
817 if (!SRpnt) return (-EBUSY);
818 if (STp->buffer->syscall_result) {
819 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) {
820 if (SRpnt->sense[13] == 8) {
821 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
824 result = osst_write_error_recovery(STp, aSRpnt, 0);
826 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
827 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
832 #define OSST_POLL_PER_SEC 10
833 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to)
835 unsigned long startwait = jiffies;
836 char * name = tape_name(STp);
838 char notyetprinted = 1;
840 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
841 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
843 while (time_before (jiffies, startwait + to*HZ))
846 result = osst_get_frame_position(STp, aSRpnt);
848 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
849 return 0; /* successful recovery leaves drive ready for frame */
850 if (result < 0) break;
851 if (STp->first_frame_position == curr &&
853 (signed)STp->last_frame_position > (signed)curr + minlast) ||
854 (minlast >= 0 && STp->cur_frames > minlast)
858 if (debugging || jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC)
860 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
861 name, curr, curr+minlast, STp->first_frame_position,
862 STp->last_frame_position, STp->cur_frames,
863 result, (jiffies-startwait)/HZ,
864 (((jiffies-startwait)%HZ)*10)/HZ);
869 if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted)
871 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
872 name, curr, curr+minlast, STp->first_frame_position,
873 STp->last_frame_position, STp->cur_frames, result);
877 msleep(1000 / OSST_POLL_PER_SEC);
880 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
881 name, curr, curr+minlast, STp->first_frame_position,
882 STp->last_frame_position, STp->cur_frames,
883 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
888 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
890 struct osst_request * SRpnt;
891 unsigned char cmd[MAX_COMMAND_SIZE];
892 unsigned long startwait = jiffies;
894 char * name = tape_name(STp);
898 char * olddata = STp->buffer->b_data;
899 int oldsize = STp->buffer->buffer_size;
901 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
903 memset(cmd, 0, MAX_COMMAND_SIZE);
904 cmd[0] = WRITE_FILEMARKS;
906 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
909 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
911 if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) {
913 /* some failure - not just not-ready */
914 retval = osst_write_error_recovery(STp, aSRpnt, 0);
917 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
919 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
920 memset(cmd, 0, MAX_COMMAND_SIZE);
921 cmd[0] = READ_POSITION;
923 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
926 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
927 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
930 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
932 /* TODO - figure out which error conditions can be handled */
933 if (STp->buffer->syscall_result)
935 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
936 (*aSRpnt)->sense[ 2] & 0x0f,
937 (*aSRpnt)->sense[12],
938 (*aSRpnt)->sense[13]);
944 * Read the next OnStream tape frame at the current location
946 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
948 unsigned char cmd[MAX_COMMAND_SIZE];
949 struct osst_request * SRpnt;
952 os_aux_t * aux = STp->buffer->aux;
953 char * name = tape_name(STp);
957 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
958 retval = osst_recover_wait_frame(STp, aSRpnt, 0);
960 memset(cmd, 0, MAX_COMMAND_SIZE);
967 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
969 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
970 STp->timeout, MAX_RETRIES, 1);
975 if ((STp->buffer)->syscall_result) {
977 if (STp->read_error_frame == 0) {
978 STp->read_error_frame = STp->first_frame_position;
980 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
985 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
987 SRpnt->sense[0], SRpnt->sense[1],
988 SRpnt->sense[2], SRpnt->sense[3],
989 SRpnt->sense[4], SRpnt->sense[5],
990 SRpnt->sense[6], SRpnt->sense[7]);
994 STp->first_frame_position++;
999 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
1002 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
1003 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
1004 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
1005 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
1006 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
1007 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
1008 if (aux->frame_type==2)
1009 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
1010 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
1011 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
1017 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
1019 struct st_partstat * STps = &(STp->ps[STp->partition]);
1020 struct osst_request * SRpnt ;
1021 unsigned char cmd[MAX_COMMAND_SIZE];
1023 char * name = tape_name(STp);
1025 if (STps->rw != ST_READING) { /* Initialize read operation */
1026 if (STps->rw == ST_WRITING || STp->dirty) {
1027 STp->write_type = OS_WRITE_DATA;
1028 osst_flush_write_buffer(STp, aSRpnt);
1029 osst_flush_drive_buffer(STp, aSRpnt);
1031 STps->rw = ST_READING;
1032 STp->frame_in_buffer = 0;
1035 * Issue a read 0 command to get the OnStream drive
1036 * read frames into its buffer.
1038 memset(cmd, 0, MAX_COMMAND_SIZE);
1043 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
1045 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
1047 if ((retval = STp->buffer->syscall_result))
1048 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
1054 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt,
1055 int frame_seq_number, int quiet)
1057 struct st_partstat * STps = &(STp->ps[STp->partition]);
1058 char * name = tape_name(STp);
1066 * If we want just any frame (-1) and there is a frame in the buffer, return it
1068 if (frame_seq_number == -1 && STp->frame_in_buffer) {
1070 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1075 * Search and wait for the next logical tape frame
1079 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1080 name, frame_seq_number);
1081 if (STp->read_error_frame) {
1082 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1084 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1085 name, STp->read_error_frame);
1087 STp->read_error_frame = 0;
1094 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1095 name, frame_seq_number, cnt);
1097 if ( osst_initiate_read(STp, aSRpnt)
1098 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1101 position = osst_get_frame_position(STp, aSRpnt);
1102 if (position >= 0xbae && position < 0xbb8)
1104 else if (position > STp->eod_frame_ppos || ++bad == 10) {
1105 position = STp->read_error_frame - 1;
1113 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1116 osst_set_frame_position(STp, aSRpnt, position, 0);
1119 if (osst_verify_frame(STp, frame_seq_number, quiet))
1121 if (osst_verify_frame(STp, -1, quiet)) {
1122 x = ntohl(STp->buffer->aux->frame_seq_num);
1123 if (STp->fast_open) {
1125 "%s:W: Found logical frame %d instead of %d after fast open\n",
1126 name, x, frame_seq_number);
1128 STp->read_error_frame = 0;
1131 if (x > frame_seq_number) {
1133 /* positioning backwards did not bring us to the desired frame */
1134 position = STp->read_error_frame - 1;
1137 position = osst_get_frame_position(STp, aSRpnt)
1138 + frame_seq_number - x - 1;
1140 if (STp->first_frame_position >= 3000 && position < 3000)
1145 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1146 name, x, frame_seq_number,
1147 STp->first_frame_position - position);
1149 osst_set_frame_position(STp, aSRpnt, position, 0);
1155 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1157 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1159 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1162 STp->frame_in_buffer = 0;
1165 STp->recover_count++;
1166 STp->recover_erreg++;
1167 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1168 name, STp->read_error_frame);
1173 if (debugging || STps->eof)
1175 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1176 name, frame_seq_number, STp->frame_seq_number, STps->eof);
1179 STp->read_error_frame = 0;
1183 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num)
1185 struct st_partstat * STps = &(STp->ps[STp->partition]);
1186 char * name = tape_name(STp);
1188 int frame_seq_estimate, ppos_estimate, move;
1190 if (logical_blk_num < 0) logical_blk_num = 0;
1192 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1193 name, logical_blk_num, STp->logical_blk_num,
1194 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1195 STp->block_size<1024?'b':'k');
1197 /* Do we know where we are? */
1198 if (STps->drv_block >= 0) {
1199 move = logical_blk_num - STp->logical_blk_num;
1200 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1201 move /= (OS_DATA_SIZE / STp->block_size);
1202 frame_seq_estimate = STp->frame_seq_number + move;
1204 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1206 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1207 else ppos_estimate = frame_seq_estimate + 20;
1208 while (++retries < 10) {
1209 if (ppos_estimate > STp->eod_frame_ppos-2) {
1210 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1211 ppos_estimate = STp->eod_frame_ppos - 2;
1213 if (frame_seq_estimate < 0) {
1214 frame_seq_estimate = 0;
1217 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1218 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1219 /* we've located the estimated frame, now does it have our block? */
1220 if (logical_blk_num < STp->logical_blk_num ||
1221 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1222 if (STps->eof == ST_FM_HIT)
1223 move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1225 move = logical_blk_num - STp->logical_blk_num;
1226 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1227 move /= (OS_DATA_SIZE / STp->block_size);
1229 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1232 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1233 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1234 STp->logical_blk_num, logical_blk_num, move);
1236 frame_seq_estimate += move;
1237 ppos_estimate += move;
1240 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1241 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1242 STp->logical_blk_num = logical_blk_num;
1245 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1246 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1247 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1250 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1251 if (STps->eof == ST_FM_HIT) {
1253 STps->drv_block = 0;
1255 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1256 STp->logical_blk_num -
1257 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1260 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1264 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1266 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1268 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1269 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1270 STp->logical_blk_num, logical_blk_num);
1272 if (frame_seq_estimate != STp->frame_seq_number)
1273 ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1278 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1279 name, logical_blk_num, STp->logical_blk_num, retries);
1283 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1284 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1285 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1286 * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1288 #define OSST_FRAME_SHIFT 6
1289 #define OSST_SECTOR_SHIFT 9
1290 #define OSST_SECTOR_MASK 0x03F
1292 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt)
1296 char * name = tape_name(STp);
1299 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1300 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1301 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1302 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1303 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1304 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1306 /* do we know where we are inside a file? */
1307 if (STp->ps[STp->partition].drv_block >= 0) {
1308 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1309 STp->first_frame_position) << OSST_FRAME_SHIFT;
1310 if (STp->ps[STp->partition].rw == ST_WRITING)
1311 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1313 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1315 sector = osst_get_frame_position(STp, aSRpnt);
1317 sector <<= OSST_FRAME_SHIFT;
1322 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector)
1324 struct st_partstat * STps = &(STp->ps[STp->partition]);
1325 int frame = sector >> OSST_FRAME_SHIFT,
1326 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1329 char * name = tape_name(STp);
1331 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1332 name, sector, frame, offset);
1334 if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1336 if (frame <= STp->first_data_ppos) {
1337 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1338 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1340 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1341 if (r < 0) return r;
1343 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1344 if (r < 0) return r;
1346 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1349 STp->logical_blk_num += offset / STp->block_size;
1350 STp->buffer->read_pointer = offset;
1351 STp->buffer->buffer_bytes -= offset;
1353 STp->frame_seq_number++;
1354 STp->frame_in_buffer = 0;
1355 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1356 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1358 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1359 if (STps->eof == ST_FM_HIT) {
1361 STps->drv_block = 0;
1363 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1364 STp->logical_blk_num -
1365 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1368 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1371 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1372 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1373 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1379 * Read back the drive's internal buffer contents, as a part
1380 * of the write error recovery mechanism for old OnStream
1381 * firmware revisions.
1382 * Precondition for this function to work: all frames in the
1383 * drive's buffer must be of one type (DATA, MARK or EOD)!
1385 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
1386 unsigned int frame, unsigned int skip, int pending)
1388 struct osst_request * SRpnt = * aSRpnt;
1389 unsigned char * buffer, * p;
1390 unsigned char cmd[MAX_COMMAND_SIZE];
1391 int flag, new_frame, i;
1392 int nframes = STp->cur_frames;
1393 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1394 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1395 - (nframes + pending - 1);
1396 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1397 - (nframes + pending - 1) * blks_per_frame;
1398 char * name = tape_name(STp);
1399 unsigned long startwait = jiffies;
1401 int dbg = debugging;
1404 if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
1407 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1408 name, nframes, pending?" and one that was pending":"");
1410 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1412 if (pending && debugging)
1413 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1414 name, frame_seq_number + nframes,
1415 logical_blk_num + nframes * blks_per_frame,
1416 p[0], p[1], p[2], p[3]);
1418 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1420 memset(cmd, 0, MAX_COMMAND_SIZE);
1421 cmd[0] = 0x3C; /* Buffer Read */
1422 cmd[1] = 6; /* Retrieve Faulty Block */
1423 cmd[7] = 32768 >> 8;
1424 cmd[8] = 32768 & 0xff;
1426 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1427 STp->timeout, MAX_RETRIES, 1);
1429 if ((STp->buffer)->syscall_result || !SRpnt) {
1430 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1435 osst_copy_from_buffer(STp->buffer, p);
1438 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1439 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1443 osst_get_frame_position(STp, aSRpnt);
1446 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1448 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1449 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1451 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1454 if (STp->write_type == OS_WRITE_HEADER) {
1456 p += skip * OS_DATA_SIZE;
1458 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1463 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1464 name, new_frame+i, frame_seq_number+i);
1466 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1467 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1468 osst_get_frame_position(STp, aSRpnt);
1471 if (new_frame > frame + 1000) {
1472 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1476 if ( i >= nframes + pending ) break;
1479 osst_copy_to_buffer(STp->buffer, p);
1481 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1483 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1484 logical_blk_num + i*blks_per_frame,
1485 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1486 memset(cmd, 0, MAX_COMMAND_SIZE);
1494 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1495 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1496 p[0], p[1], p[2], p[3]);
1498 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1499 STp->timeout, MAX_RETRIES, 1);
1501 if (STp->buffer->syscall_result)
1504 p += OS_DATA_SIZE; i++;
1506 /* if we just sent the last frame, wait till all successfully written */
1507 if ( i == nframes + pending ) {
1509 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1511 memset(cmd, 0, MAX_COMMAND_SIZE);
1512 cmd[0] = WRITE_FILEMARKS;
1514 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1515 STp->timeout, MAX_RETRIES, 1);
1518 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1519 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1523 flag = STp->buffer->syscall_result;
1524 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1526 memset(cmd, 0, MAX_COMMAND_SIZE);
1527 cmd[0] = TEST_UNIT_READY;
1529 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1532 if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
1533 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
1534 /* in the process of becoming ready */
1538 if (STp->buffer->syscall_result)
1544 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1550 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1551 SRpnt->sense[12] == 0 &&
1552 SRpnt->sense[13] == 2) {
1553 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1555 return (-EIO); /* hit end of tape = fail */
1557 i = ((SRpnt->sense[3] << 24) |
1558 (SRpnt->sense[4] << 16) |
1559 (SRpnt->sense[5] << 8) |
1560 SRpnt->sense[6] ) - new_frame;
1561 p = &buffer[i * OS_DATA_SIZE];
1563 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1565 osst_get_frame_position(STp, aSRpnt);
1567 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1568 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1573 /* error recovery did not successfully complete */
1574 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1575 STp->write_type == OS_WRITE_HEADER?"header":"body");
1578 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1583 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
1584 unsigned int frame, unsigned int skip, int pending)
1586 unsigned char cmd[MAX_COMMAND_SIZE];
1587 struct osst_request * SRpnt;
1588 char * name = tape_name(STp);
1590 int attempts = 1000 / skip;
1592 unsigned long startwait = jiffies;
1594 int dbg = debugging;
1597 while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1602 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1604 expected = frame+skip+STp->cur_frames+pending;
1606 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1607 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1609 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1612 schedule_timeout_interruptible(msecs_to_jiffies(100));
1614 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1616 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1617 name, STp->first_frame_position,
1618 STp->last_frame_position, STp->cur_frames);
1620 frame = STp->last_frame_position;
1624 if (pending && STp->cur_frames < 50) {
1626 memset(cmd, 0, MAX_COMMAND_SIZE);
1631 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1632 name, STp->frame_seq_number-1, STp->first_frame_position);
1634 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1635 STp->timeout, MAX_RETRIES, 1);
1638 if (STp->buffer->syscall_result) { /* additional write error */
1639 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1640 SRpnt->sense[12] == 0 &&
1641 SRpnt->sense[13] == 2) {
1643 "%s:E: Volume overflow in write error recovery\n",
1645 break; /* hit end of tape = fail */
1654 if (STp->cur_frames == 0) {
1657 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1659 if (STp->first_frame_position != expected) {
1660 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1661 name, STp->first_frame_position, expected);
1668 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1669 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1673 schedule_timeout_interruptible(msecs_to_jiffies(100));
1675 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1683 * Error recovery algorithm for the OnStream tape.
1686 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending)
1688 struct osst_request * SRpnt = * aSRpnt;
1689 struct st_partstat * STps = & STp->ps[STp->partition];
1690 char * name = tape_name(STp);
1693 unsigned int frame, skip;
1695 rw_state = STps->rw;
1697 if ((SRpnt->sense[ 2] & 0x0f) != 3
1698 || SRpnt->sense[12] != 12
1699 || SRpnt->sense[13] != 0) {
1701 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1702 SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]);
1706 frame = (SRpnt->sense[3] << 24) |
1707 (SRpnt->sense[4] << 16) |
1708 (SRpnt->sense[5] << 8) |
1710 skip = SRpnt->sense[9];
1713 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1715 osst_get_frame_position(STp, aSRpnt);
1717 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1718 name, STp->first_frame_position, STp->last_frame_position);
1720 switch (STp->write_type) {
1723 case OS_WRITE_NEW_MARK:
1725 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1726 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1727 if (STp->os_fw_rev >= 10600)
1728 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1730 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1731 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1733 retval?"" :"Don't worry, ",
1734 retval?" not ":" ");
1736 case OS_WRITE_LAST_MARK:
1737 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1738 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1741 case OS_WRITE_HEADER:
1742 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1743 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1746 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1747 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1749 osst_get_frame_position(STp, aSRpnt);
1751 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1752 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1753 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1756 STp->recover_count++;
1757 STp->recover_erreg++;
1761 STps->rw = rw_state;
1765 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt,
1766 int mt_op, int mt_count)
1768 char * name = tape_name(STp);
1770 int last_mark_ppos = -1;
1773 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1775 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1777 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1781 if (STp->linux_media_version >= 4) {
1783 * direct lookup in header filemark list
1785 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1786 if (STp->header_ok &&
1787 STp->header_cache != NULL &&
1788 (cnt - mt_count) >= 0 &&
1789 (cnt - mt_count) < OS_FM_TAB_MAX &&
1790 (cnt - mt_count) < STp->filemark_cnt &&
1791 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1793 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1795 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1796 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1797 STp->header_cache == NULL?"lack of header cache":"count out of range");
1799 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1801 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1802 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1803 STp->buffer->aux->last_mark_ppos))?"match":"error",
1804 mt_count, last_mark_ppos);
1806 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1807 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1808 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1811 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1815 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1816 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1817 name, last_mark_ppos);
1823 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1827 while (cnt != mt_count) {
1828 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1829 if (last_mark_ppos == -1)
1832 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1834 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1836 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1838 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1842 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1843 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1844 name, last_mark_ppos);
1849 if (mt_op == MTBSFM) {
1850 STp->frame_seq_number++;
1851 STp->frame_in_buffer = 0;
1852 STp->buffer->buffer_bytes = 0;
1853 STp->buffer->read_pointer = 0;
1854 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1860 * ADRL 1.1 compatible "slow" space filemarks fwd version
1862 * Just scans for the filemark sequentially.
1864 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt,
1865 int mt_op, int mt_count)
1869 char * name = tape_name(STp);
1871 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1873 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1875 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1880 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1882 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1886 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1888 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1890 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1892 if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1894 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1895 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1897 STp->eod_frame_ppos = STp->first_frame_position-1;
1901 if (cnt == mt_count)
1903 STp->frame_in_buffer = 0;
1905 if (mt_op == MTFSF) {
1906 STp->frame_seq_number++;
1907 STp->frame_in_buffer = 0;
1908 STp->buffer->buffer_bytes = 0;
1909 STp->buffer->read_pointer = 0;
1910 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1916 * Fast linux specific version of OnStream FSF
1918 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt,
1919 int mt_op, int mt_count)
1921 char * name = tape_name(STp);
1923 next_mark_ppos = -1;
1926 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
1928 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1930 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1935 if (STp->linux_media_version >= 4) {
1937 * direct lookup in header filemark list
1939 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
1940 if (STp->header_ok &&
1941 STp->header_cache != NULL &&
1942 (cnt + mt_count) < OS_FM_TAB_MAX &&
1943 (cnt + mt_count) < STp->filemark_cnt &&
1944 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1945 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
1947 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
1949 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
1950 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1951 STp->header_cache == NULL?"lack of header cache":"count out of range");
1953 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1955 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1956 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
1957 STp->buffer->aux->last_mark_ppos))?"match":"error",
1958 mt_count, next_mark_ppos);
1960 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
1962 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1964 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1966 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
1967 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1969 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
1974 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1975 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1976 name, next_mark_ppos);
1979 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
1980 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
1981 name, cnt+mt_count, next_mark_ppos,
1982 ntohl(STp->buffer->aux->filemark_cnt));
1988 * Find nearest (usually previous) marker, then jump from marker to marker
1991 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1993 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1995 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1999 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
2000 if (STp->first_mark_ppos == -1) {
2002 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2004 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2006 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
2007 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2010 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2015 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2016 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
2017 name, STp->first_mark_ppos);
2021 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
2027 while (cnt != mt_count) {
2028 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
2029 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
2031 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2033 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
2036 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
2038 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2040 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2042 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2047 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2048 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2049 name, next_mark_ppos);
2054 if (mt_op == MTFSF) {
2055 STp->frame_seq_number++;
2056 STp->frame_in_buffer = 0;
2057 STp->buffer->buffer_bytes = 0;
2058 STp->buffer->read_pointer = 0;
2059 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2065 * In debug mode, we want to see as many errors as possible
2066 * to test the error recovery mechanism.
2069 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries)
2071 unsigned char cmd[MAX_COMMAND_SIZE];
2072 struct osst_request * SRpnt = * aSRpnt;
2073 char * name = tape_name(STp);
2075 memset(cmd, 0, MAX_COMMAND_SIZE);
2076 cmd[0] = MODE_SELECT;
2078 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2080 (STp->buffer)->b_data[0] = cmd[4] - 1;
2081 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
2082 (STp->buffer)->b_data[2] = 0; /* Reserved */
2083 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
2084 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2085 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2086 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2087 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2090 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2092 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2095 if ((STp->buffer)->syscall_result)
2096 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2101 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt)
2104 int this_mark_ppos = STp->first_frame_position;
2105 int this_mark_lbn = STp->logical_blk_num;
2107 char * name = tape_name(STp);
2110 if (STp->raw) return 0;
2112 STp->write_type = OS_WRITE_NEW_MARK;
2114 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2115 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2118 result = osst_flush_write_buffer(STp, aSRpnt);
2119 result |= osst_flush_drive_buffer(STp, aSRpnt);
2120 STp->last_mark_ppos = this_mark_ppos;
2121 STp->last_mark_lbn = this_mark_lbn;
2122 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2123 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2124 if (STp->filemark_cnt++ == 0)
2125 STp->first_mark_ppos = this_mark_ppos;
2129 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt)
2133 char * name = tape_name(STp);
2136 if (STp->raw) return 0;
2138 STp->write_type = OS_WRITE_EOD;
2139 STp->eod_frame_ppos = STp->first_frame_position;
2141 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2142 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2146 result = osst_flush_write_buffer(STp, aSRpnt);
2147 result |= osst_flush_drive_buffer(STp, aSRpnt);
2148 STp->eod_frame_lfa = --(STp->frame_seq_number);
2152 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2154 char * name = tape_name(STp);
2157 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2159 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2160 osst_set_frame_position(STp, aSRpnt, where, 0);
2161 STp->write_type = OS_WRITE_FILLER;
2163 memcpy(STp->buffer->b_data, "Filler", 6);
2164 STp->buffer->buffer_bytes = 6;
2166 if (osst_flush_write_buffer(STp, aSRpnt)) {
2167 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2172 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2174 return osst_flush_drive_buffer(STp, aSRpnt);
2177 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2179 char * name = tape_name(STp);
2183 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2185 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2186 osst_set_frame_position(STp, aSRpnt, where, 0);
2187 STp->write_type = OS_WRITE_HEADER;
2189 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2190 STp->buffer->buffer_bytes = sizeof(os_header_t);
2192 if (osst_flush_write_buffer(STp, aSRpnt)) {
2193 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2197 result = osst_flush_drive_buffer(STp, aSRpnt);
2199 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2204 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod)
2206 os_header_t * header;
2208 char * name = tape_name(STp);
2211 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2213 if (STp->raw) return 0;
2215 if (STp->header_cache == NULL) {
2216 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2217 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2220 memset(STp->header_cache, 0, sizeof(os_header_t));
2222 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2225 if (STp->header_ok) STp->update_frame_cntr++;
2226 else STp->update_frame_cntr = 0;
2228 header = STp->header_cache;
2229 strcpy(header->ident_str, "ADR_SEQ");
2230 header->major_rev = 1;
2231 header->minor_rev = 4;
2232 header->ext_trk_tb_off = htons(17192);
2233 header->pt_par_num = 1;
2234 header->partition[0].partition_num = OS_DATA_PARTITION;
2235 header->partition[0].par_desc_ver = OS_PARTITION_VERSION;
2236 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2237 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2238 header->partition[0].last_frame_ppos = htonl(STp->capacity);
2239 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2240 header->cfg_col_width = htonl(20);
2241 header->dat_col_width = htonl(1500);
2242 header->qfa_col_width = htonl(0);
2243 header->ext_track_tb.nr_stream_part = 1;
2244 header->ext_track_tb.et_ent_sz = 32;
2245 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2246 header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2247 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2248 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2249 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa);
2250 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
2251 header->dat_fm_tab.fm_part_num = 0;
2252 header->dat_fm_tab.fm_tab_ent_sz = 4;
2253 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2254 STp->filemark_cnt:OS_FM_TAB_MAX);
2256 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2257 if (STp->update_frame_cntr == 0)
2258 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2259 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2263 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2265 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2268 printk(KERN_ERR "%s:E: Write header failed\n", name);
2270 memcpy(STp->application_sig, "LIN4", 4);
2271 STp->linux_media = 1;
2272 STp->linux_media_version = 4;
2278 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt)
2280 if (STp->header_cache != NULL)
2281 memset(STp->header_cache, 0, sizeof(os_header_t));
2283 STp->logical_blk_num = STp->frame_seq_number = 0;
2284 STp->frame_in_buffer = 0;
2285 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2286 STp->filemark_cnt = 0;
2287 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2288 return osst_write_header(STp, aSRpnt, 1);
2291 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos)
2293 char * name = tape_name(STp);
2294 os_header_t * header;
2297 int linux_media_version,
2303 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2304 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2305 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2306 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2307 if (osst_initiate_read (STp, aSRpnt)) {
2308 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2312 if (osst_read_frame(STp, aSRpnt, 180)) {
2314 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2318 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2319 aux = STp->buffer->aux;
2320 if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2322 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2326 if (ntohl(aux->frame_seq_num) != 0 ||
2327 ntohl(aux->logical_blk_num) != 0 ||
2328 aux->partition.partition_num != OS_CONFIG_PARTITION ||
2329 ntohl(aux->partition.first_frame_ppos) != 0 ||
2330 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2332 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2333 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2334 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2335 ntohl(aux->partition.last_frame_ppos));
2339 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2340 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2341 strlcpy(id_string, header->ident_str, 8);
2343 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2347 update_frame_cntr = ntohl(aux->update_frame_cntr);
2348 if (update_frame_cntr < STp->update_frame_cntr) {
2350 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2351 name, ppos, update_frame_cntr, STp->update_frame_cntr);
2355 if (header->major_rev != 1 || header->minor_rev != 4 ) {
2357 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2358 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2359 header->minor_rev > 4 )? "Invalid" : "Warning:",
2360 header->major_rev, header->minor_rev);
2362 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2366 if (header->pt_par_num != 1)
2367 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2368 name, header->pt_par_num);
2370 memcpy(id_string, aux->application_sig, 4);
2372 if (memcmp(id_string, "LIN", 3) == 0) {
2373 STp->linux_media = 1;
2374 linux_media_version = id_string[3] - '0';
2375 if (linux_media_version != 4)
2376 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2377 name, linux_media_version);
2379 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2382 if (linux_media_version < STp->linux_media_version) {
2384 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2385 name, ppos, linux_media_version);
2389 if (linux_media_version > STp->linux_media_version) {
2391 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2392 name, ppos, linux_media_version);
2394 memcpy(STp->application_sig, id_string, 5);
2395 STp->linux_media_version = linux_media_version;
2396 STp->update_frame_cntr = -1;
2398 if (update_frame_cntr > STp->update_frame_cntr) {
2400 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2401 name, ppos, update_frame_cntr);
2403 if (STp->header_cache == NULL) {
2404 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2405 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2409 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2412 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2413 header = STp->header_cache; /* further accesses from cached (full) copy */
2415 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2416 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2417 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2418 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2419 STp->filemark_cnt = ntohl(aux->filemark_cnt);
2420 STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2421 STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2422 STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2423 STp->update_frame_cntr = update_frame_cntr;
2425 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2426 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2427 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2428 STp->first_data_ppos,
2429 ntohl(header->partition[0].last_frame_ppos),
2430 ntohl(header->partition[0].eod_frame_ppos));
2431 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2432 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2434 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2436 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2438 memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2439 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2440 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2442 if (header->minor_rev == 4 &&
2443 (header->ext_trk_tb_off != htons(17192) ||
2444 header->partition[0].partition_num != OS_DATA_PARTITION ||
2445 header->partition[0].par_desc_ver != OS_PARTITION_VERSION ||
2446 header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2447 header->cfg_col_width != htonl(20) ||
2448 header->dat_col_width != htonl(1500) ||
2449 header->qfa_col_width != htonl(0) ||
2450 header->ext_track_tb.nr_stream_part != 1 ||
2451 header->ext_track_tb.et_ent_sz != 32 ||
2452 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION ||
2453 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2454 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2455 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2456 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) ||
2457 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION ||
2458 header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2459 header->dat_fm_tab.fm_tab_ent_cnt !=
2460 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2461 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2468 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt)
2473 char * name = tape_name(STp);
2475 position = osst_get_frame_position(STp, aSRpnt);
2478 STp->header_ok = STp->linux_media = 1;
2479 STp->linux_media_version = 0;
2482 STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2483 STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2484 STp->eod_frame_ppos = STp->first_data_ppos = -1;
2485 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2487 printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2490 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2491 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2493 first = position==10?0xbae: 5;
2494 last = position==10?0xbb3:10;
2496 for (ppos = first; ppos < last; ppos++)
2497 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2500 first = position==10? 5:0xbae;
2501 last = position==10?10:0xbb3;
2503 for (ppos = first; ppos < last; ppos++)
2504 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2508 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2509 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2510 osst_set_frame_position(STp, aSRpnt, 10, 0);
2513 if (position <= STp->first_data_ppos) {
2514 position = STp->first_data_ppos;
2515 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2517 osst_set_frame_position(STp, aSRpnt, position, 0);
2523 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt)
2525 int frame_position = STp->first_frame_position;
2526 int frame_seq_numbr = STp->frame_seq_number;
2527 int logical_blk_num = STp->logical_blk_num;
2528 int halfway_frame = STp->frame_in_buffer;
2529 int read_pointer = STp->buffer->read_pointer;
2530 int prev_mark_ppos = -1;
2531 int actual_mark_ppos, i, n;
2533 char * name = tape_name(STp);
2535 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2537 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2538 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2540 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2544 if (STp->linux_media_version >= 4) {
2545 for (i=0; i<STp->filemark_cnt; i++)
2546 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2549 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2550 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2551 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2552 if (frame_position != STp->first_frame_position ||
2553 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2554 prev_mark_ppos != actual_mark_ppos ) {
2556 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2557 STp->first_frame_position, frame_position,
2558 STp->frame_seq_number + (halfway_frame?0:1),
2559 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2563 if (halfway_frame) {
2564 /* prepare buffer for append and rewrite on top of original */
2565 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2566 STp->buffer->buffer_bytes = read_pointer;
2567 STp->ps[STp->partition].rw = ST_WRITING;
2570 STp->frame_in_buffer = halfway_frame;
2571 STp->frame_seq_number = frame_seq_numbr;
2572 STp->logical_blk_num = logical_blk_num;
2576 /* Acc. to OnStream, the vers. numbering is the following:
2577 * X.XX for released versions (X=digit),
2578 * XXXY for unreleased versions (Y=letter)
2579 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2580 * This fn makes monoton numbers out of this scheme ...
2582 static unsigned int osst_parse_firmware_rev (const char * str)
2584 if (str[1] == '.') {
2585 return (str[0]-'0')*10000
2589 return (str[0]-'0')*10000
2591 +(str[2]-'0')*100 - 100
2597 * Configure the OnStream SCII tape drive for default operation
2599 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
2601 unsigned char cmd[MAX_COMMAND_SIZE];
2602 char * name = tape_name(STp);
2603 struct osst_request * SRpnt = * aSRpnt;
2604 osst_mode_parameter_header_t * header;
2605 osst_block_size_page_t * bs;
2606 osst_capabilities_page_t * cp;
2607 osst_tape_paramtr_page_t * prm;
2608 int drive_buffer_size;
2610 if (STp->ready != ST_READY) {
2612 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2617 if (STp->os_fw_rev < 10600) {
2618 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2619 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2623 * Configure 32.5KB (data+aux) frame size.
2624 * Get the current frame size from the block size mode page
2626 memset(cmd, 0, MAX_COMMAND_SIZE);
2627 cmd[0] = MODE_SENSE;
2629 cmd[2] = BLOCK_SIZE_PAGE;
2630 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2632 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2633 if (SRpnt == NULL) {
2635 printk(OSST_DEB_MSG "osst :D: Busy\n");
2640 if ((STp->buffer)->syscall_result != 0) {
2641 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2645 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2646 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2649 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2650 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No");
2651 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2652 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2656 * Configure default auto columns mode, 32.5KB transfer mode
2664 memset(cmd, 0, MAX_COMMAND_SIZE);
2665 cmd[0] = MODE_SELECT;
2667 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2669 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2671 if ((STp->buffer)->syscall_result != 0) {
2672 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2677 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2679 * In debug mode, we want to see as many errors as possible
2680 * to test the error recovery mechanism.
2682 osst_set_retries(STp, aSRpnt, 0);
2687 * Set vendor name to 'LIN4' for "Linux support version 4".
2690 memset(cmd, 0, MAX_COMMAND_SIZE);
2691 cmd[0] = MODE_SELECT;
2693 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2695 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2696 header->medium_type = 0; /* Medium Type - ignoring */
2697 header->dsp = 0; /* Reserved */
2698 header->bdl = 0; /* Block Descriptor Length */
2700 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2701 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2702 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2703 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2704 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2705 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2706 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2707 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2709 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2712 if ((STp->buffer)->syscall_result != 0) {
2713 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2714 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2718 memset(cmd, 0, MAX_COMMAND_SIZE);
2719 cmd[0] = MODE_SENSE;
2721 cmd[2] = CAPABILITIES_PAGE;
2722 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2724 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2727 if ((STp->buffer)->syscall_result != 0) {
2728 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2732 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2733 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2734 sizeof(osst_mode_parameter_header_t) + header->bdl);
2736 drive_buffer_size = ntohs(cp->buffer_size) / 2;
2738 memset(cmd, 0, MAX_COMMAND_SIZE);
2739 cmd[0] = MODE_SENSE;
2741 cmd[2] = TAPE_PARAMTR_PAGE;
2742 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2744 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2747 if ((STp->buffer)->syscall_result != 0) {
2748 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2752 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2753 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2754 sizeof(osst_mode_parameter_header_t) + header->bdl);
2756 STp->density = prm->density;
2757 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2759 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2760 name, STp->density, STp->capacity / 32, drive_buffer_size);
2768 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2769 it messes up the block number). */
2770 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward)
2773 char * name = tape_name(STp);
2777 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2778 name, forward ? "forward" : "backward");
2782 /* assumes that the filemark is already read by the drive, so this is low cost */
2783 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2786 /* assumes this is only called if we just read the filemark! */
2787 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2790 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2791 name, forward ? "forward" : "backward");
2797 /* Get the tape position. */
2799 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
2801 unsigned char scmd[MAX_COMMAND_SIZE];
2802 struct osst_request * SRpnt;
2804 char * name = tape_name(STp);
2806 /* KG: We want to be able to use it for checking Write Buffer availability
2807 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2809 char * olddata = STp->buffer->b_data;
2810 int oldsize = STp->buffer->buffer_size;
2812 if (STp->ready != ST_READY) return (-EIO);
2814 memset (scmd, 0, MAX_COMMAND_SIZE);
2815 scmd[0] = READ_POSITION;
2817 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2818 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2819 STp->timeout, MAX_RETRIES, 1);
2821 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2826 if (STp->buffer->syscall_result)
2827 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */
2829 if (result == -EINVAL)
2830 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2832 if (result == -EIO) { /* re-read position - this needs to preserve media errors */
2833 unsigned char mysense[16];
2834 memcpy (mysense, SRpnt->sense, 16);
2835 memset (scmd, 0, MAX_COMMAND_SIZE);
2836 scmd[0] = READ_POSITION;
2837 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2838 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2839 STp->timeout, MAX_RETRIES, 1);
2841 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2842 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2843 SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]);
2845 if (!STp->buffer->syscall_result)
2846 memcpy (SRpnt->sense, mysense, 16);
2848 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2850 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2851 + ((STp->buffer)->b_data[5] << 16)
2852 + ((STp->buffer)->b_data[6] << 8)
2853 + (STp->buffer)->b_data[7];
2854 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2855 + ((STp->buffer)->b_data[ 9] << 16)
2856 + ((STp->buffer)->b_data[10] << 8)
2857 + (STp->buffer)->b_data[11];
2858 STp->cur_frames = (STp->buffer)->b_data[15];
2861 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2862 STp->first_frame_position, STp->last_frame_position,
2863 ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2864 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2868 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2870 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2871 STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2873 STp->first_frame_position = STp->last_frame_position;
2876 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2878 return (result == 0 ? STp->first_frame_position : result);
2882 /* Set the tape block */
2883 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip)
2885 unsigned char scmd[MAX_COMMAND_SIZE];
2886 struct osst_request * SRpnt;
2887 struct st_partstat * STps;
2889 int pp = (ppos == 3000 && !skip)? 0 : ppos;
2890 char * name = tape_name(STp);
2892 if (STp->ready != ST_READY) return (-EIO);
2894 STps = &(STp->ps[STp->partition]);
2896 if (ppos < 0 || ppos > STp->capacity) {
2897 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2898 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2905 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2907 memset (scmd, 0, MAX_COMMAND_SIZE);
2910 scmd[3] = (pp >> 24);
2911 scmd[4] = (pp >> 16);
2912 scmd[5] = (pp >> 8);
2917 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
2923 if ((STp->buffer)->syscall_result != 0) {
2925 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
2926 name, STp->first_frame_position, pp);
2931 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
2932 } while ((pp != ppos) && (pp = ppos));
2933 STp->first_frame_position = STp->last_frame_position = ppos;
2934 STps->eof = ST_NOEOF;
2937 STp->frame_in_buffer = 0;
2941 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT)
2943 struct st_partstat * STps = &(STp->ps[STp->partition]);
2946 if (STp->write_type != OS_WRITE_NEW_MARK) {
2947 /* true unless the user wrote the filemark for us */
2948 result = osst_flush_drive_buffer(STp, aSRpnt);
2949 if (result < 0) goto out;
2950 result = osst_write_filemark(STp, aSRpnt);
2951 if (result < 0) goto out;
2953 if (STps->drv_file >= 0)
2955 STps->drv_block = 0;
2957 result = osst_write_eod(STp, aSRpnt);
2958 osst_write_header(STp, aSRpnt, leave_at_EOT);
2965 /* osst versions of st functions - augmented and stripped to suit OnStream only */
2967 /* Flush the write buffer (never need to write if variable blocksize). */
2968 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt)
2970 int offset, transfer, blks = 0;
2972 unsigned char cmd[MAX_COMMAND_SIZE];
2973 struct osst_request * SRpnt = *aSRpnt;
2974 struct st_partstat * STps;
2975 char * name = tape_name(STp);
2977 if ((STp->buffer)->writing) {
2978 if (SRpnt == (STp->buffer)->last_SRpnt)
2980 { printk(OSST_DEB_MSG
2981 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name);
2983 *aSRpnt = SRpnt = NULL;
2987 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name);
2989 osst_write_behind_check(STp);
2990 if ((STp->buffer)->syscall_result) {
2993 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
2994 name, (STp->buffer)->midlevel_result);
2996 if ((STp->buffer)->midlevel_result == INT_MAX)
3003 if (STp->dirty == 1) {
3006 STps = &(STp->ps[STp->partition]);
3007 STps->rw = ST_WRITING;
3008 offset = STp->buffer->buffer_bytes;
3009 blks = (offset + STp->block_size - 1) / STp->block_size;
3010 transfer = OS_FRAME_SIZE;
3012 if (offset < OS_DATA_SIZE)
3013 osst_zero_buffer_tail(STp->buffer);
3016 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
3017 result = osst_recover_wait_frame(STp, aSRpnt, 1);
3019 memset(cmd, 0, MAX_COMMAND_SIZE);
3024 switch (STp->write_type) {
3028 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
3029 name, blks, STp->frame_seq_number,
3030 STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3032 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3033 STp->logical_blk_num - blks, STp->block_size, blks);
3036 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
3037 STp->logical_blk_num, 0, 0);
3039 case OS_WRITE_NEW_MARK:
3040 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
3041 STp->logical_blk_num++, 0, blks=1);
3043 case OS_WRITE_HEADER:
3044 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
3046 default: /* probably FILLER */
3047 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
3051 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
3052 name, offset, transfer, blks);
3055 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3056 STp->timeout, MAX_RETRIES, 1);
3061 if ((STp->buffer)->syscall_result != 0) {
3064 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3065 name, SRpnt->sense[0], SRpnt->sense[2],
3066 SRpnt->sense[12], SRpnt->sense[13]);
3068 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3069 (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3070 (SRpnt->sense[2] & 0x0f) == NO_SENSE) {
3072 (STp->buffer)->buffer_bytes = 0;
3076 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3077 printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3081 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
3084 STp->first_frame_position++;
3086 (STp->buffer)->buffer_bytes = 0;
3090 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3096 /* Flush the tape buffer. The tape will be positioned correctly unless
3097 seek_next is true. */
3098 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next)
3100 struct st_partstat * STps;
3101 int backspace = 0, result = 0;
3103 char * name = tape_name(STp);
3107 * If there was a bus reset, block further access
3110 if( STp->pos_unknown)
3113 if (STp->ready != ST_READY)
3116 STps = &(STp->ps[STp->partition]);
3117 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
3118 STp->write_type = OS_WRITE_DATA;
3119 return osst_flush_write_buffer(STp, aSRpnt);
3121 if (STp->block_size == 0)
3125 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3128 if (!STp->can_bsr) {
3129 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3130 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3131 (STp->buffer)->buffer_bytes = 0;
3132 (STp->buffer)->read_pointer = 0;
3133 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3137 if (STps->eof == ST_FM_HIT) {
3138 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3140 STps->eof = ST_NOEOF;
3142 if (STps->drv_file >= 0)
3144 STps->drv_block = 0;
3147 if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3148 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3150 else if (STps->eof == ST_FM_HIT) {
3151 if (STps->drv_file >= 0)
3153 STps->drv_block = 0;
3154 STps->eof = ST_NOEOF;
3160 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous)
3162 unsigned char cmd[MAX_COMMAND_SIZE];
3163 struct osst_request * SRpnt;
3166 char * name = tape_name(STp);
3169 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3171 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3173 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3176 /* error recovery may have bumped us past the header partition */
3177 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3179 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3181 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3186 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3187 if (osst_recover_wait_frame(STp, aSRpnt, 1))
3190 // osst_build_stats(STp, &SRpnt);
3192 STp->ps[STp->partition].rw = ST_WRITING;
3193 STp->write_type = OS_WRITE_DATA;
3195 memset(cmd, 0, MAX_COMMAND_SIZE);
3198 cmd[4] = 1; /* one frame at a time... */
3199 blks = STp->buffer->buffer_bytes / STp->block_size;
3202 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3203 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3205 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3206 STp->logical_blk_num - blks, STp->block_size, blks);
3210 STp->write_pending = 1;
3212 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3213 MAX_RETRIES, synchronous);
3219 if (STp->buffer->syscall_result != 0) {
3222 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3224 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3225 (SRpnt->sense[2] & 0x40)) {
3226 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW)
3230 if (osst_write_error_recovery(STp, aSRpnt, 1))
3235 STp->first_frame_position++;
3243 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */
3244 static int do_door_lock(struct osst_tape * STp, int do_lock)
3248 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
3250 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3252 retval = scsi_ioctl(STp->device, cmd, NULL);
3254 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3257 STp->door_locked = ST_LOCK_FAILS;
3262 /* Set the internal state after reset */
3263 static void reset_state(struct osst_tape *STp)
3266 struct st_partstat *STps;
3268 STp->pos_unknown = 0;
3269 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3270 STps = &(STp->ps[i]);
3272 STps->eof = ST_NOEOF;
3274 STps->last_block_valid = 0;
3275 STps->drv_block = -1;
3276 STps->drv_file = -1;
3281 /* Entry points to osst */
3284 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3286 ssize_t total, retval = 0;
3287 ssize_t i, do_count, blks, transfer;
3288 int write_threshold;
3289 int doing_write = 0;
3290 const char __user * b_point;
3291 struct osst_request * SRpnt = NULL;
3292 struct st_modedef * STm;
3293 struct st_partstat * STps;
3294 struct osst_tape * STp = filp->private_data;
3295 char * name = tape_name(STp);
3298 if (down_interruptible(&STp->lock))
3299 return (-ERESTARTSYS);
3302 * If we are in the middle of error recovery, don't let anyone
3303 * else try and use this device. Also, if error recovery fails, it
3304 * may try and take the device offline, in which case all further
3305 * access to the device is prohibited.
3307 if( !scsi_block_when_processing_errors(STp->device) ) {
3312 if (STp->ready != ST_READY) {
3313 if (STp->ready == ST_NO_TAPE)
3314 retval = (-ENOMEDIUM);
3319 STm = &(STp->modes[STp->current_mode]);
3320 if (!STm->defined) {
3328 * If there was a bus reset, block further access
3331 if (STp->pos_unknown) {
3338 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3344 if (STp->write_prot) {
3349 /* Write must be integral number of blocks */
3350 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3351 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3352 name, count, STp->block_size<1024?
3353 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3358 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3359 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3360 name, STp->first_frame_position);
3365 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3366 STp->door_locked = ST_LOCKED_AUTO;
3368 STps = &(STp->ps[STp->partition]);
3370 if (STps->rw == ST_READING) {
3372 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3373 STps->drv_file, STps->drv_block);
3375 retval = osst_flush_buffer(STp, &SRpnt, 0);
3380 if (STps->rw != ST_WRITING) {
3381 /* Are we totally rewriting this tape? */
3382 if (!STp->header_ok ||
3383 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3384 (STps->drv_file == 0 && STps->drv_block == 0)) {
3385 STp->wrt_pass_cntr++;
3387 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3388 name, STp->wrt_pass_cntr);
3390 osst_reset_header(STp, &SRpnt);
3391 STps->drv_file = STps->drv_block = 0;
3393 /* Do we know where we'll be writing on the tape? */
3395 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3396 STps->drv_file < 0 || STps->drv_block < 0) {
3397 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3398 STps->drv_file = STp->filemark_cnt;
3399 STps->drv_block = 0;
3402 /* We have no idea where the tape is positioned - give up */
3405 "%s:D: Cannot write at indeterminate position.\n", name);
3411 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3412 STp->filemark_cnt = STps->drv_file;
3413 STp->last_mark_ppos =
3414 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3416 "%s:W: Overwriting file %d with old write pass counter %d\n",
3417 name, STps->drv_file, STp->wrt_pass_cntr);
3419 "%s:W: may lead to stale data being accepted on reading back!\n",
3423 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3424 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3430 if (!STp->header_ok) {
3432 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3438 if ((STp->buffer)->writing) {
3439 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3440 osst_write_behind_check(STp);
3441 if ((STp->buffer)->syscall_result) {
3444 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3445 (STp->buffer)->midlevel_result);
3447 if ((STp->buffer)->midlevel_result == INT_MAX)
3448 STps->eof = ST_EOM_OK;
3450 STps->eof = ST_EOM_ERROR;
3453 if (STps->eof == ST_EOM_OK) {
3457 else if (STps->eof == ST_EOM_ERROR) {
3462 /* Check the buffer readability in cases where copy_user might catch
3463 the problems after some tape movement. */
3464 if ((copy_from_user(&i, buf, 1) != 0 ||
3465 copy_from_user(&i, buf + count - 1, 1) != 0)) {
3470 if (!STm->do_buffer_writes) {
3471 write_threshold = 1;
3474 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3475 if (!STm->do_async_writes)
3481 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3482 name, (int) count, STps->drv_file, STps->drv_block,
3483 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3486 while ((STp->buffer)->buffer_bytes + count > write_threshold)
3489 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3490 (STp->buffer)->buffer_bytes;
3491 if (do_count > count)
3494 i = append_to_buffer(b_point, STp->buffer, do_count);
3500 blks = do_count / STp->block_size;
3501 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3503 i = osst_write_frame(STp, &SRpnt, 1);
3505 if (i == (-ENOSPC)) {
3506 transfer = STp->buffer->writing; /* FIXME -- check this logic */
3507 if (transfer <= do_count) {
3508 filp->f_pos += do_count - transfer;
3509 count -= do_count - transfer;
3510 if (STps->drv_block >= 0) {
3511 STps->drv_block += (do_count - transfer) / STp->block_size;
3513 STps->eof = ST_EOM_OK;
3514 retval = (-ENOSPC); /* EOM within current request */
3517 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3518 name, (int) transfer);
3522 STps->eof = ST_EOM_ERROR;
3523 STps->drv_block = (-1); /* Too cautious? */
3524 retval = (-EIO); /* EOM for old data */
3527 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3535 if (SRpnt != NULL) {
3536 osst_release_request(SRpnt);
3539 STp->buffer->buffer_bytes = 0;
3542 retval = total - count;
3546 filp->f_pos += do_count;
3547 b_point += do_count;
3549 if (STps->drv_block >= 0) {
3550 STps->drv_block += blks;
3552 STp->buffer->buffer_bytes = 0;
3554 } /* end while write threshold exceeded */
3558 i = append_to_buffer(b_point, STp->buffer, count);
3563 blks = count / STp->block_size;
3564 STp->logical_blk_num += blks;
3565 if (STps->drv_block >= 0) {
3566 STps->drv_block += blks;
3568 filp->f_pos += count;
3572 if (doing_write && (STp->buffer)->syscall_result != 0) {
3573 retval = (STp->buffer)->syscall_result;
3577 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3578 /* Schedule an asynchronous write */
3579 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3580 STp->block_size) * STp->block_size;
3581 STp->dirty = !((STp->buffer)->writing ==
3582 (STp->buffer)->buffer_bytes);
3584 i = osst_write_frame(STp, &SRpnt, 0);
3589 SRpnt = NULL; /* Prevent releasing this request! */
3591 STps->at_sm &= (total == 0);
3593 STps->eof = ST_NOEOF;
3598 if (SRpnt != NULL) osst_release_request(SRpnt);
3607 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3609 ssize_t total, retval = 0;
3610 ssize_t i, transfer;
3612 struct st_modedef * STm;
3613 struct st_partstat * STps;
3614 struct osst_request * SRpnt = NULL;
3615 struct osst_tape * STp = filp->private_data;
3616 char * name = tape_name(STp);
3619 if (down_interruptible(&STp->lock))
3620 return (-ERESTARTSYS);
3623 * If we are in the middle of error recovery, don't let anyone
3624 * else try and use this device. Also, if error recovery fails, it
3625 * may try and take the device offline, in which case all further
3626 * access to the device is prohibited.
3628 if( !scsi_block_when_processing_errors(STp->device) ) {
3633 if (STp->ready != ST_READY) {
3634 if (STp->ready == ST_NO_TAPE)
3635 retval = (-ENOMEDIUM);
3640 STm = &(STp->modes[STp->current_mode]);
3641 if (!STm->defined) {
3647 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3652 /* Must have initialized medium */
3653 if (!STp->header_ok) {
3658 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3659 STp->door_locked = ST_LOCKED_AUTO;
3661 STps = &(STp->ps[STp->partition]);
3662 if (STps->rw == ST_WRITING) {
3663 retval = osst_flush_buffer(STp, &SRpnt, 0);
3667 /* FIXME -- this may leave the tape without EOD and up2date headers */
3670 if ((count % STp->block_size) != 0) {
3672 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3673 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3677 if (debugging && STps->eof != ST_NOEOF)
3678 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3679 STps->eof, (STp->buffer)->buffer_bytes);
3681 if ((STp->buffer)->buffer_bytes == 0 &&
3682 STps->eof >= ST_EOD_1) {
3683 if (STps->eof < ST_EOD) {
3688 retval = (-EIO); /* EOM or Blank Check */
3692 /* Check the buffer writability before any tape movement. Don't alter
3694 if (copy_from_user(&i, buf, 1) != 0 ||
3695 copy_to_user (buf, &i, 1) != 0 ||
3696 copy_from_user(&i, buf + count - 1, 1) != 0 ||
3697 copy_to_user (buf + count - 1, &i, 1) != 0) {
3702 /* Loop until enough data in buffer or a special condition found */
3703 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3705 /* Get new data if the buffer is empty */
3706 if ((STp->buffer)->buffer_bytes == 0) {
3707 if (STps->eof == ST_FM_HIT)
3709 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3710 if (special < 0) { /* No need to continue read */
3711 STp->frame_in_buffer = 0;
3717 /* Move the data from driver buffer to user buffer */
3718 if ((STp->buffer)->buffer_bytes > 0) {
3720 if (debugging && STps->eof != ST_NOEOF)
3721 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3722 STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total));
3724 /* force multiple of block size, note block_size may have been adjusted */
3725 transfer = (((STp->buffer)->buffer_bytes < count - total ?
3726 (STp->buffer)->buffer_bytes : count - total)/
3727 STp->block_size) * STp->block_size;
3729 if (transfer == 0) {
3731 "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
3732 name, count, STp->block_size < 1024?
3733 STp->block_size:STp->block_size/1024,
3734 STp->block_size<1024?'b':'k');
3737 i = from_buffer(STp->buffer, buf, transfer);
3742 STp->logical_blk_num += transfer / STp->block_size;
3743 STps->drv_block += transfer / STp->block_size;
3744 filp->f_pos += transfer;
3749 if ((STp->buffer)->buffer_bytes == 0) {
3752 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3753 name, STp->frame_seq_number);
3755 STp->frame_in_buffer = 0;
3756 STp->frame_seq_number++; /* frame to look for next time */
3758 } /* for (total = 0, special = 0; total < count && !special; ) */
3760 /* Change the eof state if no data from tape or buffer */
3762 if (STps->eof == ST_FM_HIT) {
3763 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3764 STps->drv_block = 0;
3765 if (STps->drv_file >= 0)
3768 else if (STps->eof == ST_EOD_1) {
3769 STps->eof = ST_EOD_2;
3770 if (STps->drv_block > 0 && STps->drv_file >= 0)
3772 STps->drv_block = 0;
3774 else if (STps->eof == ST_EOD_2)
3777 else if (STps->eof == ST_FM)
3778 STps->eof = ST_NOEOF;
3783 if (SRpnt != NULL) osst_release_request(SRpnt);
3791 /* Set the driver options */
3792 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3795 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3796 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3797 STm->do_read_ahead);
3799 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3800 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3802 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3803 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3804 STp->scsi2_logical);
3806 "%s:I: sysv: %d\n", name, STm->sysv);
3809 "%s:D: debugging: %d\n",
3815 static int osst_set_options(struct osst_tape *STp, long options)
3819 struct st_modedef * STm;
3820 char * name = tape_name(STp);
3822 STm = &(STp->modes[STp->current_mode]);
3823 if (!STm->defined) {
3824 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3828 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3829 name, STp->current_mode);
3833 code = options & MT_ST_OPTIONS;
3834 if (code == MT_ST_BOOLEANS) {
3835 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3836 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3837 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3838 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3839 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3840 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3841 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3842 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3843 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3844 if ((STp->device)->scsi_level >= SCSI_2)
3845 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3846 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3847 STm->sysv = (options & MT_ST_SYSV) != 0;
3849 debugging = (options & MT_ST_DEBUGGING) != 0;
3851 osst_log_options(STp, STm, name);
3853 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3854 value = (code == MT_ST_SETBOOLEANS);
3855 if ((options & MT_ST_BUFFER_WRITES) != 0)
3856 STm->do_buffer_writes = value;
3857 if ((options & MT_ST_ASYNC_WRITES) != 0)
3858 STm->do_async_writes = value;
3859 if ((options & MT_ST_DEF_WRITES) != 0)
3860 STm->defaults_for_writes = value;
3861 if ((options & MT_ST_READ_AHEAD) != 0)
3862 STm->do_read_ahead = value;
3863 if ((options & MT_ST_TWO_FM) != 0)
3864 STp->two_fm = value;
3865 if ((options & MT_ST_FAST_MTEOM) != 0)
3866 STp->fast_mteom = value;
3867 if ((options & MT_ST_AUTO_LOCK) != 0)
3868 STp->do_auto_lock = value;
3869 if ((options & MT_ST_CAN_BSR) != 0)
3870 STp->can_bsr = value;
3871 if ((options & MT_ST_NO_BLKLIMS) != 0)
3872 STp->omit_blklims = value;
3873 if ((STp->device)->scsi_level >= SCSI_2 &&
3874 (options & MT_ST_CAN_PARTITIONS) != 0)
3875 STp->can_partitions = value;
3876 if ((options & MT_ST_SCSI2LOGICAL) != 0)
3877 STp->scsi2_logical = value;
3878 if ((options & MT_ST_SYSV) != 0)
3881 if ((options & MT_ST_DEBUGGING) != 0)
3884 osst_log_options(STp, STm, name);
3886 else if (code == MT_ST_WRITE_THRESHOLD) {
3887 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3888 if (value < 1 || value > osst_buffer_size) {
3889 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3893 STp->write_threshold = value;
3894 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3897 else if (code == MT_ST_DEF_BLKSIZE) {
3898 value = (options & ~MT_ST_OPTIONS);
3899 if (value == ~MT_ST_OPTIONS) {
3900 STm->default_blksize = (-1);
3901 printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3904 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3905 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3909 STm->default_blksize = value;
3910 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
3911 name, STm->default_blksize);
3914 else if (code == MT_ST_TIMEOUTS) {
3915 value = (options & ~MT_ST_OPTIONS);
3916 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
3917 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
3918 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
3919 (value & ~MT_ST_SET_LONG_TIMEOUT));
3922 STp->timeout = value * HZ;
3923 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
3926 else if (code == MT_ST_DEF_OPTIONS) {
3927 code = (options & ~MT_ST_CLEAR_DEFAULT);
3928 value = (options & MT_ST_CLEAR_DEFAULT);
3929 if (code == MT_ST_DEF_DENSITY) {
3930 if (value == MT_ST_CLEAR_DEFAULT) {
3931 STm->default_density = (-1);
3932 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
3935 STm->default_density = value & 0xff;
3936 printk(KERN_INFO "%s:I: Density default set to %x\n",
3937 name, STm->default_density);
3940 else if (code == MT_ST_DEF_DRVBUFFER) {
3941 if (value == MT_ST_CLEAR_DEFAULT) {
3942 STp->default_drvbuffer = 0xff;
3943 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
3946 STp->default_drvbuffer = value & 7;
3947 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
3948 name, STp->default_drvbuffer);
3951 else if (code == MT_ST_DEF_COMPRESSION) {
3952 if (value == MT_ST_CLEAR_DEFAULT) {
3953 STm->default_compression = ST_DONT_TOUCH;
3954 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
3957 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
3958 printk(KERN_INFO "%s:I: Compression default set to %x\n",
3970 /* Internal ioctl function */
3971 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt,
3972 unsigned int cmd_in, unsigned long arg)
3976 int i, ioctl_result;
3978 unsigned char cmd[MAX_COMMAND_SIZE];
3979 struct osst_request * SRpnt = * aSRpnt;
3980 struct st_partstat * STps;
3981 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
3982 int datalen = 0, direction = DMA_NONE;
3983 char * name = tape_name(STp);
3985 if (STp->ready != ST_READY && cmd_in != MTLOAD) {
3986 if (STp->ready == ST_NO_TAPE)
3987 return (-ENOMEDIUM);
3991 timeout = STp->long_timeout;
3992 STps = &(STp->ps[STp->partition]);
3993 fileno = STps->drv_file;
3994 blkno = STps->drv_block;
3995 at_sm = STps->at_sm;
3996 frame_seq_numbr = STp->frame_seq_number;
3997 logical_blk_num = STp->logical_blk_num;
3999 memset(cmd, 0, MAX_COMMAND_SIZE);
4002 chg_eof = 0; /* Changed from the FSF after this */
4006 if (STp->linux_media)
4007 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
4009 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
4013 at_sm &= (arg == 0);
4017 chg_eof = 0; /* Changed from the FSF after this */
4021 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
4024 blkno = (-1); /* We can't know the block number */
4025 at_sm &= (arg == 0);
4032 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
4033 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
4035 if (cmd_in == MTFSR) {
4036 logical_blk_num += arg;
4037 if (blkno >= 0) blkno += arg;
4040 logical_blk_num -= arg;
4041 if (blkno >= 0) blkno -= arg;
4043 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
4044 fileno = STps->drv_file;
4045 blkno = STps->drv_block;
4046 at_sm &= (arg == 0);
4051 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4052 cmd[2] = (arg >> 16);
4053 cmd[3] = (arg >> 8);
4057 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4058 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4061 blkno = fileno = (-1);
4067 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4069 cmd[2] = (ltmp >> 16);
4070 cmd[3] = (ltmp >> 8);
4076 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4077 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4082 blkno = fileno = (-1);
4087 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4088 STp->write_type = OS_WRITE_DATA;
4089 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4094 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4096 for (i=0; i<arg; i++)
4097 ioctl_result |= osst_write_filemark(STp, &SRpnt);
4098 if (fileno >= 0) fileno += arg;
4099 if (blkno >= 0) blkno = 0;
4103 if (STp->write_prot)
4107 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
4108 if (cmd_in == MTWSM)
4110 cmd[2] = (arg >> 16);
4111 cmd[3] = (arg >> 8);
4113 timeout = STp->timeout;
4116 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4117 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4122 at_sm = (cmd_in == MTWSM);
4128 cmd[0] = START_STOP;
4129 cmd[1] = 1; /* Don't wait for completion */
4130 if (cmd_in == MTLOAD) {
4131 if (STp->ready == ST_NO_TAPE)
4132 cmd[4] = 4; /* open tray */
4134 cmd[4] = 1; /* load */
4136 if (cmd_in == MTRETEN)
4137 cmd[4] = 3; /* retension then mount */
4138 if (cmd_in == MTOFFL)
4139 cmd[4] = 4; /* rewind then eject */
4140 timeout = STp->timeout;
4145 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4148 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4151 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4154 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4159 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4164 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4166 return 0; /* Should do something ? */
4171 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4173 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4174 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4175 ioctl_result = -EIO;
4178 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4180 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4182 ioctl_result = -EIO;
4185 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4186 fileno = STp->filemark_cnt;
4191 if (STp->write_prot)
4193 ioctl_result = osst_reset_header(STp, &SRpnt);
4194 i = osst_write_eod(STp, &SRpnt);
4195 if (i < ioctl_result) ioctl_result = i;
4196 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4197 if (i < ioctl_result) ioctl_result = i;
4198 fileno = blkno = at_sm = 0 ;
4202 cmd[0] = REZERO_UNIT; /* rewind */
4206 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4208 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4211 case MTSETBLK: /* Set block length */
4212 if ((STps->drv_block == 0 ) &&
4214 ((STp->buffer)->buffer_bytes == 0) &&
4215 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4216 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4217 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4219 * Only allowed to change the block size if you opened the
4220 * device at the beginning of a file before writing anything.
4221 * Note, that when reading, changing block_size is futile,
4222 * as the size used when writing overrides it.
4224 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4225 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4226 name, STp->block_size);
4229 case MTSETDENSITY: /* Set tape density */
4230 case MTSETDRVBUFFER: /* Set drive buffering */
4231 case SET_DENS_AND_BLK: /* Set density and block size */
4233 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4234 return (-EIO); /* Not allowed if data in buffer */
4235 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4236 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4237 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4238 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4239 name, (int)(arg & MT_ST_BLKSIZE_MASK),
4240 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4243 return 0; /* FIXME silently ignore if block size didn't change */
4249 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4251 ioctl_result = (STp->buffer)->syscall_result;
4255 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4257 return ioctl_result;
4260 if (!ioctl_result) { /* SCSI command successful */
4261 STp->frame_seq_number = frame_seq_numbr;
4262 STp->logical_blk_num = logical_blk_num;
4268 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4271 if (!ioctl_result) { /* success */
4273 if (cmd_in == MTFSFM) {
4277 if (cmd_in == MTBSFM) {
4281 STps->drv_block = blkno;
4282 STps->drv_file = fileno;
4283 STps->at_sm = at_sm;
4285 if (cmd_in == MTEOM)
4287 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4288 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4290 STp->logical_blk_num++;
4291 STp->frame_seq_number++;
4292 STp->frame_in_buffer = 0;
4293 STp->buffer->read_pointer = 0;
4295 else if (cmd_in == MTFSF)
4296 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4298 STps->eof = ST_NOEOF;
4300 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4301 STp->rew_at_close = 0;
4302 else if (cmd_in == MTLOAD) {
4303 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4304 STp->ps[i].rw = ST_IDLE;
4305 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4310 if (cmd_in == MTREW) {
4311 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4312 if (ioctl_result > 0)
4316 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4317 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4318 STps->drv_file = STps->drv_block = -1;
4320 STps->drv_file = STps->drv_block = 0;
4321 STps->eof = ST_NOEOF;
4322 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4323 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4324 STps->drv_file = STps->drv_block = -1;
4326 STps->drv_file = STp->filemark_cnt;
4327 STps->drv_block = 0;
4330 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4331 STps->drv_file = STps->drv_block = (-1);
4332 STps->eof = ST_NOEOF;
4334 } else if (cmd_in == MTERASE) {
4336 } else if (SRpnt) { /* SCSI command was not completely successful. */
4337 if (SRpnt->sense[2] & 0x40) {
4338 STps->eof = ST_EOM_OK;
4339 STps->drv_block = 0;
4342 STps->eof = ST_NOEOF;
4344 if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK)
4347 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4348 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4352 return ioctl_result;
4356 /* Open the device */
4357 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4359 unsigned short flags;
4360 int i, b_size, new_session = 0, retval = 0;
4361 unsigned char cmd[MAX_COMMAND_SIZE];
4362 struct osst_request * SRpnt = NULL;
4363 struct osst_tape * STp;
4364 struct st_modedef * STm;
4365 struct st_partstat * STps;
4367 int dev = TAPE_NR(inode);
4368 int mode = TAPE_MODE(inode);
4371 * We really want to do nonseekable_open(inode, filp); here, but some
4372 * versions of tar incorrectly call lseek on tapes and bail out if that
4373 * fails. So we disallow pread() and pwrite(), but permit lseeks.
4375 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
4377 write_lock(&os_scsi_tapes_lock);
4378 if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4379 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4380 write_unlock(&os_scsi_tapes_lock);
4384 name = tape_name(STp);
4387 write_unlock(&os_scsi_tapes_lock);
4389 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4393 if (scsi_device_get(STp->device)) {
4394 write_unlock(&os_scsi_tapes_lock);
4396 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4400 filp->private_data = STp;
4402 write_unlock(&os_scsi_tapes_lock);
4403 STp->rew_at_close = TAPE_REWIND(inode);
4405 if( !scsi_block_when_processing_errors(STp->device) ) {
4409 if (mode != STp->current_mode) {
4412 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4413 name, STp->current_mode, mode);
4416 STp->current_mode = mode;
4418 STm = &(STp->modes[STp->current_mode]);
4420 flags = filp->f_flags;
4421 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4423 STp->raw = TAPE_IS_RAW(inode);
4427 /* Allocate data segments for this device's tape buffer */
4428 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4429 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4430 retval = (-EOVERFLOW);
4433 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4434 for (i = 0, b_size = 0;
4435 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4436 b_size += STp->buffer->sg[i++].length);
4437 STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
4439 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4440 STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4441 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4442 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4445 STp->buffer->aux = NULL; /* this had better never happen! */
4446 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4450 STp->buffer->writing = 0;
4451 STp->buffer->syscall_result = 0;
4453 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4454 STps = &(STp->ps[i]);
4457 STp->ready = ST_READY;
4459 STp->nbr_waits = STp->nbr_finished = 0;
4462 memset (cmd, 0, MAX_COMMAND_SIZE);
4463 cmd[0] = TEST_UNIT_READY;
4465 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4467 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
4470 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4471 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4472 SRpnt->sense[12] == 4 ) {
4474 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]);
4476 if (filp->f_flags & O_NONBLOCK) {
4480 if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */
4481 memset (cmd, 0, MAX_COMMAND_SIZE);
4482 cmd[0] = START_STOP;
4485 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4486 STp->timeout, MAX_RETRIES, 1);
4488 osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
4490 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4491 (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4493 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4497 for (i=0; i < 10; i++) {
4499 memset (cmd, 0, MAX_COMMAND_SIZE);
4500 cmd[0] = TEST_UNIT_READY;
4502 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4503 STp->timeout, MAX_RETRIES, 1);
4504 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4505 (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
4509 STp->pos_unknown = 0;
4510 STp->partition = STp->new_partition = 0;
4511 if (STp->can_partitions)
4512 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4513 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4514 STps = &(STp->ps[i]);
4515 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4516 STps->eof = ST_NOEOF;
4518 STps->last_block_valid = 0;
4519 STps->drv_block = 0;
4520 STps->drv_file = 0 ;
4523 STp->recover_count = 0;
4524 STp->abort_count = 0;
4527 * if we have valid headers from before, and the drive/tape seem untouched,
4528 * open without reconfiguring and re-reading the headers
4530 if (!STp->buffer->syscall_result && STp->header_ok &&
4531 !SRpnt->result && SRpnt->sense[0] == 0) {
4533 memset(cmd, 0, MAX_COMMAND_SIZE);
4534 cmd[0] = MODE_SENSE;
4536 cmd[2] = VENDOR_IDENT_PAGE;
4537 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4539 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4541 if (STp->buffer->syscall_result ||
4542 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4543 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4544 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4545 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4547 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4548 STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4549 STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4550 STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4551 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4555 i = STp->first_frame_position;
4556 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4557 if (STp->door_locked == ST_UNLOCKED) {
4558 if (do_door_lock(STp, 1))
4559 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4561 STp->door_locked = ST_LOCKED_AUTO;
4563 if (!STp->frame_in_buffer) {
4564 STp->block_size = (STm->default_blksize > 0) ?
4565 STm->default_blksize : OS_DATA_SIZE;
4566 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4568 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4570 osst_release_request(SRpnt);
4574 if (i != STp->first_frame_position)
4575 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4576 name, i, STp->first_frame_position);
4582 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4583 (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) {
4585 memset(cmd, 0, MAX_COMMAND_SIZE);
4586 cmd[0] = MODE_SELECT;
4588 cmd[4] = 4 + MODE_HEADER_LENGTH;
4590 (STp->buffer)->b_data[0] = cmd[4] - 1;
4591 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4592 (STp->buffer)->b_data[2] = 0; /* Reserved */
4593 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4594 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4595 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4596 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4597 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4600 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4602 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4606 for (i=0; i < 10; i++) {
4608 memset (cmd, 0, MAX_COMMAND_SIZE);
4609 cmd[0] = TEST_UNIT_READY;
4611 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4612 STp->timeout, MAX_RETRIES, 1);
4613 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4614 (SRpnt->sense[2] & 0x0f) == NOT_READY)
4617 if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
4618 STp->pos_unknown = 0;
4619 STp->partition = STp->new_partition = 0;
4620 if (STp->can_partitions)
4621 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4622 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4623 STps = &(STp->ps[i]);
4625 STps->eof = ST_NOEOF;
4627 STps->last_block_valid = 0;
4628 STps->drv_block = 0;
4629 STps->drv_file = 0 ;
4636 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4637 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4639 if ((STp->buffer)->syscall_result != 0) {
4640 if ((STp->device)->scsi_level >= SCSI_2 &&
4641 (SRpnt->sense[0] & 0x70) == 0x70 &&
4642 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4643 SRpnt->sense[12] == 0x3a) { /* Check ASC */
4644 STp->ready = ST_NO_TAPE;
4646 STp->ready = ST_NOT_READY;
4647 osst_release_request(SRpnt);
4649 STp->density = 0; /* Clear the erroneous "residue" */
4650 STp->write_prot = 0;
4651 STp->block_size = 0;
4652 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4653 STp->partition = STp->new_partition = 0;
4654 STp->door_locked = ST_UNLOCKED;
4658 osst_configure_onstream(STp, &SRpnt);
4660 STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4661 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4662 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4663 STp->buffer->buffer_bytes =
4664 STp->buffer->read_pointer =
4665 STp->frame_in_buffer = 0;
4669 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4670 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4671 (STp->buffer)->buffer_blocks);
4674 if (STp->drv_write_prot) {
4675 STp->write_prot = 1;
4678 printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4680 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4686 if (new_session) { /* Change the drive parameters for the new mode */
4689 printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4691 STp->density_changed = STp->blksize_changed = 0;
4692 STp->compression_changed = 0;
4696 * properly position the tape and check the ADR headers
4698 if (STp->door_locked == ST_UNLOCKED) {
4699 if (do_door_lock(STp, 1))
4700 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4702 STp->door_locked = ST_LOCKED_AUTO;
4705 osst_analyze_headers(STp, &SRpnt);
4707 osst_release_request(SRpnt);
4714 osst_release_request(SRpnt);
4715 normalize_buffer(STp->buffer);
4718 scsi_device_put(STp->device);
4724 /* Flush the tape buffer before close */
4725 static int os_scsi_tape_flush(struct file * filp)
4727 int result = 0, result2;
4728 struct osst_tape * STp = filp->private_data;
4729 struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4730 struct st_partstat * STps = &(STp->ps[STp->partition]);
4731 struct osst_request * SRpnt = NULL;
4732 char * name = tape_name(STp);
4734 if (file_count(filp) > 1)
4737 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4738 STp->write_type = OS_WRITE_DATA;
4739 result = osst_flush_write_buffer(STp, &SRpnt);
4740 if (result != 0 && result != (-ENOSPC))
4743 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4747 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4748 name, (long)(filp->f_pos));
4749 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4750 name, STp->nbr_waits, STp->nbr_finished);
4753 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4756 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4757 name, 1+STp->two_fm);
4760 else if (!STp->rew_at_close) {
4761 STps = &(STp->ps[STp->partition]);
4762 if (!STm->sysv || STps->rw != ST_READING) {
4764 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4765 else if (STps->eof == ST_FM_HIT) {
4766 result = cross_eof(STp, &SRpnt, 0);
4768 if (STps->drv_file >= 0)
4770 STps->drv_block = 0;
4774 STps->eof = ST_NOEOF;
4777 else if ((STps->eof == ST_NOEOF &&
4778 !(result = cross_eof(STp, &SRpnt, 1))) ||
4779 STps->eof == ST_FM_HIT) {
4780 if (STps->drv_file >= 0)
4782 STps->drv_block = 0;
4788 if (STp->rew_at_close) {
4789 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4790 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4791 if (result == 0 && result2 < 0)
4794 if (SRpnt) osst_release_request(SRpnt);
4796 if (STp->abort_count || STp->recover_count) {
4797 printk(KERN_INFO "%s:I:", name);
4798 if (STp->abort_count)
4799 printk(" %d unrecovered errors", STp->abort_count);
4800 if (STp->recover_count)
4801 printk(" %d recovered errors", STp->recover_count);
4802 if (STp->write_count)
4803 printk(" in %d frames written", STp->write_count);
4804 if (STp->read_count)
4805 printk(" in %d frames read", STp->read_count);
4807 STp->recover_count = 0;
4808 STp->abort_count = 0;
4810 STp->write_count = 0;
4811 STp->read_count = 0;
4817 /* Close the device and release it */
4818 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4821 struct osst_tape * STp = filp->private_data;
4823 if (STp->door_locked == ST_LOCKED_AUTO)
4824 do_door_lock(STp, 0);
4829 normalize_buffer(STp->buffer);
4830 write_lock(&os_scsi_tapes_lock);
4832 write_unlock(&os_scsi_tapes_lock);
4834 scsi_device_put(STp->device);
4840 /* The ioctl command */
4841 static int osst_ioctl(struct inode * inode,struct file * file,
4842 unsigned int cmd_in, unsigned long arg)
4844 int i, cmd_nr, cmd_type, retval = 0;
4846 struct st_modedef * STm;
4847 struct st_partstat * STps;
4848 struct osst_request * SRpnt = NULL;
4849 struct osst_tape * STp = file->private_data;
4850 char * name = tape_name(STp);
4851 void __user * p = (void __user *)arg;
4853 if (down_interruptible(&STp->lock))
4854 return -ERESTARTSYS;
4857 if (debugging && !STp->in_use) {
4858 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4863 STm = &(STp->modes[STp->current_mode]);
4864 STps = &(STp->ps[STp->partition]);
4867 * If we are in the middle of error recovery, don't let anyone
4868 * else try and use this device. Also, if error recovery fails, it
4869 * may try and take the device offline, in which case all further
4870 * access to the device is prohibited.
4872 if( !scsi_block_when_processing_errors(STp->device) ) {
4877 cmd_type = _IOC_TYPE(cmd_in);
4878 cmd_nr = _IOC_NR(cmd_in);
4880 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4881 cmd_type, cmd_nr, STp->raw?"raw":"normal");
4883 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4887 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
4892 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
4898 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
4899 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
4904 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
4909 if (!STp->pos_unknown) {
4911 if (STps->eof == ST_FM_HIT) {
4912 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
4914 if (STps->drv_file >= 0)
4915 STps->drv_file += 1;
4917 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
4919 if (STps->drv_file >= 0)
4920 STps->drv_file += 1;
4924 if (mtc.mt_op == MTSEEK) {
4925 /* Old position must be restored if partition will be changed */
4926 i = !STp->can_partitions || (STp->new_partition != STp->partition);
4929 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
4930 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
4931 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
4932 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
4933 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
4934 mtc.mt_op == MTCOMPRESSION;
4936 i = osst_flush_buffer(STp, &SRpnt, i);
4944 * If there was a bus reset, block further access
4945 * to this device. If the user wants to rewind the tape,
4946 * then reset the flag and allow access again.
4948 if(mtc.mt_op != MTREW &&
4949 mtc.mt_op != MTOFFL &&
4950 mtc.mt_op != MTRETEN &&
4951 mtc.mt_op != MTERASE &&
4952 mtc.mt_op != MTSEEK &&
4953 mtc.mt_op != MTEOM) {
4958 /* remove this when the midlevel properly clears was_reset */
4959 STp->device->was_reset = 0;
4962 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK &&
4963 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
4964 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER &&
4965 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART &&
4966 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) {
4969 * The user tells us to move to another position on the tape.
4970 * If we were appending to the tape content, that would leave
4971 * the tape without proper end, in that case write EOD and
4972 * update the header to reflect its position.
4975 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
4976 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
4977 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
4978 STp->logical_blk_num, STps->drv_file, STps->drv_block );
4980 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
4981 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
4982 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4983 i = osst_write_trailer(STp, &SRpnt,
4984 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4986 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
4987 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
4988 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
4998 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
4999 do_door_lock(STp, 0); /* Ignore result! */
5001 if (mtc.mt_op == MTSETDRVBUFFER &&
5002 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
5003 retval = osst_set_options(STp, mtc.mt_count);
5007 if (mtc.mt_op == MTSETPART) {
5008 if (mtc.mt_count >= STp->nbr_partitions)
5011 STp->new_partition = mtc.mt_count;
5017 if (mtc.mt_op == MTMKPART) {
5018 if (!STp->can_partitions) {
5022 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
5023 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
5027 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5028 STp->ps[i].rw = ST_IDLE;
5029 STp->ps[i].at_sm = 0;
5030 STp->ps[i].last_block_valid = 0;
5032 STp->partition = STp->new_partition = 0;
5033 STp->nbr_partitions = 1; /* Bad guess ?-) */
5034 STps->drv_block = STps->drv_file = 0;
5039 if (mtc.mt_op == MTSEEK) {
5041 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
5043 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
5044 if (!STp->can_partitions)
5045 STp->ps[0].rw = ST_IDLE;
5050 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
5051 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
5056 cross_eof(STp, &SRpnt, 0);
5058 if (mtc.mt_op == MTCOMPRESSION)
5059 retval = -EINVAL; /* OnStream drives don't have compression hardware */
5061 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5062 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5063 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5067 if (!STm->defined) {
5072 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5077 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
5078 struct mtget mt_status;
5080 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
5085 mt_status.mt_type = MT_ISONSTREAM_SC;
5086 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
5087 mt_status.mt_dsreg =
5088 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
5089 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
5090 mt_status.mt_blkno = STps->drv_block;
5091 mt_status.mt_fileno = STps->drv_file;
5092 if (STp->block_size != 0) {
5093 if (STps->rw == ST_WRITING)
5094 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
5095 else if (STps->rw == ST_READING)
5096 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
5097 STp->block_size - 1) / STp->block_size;
5100 mt_status.mt_gstat = 0;
5101 if (STp->drv_write_prot)
5102 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
5103 if (mt_status.mt_blkno == 0) {
5104 if (mt_status.mt_fileno == 0)
5105 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
5107 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
5109 mt_status.mt_resid = STp->partition;
5110 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
5111 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
5112 else if (STps->eof >= ST_EOM_OK)
5113 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
5114 if (STp->density == 1)
5115 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
5116 else if (STp->density == 2)
5117 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
5118 else if (STp->density == 3)
5119 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
5120 if (STp->ready == ST_READY)
5121 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
5122 if (STp->ready == ST_NO_TAPE)
5123 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
5125 mt_status.mt_gstat |= GMT_SM(0xffffffff);
5126 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
5127 STp->drv_buffer != 0)
5128 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
5130 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
5136 STp->recover_erreg = 0; /* Clear after read */
5139 } /* End of MTIOCGET */
5141 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5142 struct mtpos mt_pos;
5144 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5149 blk = osst_get_frame_position(STp, &SRpnt);
5151 blk = osst_get_sector(STp, &SRpnt);
5156 mt_pos.mt_blkno = blk;
5157 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5162 if (SRpnt) osst_release_request(SRpnt);
5166 return scsi_ioctl(STp->device, cmd_in, p);
5169 if (SRpnt) osst_release_request(SRpnt);
5176 #ifdef CONFIG_COMPAT
5177 static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg)
5179 struct osst_tape *STp = file->private_data;
5180 struct scsi_device *sdev = STp->device;
5181 int ret = -ENOIOCTLCMD;
5182 if (sdev->host->hostt->compat_ioctl) {
5184 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
5193 /* Memory handling routines */
5195 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5196 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5200 struct osst_buffer *tb;
5202 if (from_initialization)
5203 priority = GFP_ATOMIC;
5205 priority = GFP_KERNEL;
5207 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5208 tb = (struct osst_buffer *)kmalloc(i, priority);
5210 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5214 tb->sg_segs = tb->orig_sg_segs = 0;
5215 tb->use_sg = max_sg;
5218 tb->buffer_size = 0;
5222 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5223 i, max_sg, need_dma);
5228 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5229 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5231 int segs, nbr, max_segs, b_size, order, got;
5234 if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5237 if (STbuffer->sg_segs) {
5238 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5239 normalize_buffer(STbuffer);
5241 /* See how many segments we can use -- need at least two */
5242 nbr = max_segs = STbuffer->use_sg;
5246 priority = GFP_KERNEL /* | __GFP_NOWARN */;
5248 priority |= GFP_DMA;
5250 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5251 big enough to reach the goal (code assumes no segments in place) */
5252 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5253 STbuffer->sg[0].page = alloc_pages(priority, order);
5254 STbuffer->sg[0].offset = 0;
5255 if (STbuffer->sg[0].page != NULL) {
5256 STbuffer->sg[0].length = b_size;
5257 STbuffer->b_data = page_address(STbuffer->sg[0].page);
5261 if (STbuffer->sg[0].page == NULL) {
5262 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5265 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5266 for (segs=STbuffer->sg_segs=1, got=b_size;
5267 segs < max_segs && got < OS_FRAME_SIZE; ) {
5268 STbuffer->sg[segs].page =
5269 alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5270 STbuffer->sg[segs].offset = 0;
5271 if (STbuffer->sg[segs].page == NULL) {
5272 if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
5273 b_size /= 2; /* Large enough for the rest of the buffers */
5277 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5280 STbuffer->buffer_size = got;
5282 normalize_buffer(STbuffer);
5285 STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
5286 got += STbuffer->sg[segs].length;
5287 STbuffer->buffer_size = got;
5288 STbuffer->sg_segs = ++segs;
5293 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5294 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5296 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5297 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5298 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5306 /* Release the segments */
5307 static void normalize_buffer(struct osst_buffer *STbuffer)
5309 int i, order, b_size;
5311 for (i=0; i < STbuffer->sg_segs; i++) {
5313 for (b_size = PAGE_SIZE, order = 0;
5314 b_size < STbuffer->sg[i].length;
5315 b_size *= 2, order++);
5317 __free_pages(STbuffer->sg[i].page, order);
5318 STbuffer->buffer_size -= STbuffer->sg[i].length;
5321 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5322 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5323 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5325 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5329 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5330 negative error code. */
5331 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
5333 int i, cnt, res, offset;
5335 for (i=0, offset=st_bp->buffer_bytes;
5336 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5337 offset -= st_bp->sg[i].length;
5338 if (i == st_bp->sg_segs) { /* Should never happen */
5339 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5342 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5343 cnt = st_bp->sg[i].length - offset < do_count ?
5344 st_bp->sg[i].length - offset : do_count;
5345 res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
5349 st_bp->buffer_bytes += cnt;
5353 if (do_count) { /* Should never happen */
5354 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5362 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5363 negative error code. */
5364 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
5366 int i, cnt, res, offset;
5368 for (i=0, offset=st_bp->read_pointer;
5369 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5370 offset -= st_bp->sg[i].length;
5371 if (i == st_bp->sg_segs) { /* Should never happen */
5372 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5375 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5376 cnt = st_bp->sg[i].length - offset < do_count ?
5377 st_bp->sg[i].length - offset : do_count;
5378 res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
5382 st_bp->buffer_bytes -= cnt;
5383 st_bp->read_pointer += cnt;
5387 if (do_count) { /* Should never happen */
5388 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5394 /* Sets the tail of the buffer after fill point to zero.
5395 Returns zero (success) or negative error code. */
5396 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
5398 int i, offset, do_count, cnt;
5400 for (i = 0, offset = st_bp->buffer_bytes;
5401 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5402 offset -= st_bp->sg[i].length;
5403 if (i == st_bp->sg_segs) { /* Should never happen */
5404 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5407 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5408 i < st_bp->sg_segs && do_count > 0; i++) {
5409 cnt = st_bp->sg[i].length - offset < do_count ?
5410 st_bp->sg[i].length - offset : do_count ;
5411 memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
5415 if (do_count) { /* Should never happen */
5416 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5422 /* Copy a osst 32K chunk of memory into the buffer.
5423 Returns zero (success) or negative error code. */
5424 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5426 int i, cnt, do_count = OS_DATA_SIZE;
5428 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5429 cnt = st_bp->sg[i].length < do_count ?
5430 st_bp->sg[i].length : do_count ;
5431 memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
5435 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5436 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5443 /* Copy a osst 32K chunk of memory from the buffer.
5444 Returns zero (success) or negative error code. */
5445 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5447 int i, cnt, do_count = OS_DATA_SIZE;
5449 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5450 cnt = st_bp->sg[i].length < do_count ?
5451 st_bp->sg[i].length : do_count ;
5452 memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
5456 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5457 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5465 /* Module housekeeping */
5467 static void validate_options (void)
5470 osst_max_dev = max_dev;
5471 if (write_threshold_kbs > 0)
5472 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5473 if (osst_write_threshold > osst_buffer_size)
5474 osst_write_threshold = osst_buffer_size;
5475 if (max_sg_segs >= OSST_FIRST_SG)
5476 osst_max_sg_segs = max_sg_segs;
5478 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5479 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5484 /* Set the boot options. Syntax: osst=xxx,yyy,...
5485 where xxx is write threshold in 1024 byte blocks,
5486 and yyy is number of s/g segments to use. */
5487 static int __init osst_setup (char *str)
5492 stp = get_options(str, ARRAY_SIZE(ints), ints);
5495 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5496 *parms[i].val = ints[i + 1];
5498 while (stp != NULL) {
5499 for (i = 0; i < ARRAY_SIZE(parms); i++) {
5500 int len = strlen(parms[i].name);
5501 if (!strncmp(stp, parms[i].name, len) &&
5502 (*(stp + len) == ':' || *(stp + len) == '=')) {
5504 simple_strtoul(stp + len + 1, NULL, 0);
5508 if (i >= sizeof(parms) / sizeof(struct osst_dev_parm))
5509 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5511 stp = strchr(stp, ',');
5520 __setup("osst=", osst_setup);
5524 static struct file_operations osst_fops = {
5525 .owner = THIS_MODULE,
5527 .write = osst_write,
5528 .ioctl = osst_ioctl,
5529 #ifdef CONFIG_COMPAT
5530 .compat_ioctl = osst_compat_ioctl,
5532 .open = os_scsi_tape_open,
5533 .flush = os_scsi_tape_flush,
5534 .release = os_scsi_tape_close,
5537 static int osst_supports(struct scsi_device * SDp)
5539 struct osst_support_data {
5543 char *driver_hint; /* Name of the correct driver, NULL if unknown */
5546 static struct osst_support_data support_list[] = {
5547 /* {"XXX", "Yy-", "", NULL}, example */
5551 struct osst_support_data *rp;
5553 /* We are willing to drive OnStream SC-x0 as well as the
5554 * * IDE, ParPort, FireWire, USB variants, if accessible by
5555 * * emulation layer (ide-scsi, usb-storage, ...) */
5557 for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5558 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5559 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5560 !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5566 * sysfs support for osst driver parameter information
5569 static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
5571 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
5574 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
5576 static void osst_create_driverfs_files(struct device_driver *driverfs)
5578 driver_create_file(driverfs, &driver_attr_version);
5581 static void osst_remove_driverfs_files(struct device_driver *driverfs)
5583 driver_remove_file(driverfs, &driver_attr_version);
5587 * sysfs support for accessing ADR header information
5590 static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf)
5592 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5595 if (STp && STp->header_ok && STp->linux_media)
5596 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
5600 CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
5602 static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf)
5604 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5607 if (STp && STp->header_ok && STp->linux_media)
5608 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
5612 CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
5614 static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf)
5616 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5619 if (STp && STp->header_ok && STp->linux_media)
5620 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
5624 CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
5626 static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf)
5628 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5631 if (STp && STp->header_ok && STp->linux_media)
5632 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
5636 CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
5638 static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf)
5640 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5643 if (STp && STp->header_ok && STp->linux_media)
5644 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
5648 CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
5650 static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf)
5652 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5655 if (STp && STp->header_ok && STp->linux_media)
5656 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
5660 CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5662 static struct class *osst_sysfs_class;
5664 static int osst_sysfs_valid = 0;
5666 static void osst_sysfs_init(void)
5668 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
5669 if ( IS_ERR(osst_sysfs_class) )
5670 printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
5672 osst_sysfs_valid = 1;
5675 static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5677 struct class_device *osst_class_member;
5679 if (!osst_sysfs_valid) return;
5681 osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name);
5682 if (IS_ERR(osst_class_member)) {
5683 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5686 class_set_devdata(osst_class_member, STp);
5687 class_device_create_file(osst_class_member, &class_device_attr_ADR_rev);
5688 class_device_create_file(osst_class_member, &class_device_attr_media_version);
5689 class_device_create_file(osst_class_member, &class_device_attr_capacity);
5690 class_device_create_file(osst_class_member, &class_device_attr_BOT_frame);
5691 class_device_create_file(osst_class_member, &class_device_attr_EOD_frame);
5692 class_device_create_file(osst_class_member, &class_device_attr_file_count);
5695 static void osst_sysfs_destroy(dev_t dev)
5697 if (!osst_sysfs_valid) return;
5699 class_device_destroy(osst_sysfs_class, dev);
5702 static void osst_sysfs_cleanup(void)
5704 if (osst_sysfs_valid) {
5705 class_destroy(osst_sysfs_class);
5706 osst_sysfs_valid = 0;
5711 * osst startup / cleanup code
5714 static int osst_probe(struct device *dev)
5716 struct scsi_device * SDp = to_scsi_device(dev);
5717 struct osst_tape * tpnt;
5718 struct st_modedef * STm;
5719 struct st_partstat * STps;
5720 struct osst_buffer * buffer;
5721 struct gendisk * drive;
5724 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5727 drive = alloc_disk(1);
5729 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5733 /* if this is the first attach, build the infrastructure */
5734 write_lock(&os_scsi_tapes_lock);
5735 if (os_scsi_tapes == NULL) {
5737 (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *),
5739 if (os_scsi_tapes == NULL) {
5740 write_unlock(&os_scsi_tapes_lock);
5741 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5744 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5747 if (osst_nr_dev >= osst_max_dev) {
5748 write_unlock(&os_scsi_tapes_lock);
5749 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5753 /* find a free minor number */
5754 for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++);
5755 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5758 /* allocate a struct osst_tape for this device */
5759 tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
5761 write_unlock(&os_scsi_tapes_lock);
5762 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5765 memset(tpnt, 0, sizeof(struct osst_tape));
5767 /* allocate a buffer for this device */
5768 i = SDp->host->sg_tablesize;
5769 if (osst_max_sg_segs < i)
5770 i = osst_max_sg_segs;
5771 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
5772 if (buffer == NULL) {
5773 write_unlock(&os_scsi_tapes_lock);
5774 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5778 os_scsi_tapes[dev_num] = tpnt;
5779 tpnt->buffer = buffer;
5781 drive->private_data = &tpnt->driver;
5782 sprintf(drive->disk_name, "osst%d", dev_num);
5783 tpnt->driver = &osst_template;
5784 tpnt->drive = drive;
5786 tpnt->capacity = 0xfffff;
5788 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
5789 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5791 tpnt->do_auto_lock = OSST_AUTO_LOCK;
5792 tpnt->can_bsr = OSST_IN_FILE_POS;
5793 tpnt->can_partitions = 0;
5794 tpnt->two_fm = OSST_TWO_FM;
5795 tpnt->fast_mteom = OSST_FAST_MTEOM;
5796 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5797 tpnt->write_threshold = osst_write_threshold;
5798 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5799 tpnt->partition = 0;
5800 tpnt->new_partition = 0;
5801 tpnt->nbr_partitions = 0;
5802 tpnt->min_block = 512;
5803 tpnt->max_block = OS_DATA_SIZE;
5804 tpnt->timeout = OSST_TIMEOUT;
5805 tpnt->long_timeout = OSST_LONG_TIMEOUT;
5807 /* Recognize OnStream tapes */
5808 /* We don't need to test for OnStream, as this has been done in detect () */
5809 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5810 tpnt->omit_blklims = 1;
5812 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5813 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5814 tpnt->frame_in_buffer = 0;
5815 tpnt->header_ok = 0;
5816 tpnt->linux_media = 0;
5817 tpnt->header_cache = NULL;
5819 for (i=0; i < ST_NBR_MODES; i++) {
5820 STm = &(tpnt->modes[i]);
5822 STm->sysv = OSST_SYSV;
5823 STm->defaults_for_writes = 0;
5824 STm->do_async_writes = OSST_ASYNC_WRITES;
5825 STm->do_buffer_writes = OSST_BUFFER_WRITES;
5826 STm->do_read_ahead = OSST_READ_AHEAD;
5827 STm->default_compression = ST_DONT_TOUCH;
5828 STm->default_blksize = 512;
5829 STm->default_density = (-1); /* No forced density */
5832 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5833 STps = &(tpnt->ps[i]);
5835 STps->eof = ST_NOEOF;
5837 STps->last_block_valid = 0;
5838 STps->drv_block = (-1);
5839 STps->drv_file = (-1);
5842 tpnt->current_mode = 0;
5843 tpnt->modes[0].defined = 1;
5844 tpnt->modes[2].defined = 1;
5845 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
5847 init_MUTEX(&tpnt->lock);
5849 write_unlock(&os_scsi_tapes_lock);
5853 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5854 /* No-rewind entry */
5855 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5856 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5859 sdev_printk(KERN_INFO, SDp,
5860 "osst :I: Attached OnStream %.5s tape as %s\n",
5861 SDp->model, tape_name(tpnt));
5870 static int osst_remove(struct device *dev)
5872 struct scsi_device * SDp = to_scsi_device(dev);
5873 struct osst_tape * tpnt;
5876 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
5879 write_lock(&os_scsi_tapes_lock);
5880 for(i=0; i < osst_max_dev; i++) {
5881 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
5882 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
5883 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
5884 tpnt->device = NULL;
5885 put_disk(tpnt->drive);
5886 os_scsi_tapes[i] = NULL;
5888 write_unlock(&os_scsi_tapes_lock);
5889 vfree(tpnt->header_cache);
5891 normalize_buffer(tpnt->buffer);
5892 kfree(tpnt->buffer);
5898 write_unlock(&os_scsi_tapes_lock);
5902 static int __init init_osst(void)
5904 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
5909 if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
5910 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
5911 osst_sysfs_cleanup();
5914 osst_create_driverfs_files(&osst_template.gendrv);
5919 static void __exit exit_osst (void)
5922 struct osst_tape * STp;
5924 osst_remove_driverfs_files(&osst_template.gendrv);
5925 scsi_unregister_driver(&osst_template.gendrv);
5926 unregister_chrdev(OSST_MAJOR, "osst");
5927 osst_sysfs_cleanup();
5929 if (os_scsi_tapes) {
5930 for (i=0; i < osst_max_dev; ++i) {
5931 if (!(STp = os_scsi_tapes[i])) continue;
5932 /* This is defensive, supposed to happen during detach */
5933 vfree(STp->header_cache);
5935 normalize_buffer(STp->buffer);
5938 put_disk(STp->drive);
5941 kfree(os_scsi_tapes);
5943 printk(KERN_INFO "osst :I: Unloaded.\n");
5946 module_init(init_osst);
5947 module_exit(exit_osst);