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 <linux/jiffies.h>
53 #include <asm/uaccess.h>
55 #include <asm/system.h>
57 /* The driver prints some debugging information on the console if DEBUG
58 is defined and non-zero. */
61 /* The message level for the debug messages is currently set to KERN_NOTICE
62 so that people can easily see the messages. Later when the debugging messages
63 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
64 #define OSST_DEB_MSG KERN_NOTICE
66 #include <scsi/scsi.h>
67 #include <scsi/scsi_dbg.h>
68 #include <scsi/scsi_device.h>
69 #include <scsi/scsi_driver.h>
70 #include <scsi/scsi_eh.h>
71 #include <scsi/scsi_host.h>
72 #include <scsi/scsi_ioctl.h>
74 #define ST_KILOBYTE 1024
78 #include "osst_options.h"
79 #include "osst_detect.h"
81 static int max_dev = 0;
82 static int write_threshold_kbs = 0;
83 static int max_sg_segs = 0;
86 MODULE_AUTHOR("Willem Riede");
87 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
88 MODULE_LICENSE("GPL");
89 MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR);
90 MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
92 module_param(max_dev, int, 0444);
93 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
95 module_param(write_threshold_kbs, int, 0644);
96 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
98 module_param(max_sg_segs, int, 0644);
99 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
101 static struct osst_dev_parm {
104 } parms[] __initdata = {
105 { "max_dev", &max_dev },
106 { "write_threshold_kbs", &write_threshold_kbs },
107 { "max_sg_segs", &max_sg_segs }
111 /* Some default definitions have been moved to osst_options.h */
112 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
113 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
115 /* The buffer size should fit into the 24 bits for length in the
116 6-byte SCSI read and write commands. */
117 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
118 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
122 static int debugging = 1;
123 /* uncomment define below to test error recovery */
124 // #define OSST_INJECT_ERRORS 1
127 /* Do not retry! The drive firmware already retries when appropriate,
128 and when it tries to tell us something, we had better listen... */
129 #define MAX_RETRIES 0
131 #define NO_TAPE NOT_READY
133 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
134 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
135 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
137 #define OSST_TIMEOUT (200 * HZ)
138 #define OSST_LONG_TIMEOUT (1800 * HZ)
140 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
141 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
142 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
143 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
145 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
147 #define SET_DENS_AND_BLK 0x10001
149 static int osst_buffer_size = OSST_BUFFER_SIZE;
150 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
151 static int osst_max_sg_segs = OSST_MAX_SG;
152 static int osst_max_dev = OSST_MAX_TAPES;
153 static int osst_nr_dev;
155 static struct osst_tape **os_scsi_tapes = NULL;
156 static DEFINE_RWLOCK(os_scsi_tapes_lock);
158 static int modes_defined = 0;
160 static struct osst_buffer *new_tape_buffer(int, int, int);
161 static int enlarge_buffer(struct osst_buffer *, int);
162 static void normalize_buffer(struct osst_buffer *);
163 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
164 static int from_buffer(struct osst_buffer *, char __user *, int);
165 static int osst_zero_buffer_tail(struct osst_buffer *);
166 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
167 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
169 static int osst_probe(struct device *);
170 static int osst_remove(struct device *);
172 static struct scsi_driver osst_template = {
173 .owner = THIS_MODULE,
177 .remove = osst_remove,
181 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt,
182 unsigned int cmd_in, unsigned long arg);
184 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip);
186 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt);
188 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt);
190 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending);
192 static inline char *tape_name(struct osst_tape *tape)
194 return tape->drive->disk_name;
197 /* Routines that handle the interaction with mid-layer SCSI routines */
200 /* Normalize Sense */
201 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s)
204 const u8 *sense = SRpnt->sense;
206 s->have_sense = scsi_normalize_sense(SRpnt->sense,
207 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
213 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
214 switch (sense[0] & 0x7f) {
219 s->flags = sense[2] & 0xe0;
225 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
226 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
232 /* Convert the result to success code */
233 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
235 char *name = tape_name(STp);
236 int result = SRpnt->result;
237 u8 * sense = SRpnt->sense, scode;
241 struct st_cmdstatus *cmdstatp;
246 cmdstatp = &STp->buffer->cmdstat;
247 osst_analyze_sense(SRpnt, cmdstatp);
249 if (cmdstatp->have_sense)
250 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
255 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
257 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
258 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
259 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
260 name, scode, sense[12], sense[13]);
261 if (cmdstatp->have_sense)
262 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
266 if (cmdstatp->have_sense && (
268 scode != RECOVERED_ERROR &&
269 /* scode != UNIT_ATTENTION && */
270 scode != BLANK_CHECK &&
271 scode != VOLUME_OVERFLOW &&
272 SRpnt->cmd[0] != MODE_SENSE &&
273 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
274 if (cmdstatp->have_sense) {
275 printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
276 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
279 static int notyetprinted = 1;
282 "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
283 name, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
288 "%s:I: This warning may be caused by your scsi controller,\n", name);
290 "%s:I: it has been reported with some Buslogic cards.\n", name);
294 STp->pos_unknown |= STp->device->was_reset;
296 if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
297 STp->recover_count++;
298 STp->recover_erreg++;
301 if (SRpnt->cmd[0] == READ_6)
303 else if (SRpnt->cmd[0] == WRITE_6)
307 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
311 if ((sense[2] & 0xe0) == 0)
318 /* Wakeup from interrupt */
319 static void osst_sleep_done(void *data, char *sense, int result, int resid)
321 struct osst_request *SRpnt = data;
322 struct osst_tape *STp = SRpnt->stp;
324 memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
325 STp->buffer->cmdstat.midlevel_result = SRpnt->result = result;
327 STp->write_pending = 0;
330 complete(SRpnt->waiting);
333 /* osst_request memory management */
334 static struct osst_request *osst_allocate_request(void)
336 return kzalloc(sizeof(struct osst_request), GFP_KERNEL);
339 static void osst_release_request(struct osst_request *streq)
344 /* Do the scsi command. Waits until command performed if do_wait is true.
345 Otherwise osst_write_behind_check() is used to check that the command
347 static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp,
348 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
351 unsigned short use_sg;
352 #ifdef OSST_INJECT_ERRORS
353 static int inject = 0;
354 static int repeat = 0;
356 struct completion *waiting;
358 /* if async, make sure there's no command outstanding */
359 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
360 printk(KERN_ERR "%s: Async command already active.\n",
362 if (signal_pending(current))
363 (STp->buffer)->syscall_result = (-EINTR);
365 (STp->buffer)->syscall_result = (-EBUSY);
370 SRpnt = osst_allocate_request();
372 printk(KERN_ERR "%s: Can't allocate SCSI request.\n",
374 if (signal_pending(current))
375 (STp->buffer)->syscall_result = (-EINTR);
377 (STp->buffer)->syscall_result = (-EBUSY);
383 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
384 which IO is outstanding. It's nulled out when the IO completes. */
386 (STp->buffer)->last_SRpnt = SRpnt;
388 waiting = &STp->wait;
389 init_completion(waiting);
390 SRpnt->waiting = waiting;
392 use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0;
394 bp = (char *)&(STp->buffer->sg[0]);
395 if (STp->buffer->sg_segs < use_sg)
396 use_sg = STp->buffer->sg_segs;
399 bp = (STp->buffer)->b_data;
401 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
402 STp->buffer->cmdstat.have_sense = 0;
403 STp->buffer->syscall_result = 0;
405 if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
406 use_sg, timeout, retries, SRpnt, osst_sleep_done, GFP_KERNEL))
407 /* could not allocate the buffer or request was too large */
408 (STp->buffer)->syscall_result = (-EBUSY);
410 wait_for_completion(waiting);
411 SRpnt->waiting = NULL;
412 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
413 #ifdef OSST_INJECT_ERRORS
414 if (STp->buffer->syscall_result == 0 &&
417 ( (++ inject % 83) == 29 ||
418 (STp->first_frame_position == 240
419 /* or STp->read_error_frame to fail again on the block calculated above */ &&
421 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
422 STp->buffer->last_result_fatal = 1;
430 /* Handle the write-behind checking (downs the semaphore) */
431 static void osst_write_behind_check(struct osst_tape *STp)
433 struct osst_buffer * STbuffer;
435 STbuffer = STp->buffer;
438 if (STp->write_pending)
443 wait_for_completion(&(STp->wait));
444 STp->buffer->last_SRpnt->waiting = NULL;
446 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
448 if (STp->buffer->syscall_result)
449 STp->buffer->syscall_result =
450 osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1);
452 STp->first_frame_position++;
454 osst_release_request(STp->buffer->last_SRpnt);
456 if (STbuffer->writing < STbuffer->buffer_bytes)
457 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
459 STbuffer->last_SRpnt = NULL;
460 STbuffer->buffer_bytes -= STbuffer->writing;
461 STbuffer->writing = 0;
468 /* Onstream specific Routines */
470 * Initialize the OnStream AUX
472 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
473 int logical_blk_num, int blk_sz, int blk_cnt)
475 os_aux_t *aux = STp->buffer->aux;
476 os_partition_t *par = &aux->partition;
477 os_dat_t *dat = &aux->dat;
479 if (STp->raw) return;
481 memset(aux, 0, sizeof(*aux));
482 aux->format_id = htonl(0);
483 memcpy(aux->application_sig, "LIN4", 4);
484 aux->hdwr = htonl(0);
485 aux->frame_type = frame_type;
487 switch (frame_type) {
488 case OS_FRAME_TYPE_HEADER:
489 aux->update_frame_cntr = htonl(STp->update_frame_cntr);
490 par->partition_num = OS_CONFIG_PARTITION;
491 par->par_desc_ver = OS_PARTITION_VERSION;
492 par->wrt_pass_cntr = htons(0xffff);
493 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
494 par->first_frame_ppos = htonl(0);
495 par->last_frame_ppos = htonl(0xbb7);
496 aux->frame_seq_num = htonl(0);
497 aux->logical_blk_num_high = htonl(0);
498 aux->logical_blk_num = htonl(0);
499 aux->next_mark_ppos = htonl(STp->first_mark_ppos);
501 case OS_FRAME_TYPE_DATA:
502 case OS_FRAME_TYPE_MARKER:
507 dat->dat_list[0].blk_sz = htonl(blk_sz);
508 dat->dat_list[0].blk_cnt = htons(blk_cnt);
509 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
510 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
511 dat->dat_list[0].reserved = 0;
512 case OS_FRAME_TYPE_EOD:
513 aux->update_frame_cntr = htonl(0);
514 par->partition_num = OS_DATA_PARTITION;
515 par->par_desc_ver = OS_PARTITION_VERSION;
516 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
517 par->first_frame_ppos = htonl(STp->first_data_ppos);
518 par->last_frame_ppos = htonl(STp->capacity);
519 aux->frame_seq_num = htonl(frame_seq_number);
520 aux->logical_blk_num_high = htonl(0);
521 aux->logical_blk_num = htonl(logical_blk_num);
523 default: ; /* probably FILL */
525 aux->filemark_cnt = htonl(STp->filemark_cnt);
526 aux->phys_fm = htonl(0xffffffff);
527 aux->last_mark_ppos = htonl(STp->last_mark_ppos);
528 aux->last_mark_lbn = htonl(STp->last_mark_lbn);
532 * Verify that we have the correct tape frame
534 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
536 char * name = tape_name(STp);
537 os_aux_t * aux = STp->buffer->aux;
538 os_partition_t * par = &(aux->partition);
539 struct st_partstat * STps = &(STp->ps[STp->partition]);
540 int blk_cnt, blk_sz, i;
543 if (STp->buffer->syscall_result) {
544 for (i=0; i < STp->buffer->sg_segs; i++)
545 memset(page_address(sg_page(&STp->buffer->sg[i])),
546 0, STp->buffer->sg[i].length);
547 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
549 STp->buffer->buffer_bytes = OS_FRAME_SIZE;
552 if (STp->buffer->syscall_result) {
554 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
558 if (ntohl(aux->format_id) != 0) {
560 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
564 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
565 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
567 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
571 if (par->partition_num != OS_DATA_PARTITION) {
572 if (!STp->linux_media || STp->linux_media_version != 2) {
574 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
575 name, par->partition_num);
580 if (par->par_desc_ver != OS_PARTITION_VERSION) {
582 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
586 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
588 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
589 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
593 if (aux->frame_type != OS_FRAME_TYPE_DATA &&
594 aux->frame_type != OS_FRAME_TYPE_EOD &&
595 aux->frame_type != OS_FRAME_TYPE_MARKER) {
598 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
603 if (aux->frame_type == OS_FRAME_TYPE_EOD &&
604 STp->first_frame_position < STp->eod_frame_ppos) {
605 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
606 STp->first_frame_position);
609 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
612 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
613 name, ntohl(aux->frame_seq_num), frame_seq_number);
618 if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
619 STps->eof = ST_FM_HIT;
621 i = ntohl(aux->filemark_cnt);
622 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
623 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
625 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
626 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
627 i, STp->first_frame_position - 1);
629 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
630 if (i >= STp->filemark_cnt)
631 STp->filemark_cnt = i+1;
634 if (aux->frame_type == OS_FRAME_TYPE_EOD) {
635 STps->eof = ST_EOD_1;
636 STp->frame_in_buffer = 1;
638 if (aux->frame_type == OS_FRAME_TYPE_DATA) {
639 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
640 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
641 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
642 STp->buffer->read_pointer = 0;
643 STp->frame_in_buffer = 1;
645 /* See what block size was used to write file */
646 if (STp->block_size != blk_sz && blk_sz > 0) {
648 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
649 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
650 STp->block_size<1024?STp->block_size:STp->block_size/1024,
651 STp->block_size<1024?'b':'k');
652 STp->block_size = blk_sz;
653 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
655 STps->eof = ST_NOEOF;
657 STp->frame_seq_number = ntohl(aux->frame_seq_num);
658 STp->logical_blk_num = ntohl(aux->logical_blk_num);
662 if (STp->read_error_frame == 0)
663 STp->read_error_frame = STp->first_frame_position - 1;
668 * Wait for the unit to become Ready
670 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
671 unsigned timeout, int initial_delay)
673 unsigned char cmd[MAX_COMMAND_SIZE];
674 struct osst_request * SRpnt;
675 unsigned long startwait = jiffies;
678 char * name = tape_name(STp);
680 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
683 if (initial_delay > 0)
684 msleep(jiffies_to_msecs(initial_delay));
686 memset(cmd, 0, MAX_COMMAND_SIZE);
687 cmd[0] = TEST_UNIT_READY;
689 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
691 if (!SRpnt) return (-EBUSY);
693 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
694 (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
695 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) ||
696 ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 &&
697 SRpnt->sense[13] == 0 ) )) {
700 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
701 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
707 memset(cmd, 0, MAX_COMMAND_SIZE);
708 cmd[0] = TEST_UNIT_READY;
710 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
716 if ( STp->buffer->syscall_result &&
717 osst_write_error_recovery(STp, aSRpnt, 0) ) {
719 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
720 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
721 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
722 SRpnt->sense[12], SRpnt->sense[13]);
727 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
733 * Wait for a tape to be inserted in the unit
735 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
737 unsigned char cmd[MAX_COMMAND_SIZE];
738 struct osst_request * SRpnt;
739 unsigned long startwait = jiffies;
742 char * name = tape_name(STp);
744 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
747 memset(cmd, 0, MAX_COMMAND_SIZE);
748 cmd[0] = TEST_UNIT_READY;
750 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
752 if (!SRpnt) return (-EBUSY);
754 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
755 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) {
758 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
759 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
765 memset(cmd, 0, MAX_COMMAND_SIZE);
766 cmd[0] = TEST_UNIT_READY;
768 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
774 if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 &&
775 SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) {
777 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
778 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
779 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
780 SRpnt->sense[12], SRpnt->sense[13]);
785 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
790 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame)
794 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
795 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
796 if (retval) return (retval);
797 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
798 return (osst_get_frame_position(STp, aSRpnt));
802 * Wait for write(s) to complete
804 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
806 unsigned char cmd[MAX_COMMAND_SIZE];
807 struct osst_request * SRpnt;
809 int delay = OSST_WAIT_WRITE_COMPLETE;
811 char * name = tape_name(STp);
813 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
816 memset(cmd, 0, MAX_COMMAND_SIZE);
817 cmd[0] = WRITE_FILEMARKS;
820 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
822 if (!SRpnt) return (-EBUSY);
823 if (STp->buffer->syscall_result) {
824 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) {
825 if (SRpnt->sense[13] == 8) {
826 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
829 result = osst_write_error_recovery(STp, aSRpnt, 0);
831 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
832 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
837 #define OSST_POLL_PER_SEC 10
838 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to)
840 unsigned long startwait = jiffies;
841 char * name = tape_name(STp);
843 char notyetprinted = 1;
845 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
846 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
848 while (time_before (jiffies, startwait + to*HZ))
851 result = osst_get_frame_position(STp, aSRpnt);
853 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
854 return 0; /* successful recovery leaves drive ready for frame */
855 if (result < 0) break;
856 if (STp->first_frame_position == curr &&
858 (signed)STp->last_frame_position > (signed)curr + minlast) ||
859 (minlast >= 0 && STp->cur_frames > minlast)
863 if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC))
865 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
866 name, curr, curr+minlast, STp->first_frame_position,
867 STp->last_frame_position, STp->cur_frames,
868 result, (jiffies-startwait)/HZ,
869 (((jiffies-startwait)%HZ)*10)/HZ);
874 if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted)
876 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
877 name, curr, curr+minlast, STp->first_frame_position,
878 STp->last_frame_position, STp->cur_frames, result);
882 msleep(1000 / OSST_POLL_PER_SEC);
885 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
886 name, curr, curr+minlast, STp->first_frame_position,
887 STp->last_frame_position, STp->cur_frames,
888 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
893 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
895 struct osst_request * SRpnt;
896 unsigned char cmd[MAX_COMMAND_SIZE];
897 unsigned long startwait = jiffies;
899 char * name = tape_name(STp);
903 char * olddata = STp->buffer->b_data;
904 int oldsize = STp->buffer->buffer_size;
906 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
908 memset(cmd, 0, MAX_COMMAND_SIZE);
909 cmd[0] = WRITE_FILEMARKS;
911 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
914 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
916 if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) {
918 /* some failure - not just not-ready */
919 retval = osst_write_error_recovery(STp, aSRpnt, 0);
922 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
924 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
925 memset(cmd, 0, MAX_COMMAND_SIZE);
926 cmd[0] = READ_POSITION;
928 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
931 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
932 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
935 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
937 /* TODO - figure out which error conditions can be handled */
938 if (STp->buffer->syscall_result)
940 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
941 (*aSRpnt)->sense[ 2] & 0x0f,
942 (*aSRpnt)->sense[12],
943 (*aSRpnt)->sense[13]);
949 * Read the next OnStream tape frame at the current location
951 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
953 unsigned char cmd[MAX_COMMAND_SIZE];
954 struct osst_request * SRpnt;
957 os_aux_t * aux = STp->buffer->aux;
958 char * name = tape_name(STp);
962 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
963 retval = osst_recover_wait_frame(STp, aSRpnt, 0);
965 memset(cmd, 0, MAX_COMMAND_SIZE);
972 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
974 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
975 STp->timeout, MAX_RETRIES, 1);
980 if ((STp->buffer)->syscall_result) {
982 if (STp->read_error_frame == 0) {
983 STp->read_error_frame = STp->first_frame_position;
985 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
990 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
992 SRpnt->sense[0], SRpnt->sense[1],
993 SRpnt->sense[2], SRpnt->sense[3],
994 SRpnt->sense[4], SRpnt->sense[5],
995 SRpnt->sense[6], SRpnt->sense[7]);
999 STp->first_frame_position++;
1004 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
1007 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
1008 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
1009 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
1010 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
1011 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
1012 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
1013 if (aux->frame_type==2)
1014 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
1015 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
1016 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
1022 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
1024 struct st_partstat * STps = &(STp->ps[STp->partition]);
1025 struct osst_request * SRpnt ;
1026 unsigned char cmd[MAX_COMMAND_SIZE];
1028 char * name = tape_name(STp);
1030 if (STps->rw != ST_READING) { /* Initialize read operation */
1031 if (STps->rw == ST_WRITING || STp->dirty) {
1032 STp->write_type = OS_WRITE_DATA;
1033 osst_flush_write_buffer(STp, aSRpnt);
1034 osst_flush_drive_buffer(STp, aSRpnt);
1036 STps->rw = ST_READING;
1037 STp->frame_in_buffer = 0;
1040 * Issue a read 0 command to get the OnStream drive
1041 * read frames into its buffer.
1043 memset(cmd, 0, MAX_COMMAND_SIZE);
1048 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
1050 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
1052 if ((retval = STp->buffer->syscall_result))
1053 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
1059 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt,
1060 int frame_seq_number, int quiet)
1062 struct st_partstat * STps = &(STp->ps[STp->partition]);
1063 char * name = tape_name(STp);
1071 * If we want just any frame (-1) and there is a frame in the buffer, return it
1073 if (frame_seq_number == -1 && STp->frame_in_buffer) {
1075 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1080 * Search and wait for the next logical tape frame
1084 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1085 name, frame_seq_number);
1086 if (STp->read_error_frame) {
1087 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1089 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1090 name, STp->read_error_frame);
1092 STp->read_error_frame = 0;
1099 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1100 name, frame_seq_number, cnt);
1102 if ( osst_initiate_read(STp, aSRpnt)
1103 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1106 position = osst_get_frame_position(STp, aSRpnt);
1107 if (position >= 0xbae && position < 0xbb8)
1109 else if (position > STp->eod_frame_ppos || ++bad == 10) {
1110 position = STp->read_error_frame - 1;
1118 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1121 osst_set_frame_position(STp, aSRpnt, position, 0);
1124 if (osst_verify_frame(STp, frame_seq_number, quiet))
1126 if (osst_verify_frame(STp, -1, quiet)) {
1127 x = ntohl(STp->buffer->aux->frame_seq_num);
1128 if (STp->fast_open) {
1130 "%s:W: Found logical frame %d instead of %d after fast open\n",
1131 name, x, frame_seq_number);
1133 STp->read_error_frame = 0;
1136 if (x > frame_seq_number) {
1138 /* positioning backwards did not bring us to the desired frame */
1139 position = STp->read_error_frame - 1;
1142 position = osst_get_frame_position(STp, aSRpnt)
1143 + frame_seq_number - x - 1;
1145 if (STp->first_frame_position >= 3000 && position < 3000)
1150 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1151 name, x, frame_seq_number,
1152 STp->first_frame_position - position);
1154 osst_set_frame_position(STp, aSRpnt, position, 0);
1160 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1162 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1164 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1167 STp->frame_in_buffer = 0;
1170 STp->recover_count++;
1171 STp->recover_erreg++;
1172 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1173 name, STp->read_error_frame);
1178 if (debugging || STps->eof)
1180 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1181 name, frame_seq_number, STp->frame_seq_number, STps->eof);
1184 STp->read_error_frame = 0;
1188 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num)
1190 struct st_partstat * STps = &(STp->ps[STp->partition]);
1191 char * name = tape_name(STp);
1193 int frame_seq_estimate, ppos_estimate, move;
1195 if (logical_blk_num < 0) logical_blk_num = 0;
1197 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1198 name, logical_blk_num, STp->logical_blk_num,
1199 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1200 STp->block_size<1024?'b':'k');
1202 /* Do we know where we are? */
1203 if (STps->drv_block >= 0) {
1204 move = logical_blk_num - STp->logical_blk_num;
1205 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1206 move /= (OS_DATA_SIZE / STp->block_size);
1207 frame_seq_estimate = STp->frame_seq_number + move;
1209 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1211 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1212 else ppos_estimate = frame_seq_estimate + 20;
1213 while (++retries < 10) {
1214 if (ppos_estimate > STp->eod_frame_ppos-2) {
1215 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1216 ppos_estimate = STp->eod_frame_ppos - 2;
1218 if (frame_seq_estimate < 0) {
1219 frame_seq_estimate = 0;
1222 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1223 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1224 /* we've located the estimated frame, now does it have our block? */
1225 if (logical_blk_num < STp->logical_blk_num ||
1226 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1227 if (STps->eof == ST_FM_HIT)
1228 move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1230 move = logical_blk_num - STp->logical_blk_num;
1231 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1232 move /= (OS_DATA_SIZE / STp->block_size);
1234 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1237 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1238 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1239 STp->logical_blk_num, logical_blk_num, move);
1241 frame_seq_estimate += move;
1242 ppos_estimate += move;
1245 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1246 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1247 STp->logical_blk_num = logical_blk_num;
1250 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1251 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1252 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1255 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1256 if (STps->eof == ST_FM_HIT) {
1258 STps->drv_block = 0;
1260 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1261 STp->logical_blk_num -
1262 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1265 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1269 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1271 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1273 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1274 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1275 STp->logical_blk_num, logical_blk_num);
1277 if (frame_seq_estimate != STp->frame_seq_number)
1278 ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1283 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1284 name, logical_blk_num, STp->logical_blk_num, retries);
1288 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1289 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1290 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1291 * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1293 #define OSST_FRAME_SHIFT 6
1294 #define OSST_SECTOR_SHIFT 9
1295 #define OSST_SECTOR_MASK 0x03F
1297 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt)
1301 char * name = tape_name(STp);
1304 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1305 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1306 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1307 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1308 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1309 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1311 /* do we know where we are inside a file? */
1312 if (STp->ps[STp->partition].drv_block >= 0) {
1313 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1314 STp->first_frame_position) << OSST_FRAME_SHIFT;
1315 if (STp->ps[STp->partition].rw == ST_WRITING)
1316 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1318 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1320 sector = osst_get_frame_position(STp, aSRpnt);
1322 sector <<= OSST_FRAME_SHIFT;
1327 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector)
1329 struct st_partstat * STps = &(STp->ps[STp->partition]);
1330 int frame = sector >> OSST_FRAME_SHIFT,
1331 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1334 char * name = tape_name(STp);
1336 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1337 name, sector, frame, offset);
1339 if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1341 if (frame <= STp->first_data_ppos) {
1342 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1343 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1345 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1346 if (r < 0) return r;
1348 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1349 if (r < 0) return r;
1351 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1354 STp->logical_blk_num += offset / STp->block_size;
1355 STp->buffer->read_pointer = offset;
1356 STp->buffer->buffer_bytes -= offset;
1358 STp->frame_seq_number++;
1359 STp->frame_in_buffer = 0;
1360 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1361 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1363 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1364 if (STps->eof == ST_FM_HIT) {
1366 STps->drv_block = 0;
1368 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1369 STp->logical_blk_num -
1370 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1373 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1376 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1377 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1378 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1384 * Read back the drive's internal buffer contents, as a part
1385 * of the write error recovery mechanism for old OnStream
1386 * firmware revisions.
1387 * Precondition for this function to work: all frames in the
1388 * drive's buffer must be of one type (DATA, MARK or EOD)!
1390 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
1391 unsigned int frame, unsigned int skip, int pending)
1393 struct osst_request * SRpnt = * aSRpnt;
1394 unsigned char * buffer, * p;
1395 unsigned char cmd[MAX_COMMAND_SIZE];
1396 int flag, new_frame, i;
1397 int nframes = STp->cur_frames;
1398 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1399 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1400 - (nframes + pending - 1);
1401 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1402 - (nframes + pending - 1) * blks_per_frame;
1403 char * name = tape_name(STp);
1404 unsigned long startwait = jiffies;
1406 int dbg = debugging;
1409 if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
1412 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1413 name, nframes, pending?" and one that was pending":"");
1415 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1417 if (pending && debugging)
1418 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1419 name, frame_seq_number + nframes,
1420 logical_blk_num + nframes * blks_per_frame,
1421 p[0], p[1], p[2], p[3]);
1423 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1425 memset(cmd, 0, MAX_COMMAND_SIZE);
1426 cmd[0] = 0x3C; /* Buffer Read */
1427 cmd[1] = 6; /* Retrieve Faulty Block */
1428 cmd[7] = 32768 >> 8;
1429 cmd[8] = 32768 & 0xff;
1431 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1432 STp->timeout, MAX_RETRIES, 1);
1434 if ((STp->buffer)->syscall_result || !SRpnt) {
1435 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1440 osst_copy_from_buffer(STp->buffer, p);
1443 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1444 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1448 osst_get_frame_position(STp, aSRpnt);
1451 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1453 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1454 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1456 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1459 if (STp->write_type == OS_WRITE_HEADER) {
1461 p += skip * OS_DATA_SIZE;
1463 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1468 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1469 name, new_frame+i, frame_seq_number+i);
1471 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1472 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1473 osst_get_frame_position(STp, aSRpnt);
1476 if (new_frame > frame + 1000) {
1477 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1481 if ( i >= nframes + pending ) break;
1484 osst_copy_to_buffer(STp->buffer, p);
1486 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1488 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1489 logical_blk_num + i*blks_per_frame,
1490 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1491 memset(cmd, 0, MAX_COMMAND_SIZE);
1499 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1500 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1501 p[0], p[1], p[2], p[3]);
1503 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1504 STp->timeout, MAX_RETRIES, 1);
1506 if (STp->buffer->syscall_result)
1509 p += OS_DATA_SIZE; i++;
1511 /* if we just sent the last frame, wait till all successfully written */
1512 if ( i == nframes + pending ) {
1514 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1516 memset(cmd, 0, MAX_COMMAND_SIZE);
1517 cmd[0] = WRITE_FILEMARKS;
1519 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1520 STp->timeout, MAX_RETRIES, 1);
1523 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1524 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1528 flag = STp->buffer->syscall_result;
1529 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1531 memset(cmd, 0, MAX_COMMAND_SIZE);
1532 cmd[0] = TEST_UNIT_READY;
1534 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1537 if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
1538 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
1539 /* in the process of becoming ready */
1543 if (STp->buffer->syscall_result)
1549 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1555 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1556 SRpnt->sense[12] == 0 &&
1557 SRpnt->sense[13] == 2) {
1558 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1560 return (-EIO); /* hit end of tape = fail */
1562 i = ((SRpnt->sense[3] << 24) |
1563 (SRpnt->sense[4] << 16) |
1564 (SRpnt->sense[5] << 8) |
1565 SRpnt->sense[6] ) - new_frame;
1566 p = &buffer[i * OS_DATA_SIZE];
1568 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1570 osst_get_frame_position(STp, aSRpnt);
1572 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1573 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1578 /* error recovery did not successfully complete */
1579 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1580 STp->write_type == OS_WRITE_HEADER?"header":"body");
1583 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1588 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
1589 unsigned int frame, unsigned int skip, int pending)
1591 unsigned char cmd[MAX_COMMAND_SIZE];
1592 struct osst_request * SRpnt;
1593 char * name = tape_name(STp);
1595 int attempts = 1000 / skip;
1597 unsigned long startwait = jiffies;
1599 int dbg = debugging;
1602 while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1607 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1609 expected = frame+skip+STp->cur_frames+pending;
1611 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1612 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1614 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1617 schedule_timeout_interruptible(msecs_to_jiffies(100));
1619 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1621 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1622 name, STp->first_frame_position,
1623 STp->last_frame_position, STp->cur_frames);
1625 frame = STp->last_frame_position;
1629 if (pending && STp->cur_frames < 50) {
1631 memset(cmd, 0, MAX_COMMAND_SIZE);
1636 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1637 name, STp->frame_seq_number-1, STp->first_frame_position);
1639 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1640 STp->timeout, MAX_RETRIES, 1);
1643 if (STp->buffer->syscall_result) { /* additional write error */
1644 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1645 SRpnt->sense[12] == 0 &&
1646 SRpnt->sense[13] == 2) {
1648 "%s:E: Volume overflow in write error recovery\n",
1650 break; /* hit end of tape = fail */
1659 if (STp->cur_frames == 0) {
1662 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1664 if (STp->first_frame_position != expected) {
1665 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1666 name, STp->first_frame_position, expected);
1673 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1674 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1678 schedule_timeout_interruptible(msecs_to_jiffies(100));
1680 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1688 * Error recovery algorithm for the OnStream tape.
1691 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending)
1693 struct osst_request * SRpnt = * aSRpnt;
1694 struct st_partstat * STps = & STp->ps[STp->partition];
1695 char * name = tape_name(STp);
1698 unsigned int frame, skip;
1700 rw_state = STps->rw;
1702 if ((SRpnt->sense[ 2] & 0x0f) != 3
1703 || SRpnt->sense[12] != 12
1704 || SRpnt->sense[13] != 0) {
1706 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1707 SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]);
1711 frame = (SRpnt->sense[3] << 24) |
1712 (SRpnt->sense[4] << 16) |
1713 (SRpnt->sense[5] << 8) |
1715 skip = SRpnt->sense[9];
1718 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1720 osst_get_frame_position(STp, aSRpnt);
1722 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1723 name, STp->first_frame_position, STp->last_frame_position);
1725 switch (STp->write_type) {
1728 case OS_WRITE_NEW_MARK:
1730 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1731 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1732 if (STp->os_fw_rev >= 10600)
1733 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1735 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1736 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1738 retval?"" :"Don't worry, ",
1739 retval?" not ":" ");
1741 case OS_WRITE_LAST_MARK:
1742 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1743 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1746 case OS_WRITE_HEADER:
1747 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1748 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1751 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1752 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1754 osst_get_frame_position(STp, aSRpnt);
1756 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1757 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1758 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1761 STp->recover_count++;
1762 STp->recover_erreg++;
1766 STps->rw = rw_state;
1770 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt,
1771 int mt_op, int mt_count)
1773 char * name = tape_name(STp);
1775 int last_mark_ppos = -1;
1778 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1780 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1782 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1786 if (STp->linux_media_version >= 4) {
1788 * direct lookup in header filemark list
1790 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1791 if (STp->header_ok &&
1792 STp->header_cache != NULL &&
1793 (cnt - mt_count) >= 0 &&
1794 (cnt - mt_count) < OS_FM_TAB_MAX &&
1795 (cnt - mt_count) < STp->filemark_cnt &&
1796 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1798 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1800 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1801 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1802 STp->header_cache == NULL?"lack of header cache":"count out of range");
1804 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1806 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1807 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1808 STp->buffer->aux->last_mark_ppos))?"match":"error",
1809 mt_count, last_mark_ppos);
1811 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1812 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1813 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1816 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1820 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1821 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1822 name, last_mark_ppos);
1828 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1832 while (cnt != mt_count) {
1833 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1834 if (last_mark_ppos == -1)
1837 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1839 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1841 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1843 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1847 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1848 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1849 name, last_mark_ppos);
1854 if (mt_op == MTBSFM) {
1855 STp->frame_seq_number++;
1856 STp->frame_in_buffer = 0;
1857 STp->buffer->buffer_bytes = 0;
1858 STp->buffer->read_pointer = 0;
1859 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1865 * ADRL 1.1 compatible "slow" space filemarks fwd version
1867 * Just scans for the filemark sequentially.
1869 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt,
1870 int mt_op, int mt_count)
1874 char * name = tape_name(STp);
1876 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1878 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1880 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1885 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1887 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1891 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1893 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1895 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1897 if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1899 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1900 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1902 STp->eod_frame_ppos = STp->first_frame_position-1;
1906 if (cnt == mt_count)
1908 STp->frame_in_buffer = 0;
1910 if (mt_op == MTFSF) {
1911 STp->frame_seq_number++;
1912 STp->frame_in_buffer = 0;
1913 STp->buffer->buffer_bytes = 0;
1914 STp->buffer->read_pointer = 0;
1915 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1921 * Fast linux specific version of OnStream FSF
1923 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt,
1924 int mt_op, int mt_count)
1926 char * name = tape_name(STp);
1928 next_mark_ppos = -1;
1931 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
1933 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1935 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1940 if (STp->linux_media_version >= 4) {
1942 * direct lookup in header filemark list
1944 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
1945 if (STp->header_ok &&
1946 STp->header_cache != NULL &&
1947 (cnt + mt_count) < OS_FM_TAB_MAX &&
1948 (cnt + mt_count) < STp->filemark_cnt &&
1949 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1950 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
1952 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
1954 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
1955 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1956 STp->header_cache == NULL?"lack of header cache":"count out of range");
1958 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1960 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1961 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
1962 STp->buffer->aux->last_mark_ppos))?"match":"error",
1963 mt_count, next_mark_ppos);
1965 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
1967 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1969 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1971 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
1972 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1974 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
1979 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1980 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1981 name, next_mark_ppos);
1984 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
1985 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
1986 name, cnt+mt_count, next_mark_ppos,
1987 ntohl(STp->buffer->aux->filemark_cnt));
1993 * Find nearest (usually previous) marker, then jump from marker to marker
1996 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1998 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
2000 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
2004 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
2005 if (STp->first_mark_ppos == -1) {
2007 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2009 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2011 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
2012 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2015 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2020 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2021 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
2022 name, STp->first_mark_ppos);
2026 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
2032 while (cnt != mt_count) {
2033 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
2034 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
2036 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2038 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
2041 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
2043 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2045 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2047 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2052 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2053 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2054 name, next_mark_ppos);
2059 if (mt_op == MTFSF) {
2060 STp->frame_seq_number++;
2061 STp->frame_in_buffer = 0;
2062 STp->buffer->buffer_bytes = 0;
2063 STp->buffer->read_pointer = 0;
2064 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2070 * In debug mode, we want to see as many errors as possible
2071 * to test the error recovery mechanism.
2074 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries)
2076 unsigned char cmd[MAX_COMMAND_SIZE];
2077 struct osst_request * SRpnt = * aSRpnt;
2078 char * name = tape_name(STp);
2080 memset(cmd, 0, MAX_COMMAND_SIZE);
2081 cmd[0] = MODE_SELECT;
2083 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2085 (STp->buffer)->b_data[0] = cmd[4] - 1;
2086 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
2087 (STp->buffer)->b_data[2] = 0; /* Reserved */
2088 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
2089 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2090 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2091 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2092 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2095 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2097 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2100 if ((STp->buffer)->syscall_result)
2101 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2106 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt)
2109 int this_mark_ppos = STp->first_frame_position;
2110 int this_mark_lbn = STp->logical_blk_num;
2112 char * name = tape_name(STp);
2115 if (STp->raw) return 0;
2117 STp->write_type = OS_WRITE_NEW_MARK;
2119 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2120 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2123 result = osst_flush_write_buffer(STp, aSRpnt);
2124 result |= osst_flush_drive_buffer(STp, aSRpnt);
2125 STp->last_mark_ppos = this_mark_ppos;
2126 STp->last_mark_lbn = this_mark_lbn;
2127 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2128 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2129 if (STp->filemark_cnt++ == 0)
2130 STp->first_mark_ppos = this_mark_ppos;
2134 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt)
2138 char * name = tape_name(STp);
2141 if (STp->raw) return 0;
2143 STp->write_type = OS_WRITE_EOD;
2144 STp->eod_frame_ppos = STp->first_frame_position;
2146 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2147 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2151 result = osst_flush_write_buffer(STp, aSRpnt);
2152 result |= osst_flush_drive_buffer(STp, aSRpnt);
2153 STp->eod_frame_lfa = --(STp->frame_seq_number);
2157 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2159 char * name = tape_name(STp);
2162 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2164 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2165 osst_set_frame_position(STp, aSRpnt, where, 0);
2166 STp->write_type = OS_WRITE_FILLER;
2168 memcpy(STp->buffer->b_data, "Filler", 6);
2169 STp->buffer->buffer_bytes = 6;
2171 if (osst_flush_write_buffer(STp, aSRpnt)) {
2172 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2177 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2179 return osst_flush_drive_buffer(STp, aSRpnt);
2182 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2184 char * name = tape_name(STp);
2188 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2190 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2191 osst_set_frame_position(STp, aSRpnt, where, 0);
2192 STp->write_type = OS_WRITE_HEADER;
2194 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2195 STp->buffer->buffer_bytes = sizeof(os_header_t);
2197 if (osst_flush_write_buffer(STp, aSRpnt)) {
2198 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2202 result = osst_flush_drive_buffer(STp, aSRpnt);
2204 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2209 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod)
2211 os_header_t * header;
2213 char * name = tape_name(STp);
2216 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2218 if (STp->raw) return 0;
2220 if (STp->header_cache == NULL) {
2221 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2222 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2225 memset(STp->header_cache, 0, sizeof(os_header_t));
2227 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2230 if (STp->header_ok) STp->update_frame_cntr++;
2231 else STp->update_frame_cntr = 0;
2233 header = STp->header_cache;
2234 strcpy(header->ident_str, "ADR_SEQ");
2235 header->major_rev = 1;
2236 header->minor_rev = 4;
2237 header->ext_trk_tb_off = htons(17192);
2238 header->pt_par_num = 1;
2239 header->partition[0].partition_num = OS_DATA_PARTITION;
2240 header->partition[0].par_desc_ver = OS_PARTITION_VERSION;
2241 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2242 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2243 header->partition[0].last_frame_ppos = htonl(STp->capacity);
2244 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2245 header->cfg_col_width = htonl(20);
2246 header->dat_col_width = htonl(1500);
2247 header->qfa_col_width = htonl(0);
2248 header->ext_track_tb.nr_stream_part = 1;
2249 header->ext_track_tb.et_ent_sz = 32;
2250 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2251 header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2252 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2253 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2254 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa);
2255 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
2256 header->dat_fm_tab.fm_part_num = 0;
2257 header->dat_fm_tab.fm_tab_ent_sz = 4;
2258 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2259 STp->filemark_cnt:OS_FM_TAB_MAX);
2261 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2262 if (STp->update_frame_cntr == 0)
2263 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2264 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2268 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2270 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2273 printk(KERN_ERR "%s:E: Write header failed\n", name);
2275 memcpy(STp->application_sig, "LIN4", 4);
2276 STp->linux_media = 1;
2277 STp->linux_media_version = 4;
2283 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt)
2285 if (STp->header_cache != NULL)
2286 memset(STp->header_cache, 0, sizeof(os_header_t));
2288 STp->logical_blk_num = STp->frame_seq_number = 0;
2289 STp->frame_in_buffer = 0;
2290 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2291 STp->filemark_cnt = 0;
2292 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2293 return osst_write_header(STp, aSRpnt, 1);
2296 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos)
2298 char * name = tape_name(STp);
2299 os_header_t * header;
2302 int linux_media_version,
2308 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2309 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2310 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2311 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2312 if (osst_initiate_read (STp, aSRpnt)) {
2313 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2317 if (osst_read_frame(STp, aSRpnt, 180)) {
2319 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2323 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2324 aux = STp->buffer->aux;
2325 if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2327 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2331 if (ntohl(aux->frame_seq_num) != 0 ||
2332 ntohl(aux->logical_blk_num) != 0 ||
2333 aux->partition.partition_num != OS_CONFIG_PARTITION ||
2334 ntohl(aux->partition.first_frame_ppos) != 0 ||
2335 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2337 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2338 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2339 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2340 ntohl(aux->partition.last_frame_ppos));
2344 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2345 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2346 strlcpy(id_string, header->ident_str, 8);
2348 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2352 update_frame_cntr = ntohl(aux->update_frame_cntr);
2353 if (update_frame_cntr < STp->update_frame_cntr) {
2355 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2356 name, ppos, update_frame_cntr, STp->update_frame_cntr);
2360 if (header->major_rev != 1 || header->minor_rev != 4 ) {
2362 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2363 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2364 header->minor_rev > 4 )? "Invalid" : "Warning:",
2365 header->major_rev, header->minor_rev);
2367 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2371 if (header->pt_par_num != 1)
2372 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2373 name, header->pt_par_num);
2375 memcpy(id_string, aux->application_sig, 4);
2377 if (memcmp(id_string, "LIN", 3) == 0) {
2378 STp->linux_media = 1;
2379 linux_media_version = id_string[3] - '0';
2380 if (linux_media_version != 4)
2381 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2382 name, linux_media_version);
2384 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2387 if (linux_media_version < STp->linux_media_version) {
2389 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2390 name, ppos, linux_media_version);
2394 if (linux_media_version > STp->linux_media_version) {
2396 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2397 name, ppos, linux_media_version);
2399 memcpy(STp->application_sig, id_string, 5);
2400 STp->linux_media_version = linux_media_version;
2401 STp->update_frame_cntr = -1;
2403 if (update_frame_cntr > STp->update_frame_cntr) {
2405 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2406 name, ppos, update_frame_cntr);
2408 if (STp->header_cache == NULL) {
2409 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2410 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2414 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2417 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2418 header = STp->header_cache; /* further accesses from cached (full) copy */
2420 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2421 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2422 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2423 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2424 STp->filemark_cnt = ntohl(aux->filemark_cnt);
2425 STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2426 STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2427 STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2428 STp->update_frame_cntr = update_frame_cntr;
2430 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2431 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2432 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2433 STp->first_data_ppos,
2434 ntohl(header->partition[0].last_frame_ppos),
2435 ntohl(header->partition[0].eod_frame_ppos));
2436 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2437 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2439 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2441 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2443 memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2444 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2445 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2447 if (header->minor_rev == 4 &&
2448 (header->ext_trk_tb_off != htons(17192) ||
2449 header->partition[0].partition_num != OS_DATA_PARTITION ||
2450 header->partition[0].par_desc_ver != OS_PARTITION_VERSION ||
2451 header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2452 header->cfg_col_width != htonl(20) ||
2453 header->dat_col_width != htonl(1500) ||
2454 header->qfa_col_width != htonl(0) ||
2455 header->ext_track_tb.nr_stream_part != 1 ||
2456 header->ext_track_tb.et_ent_sz != 32 ||
2457 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION ||
2458 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2459 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2460 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2461 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) ||
2462 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION ||
2463 header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2464 header->dat_fm_tab.fm_tab_ent_cnt !=
2465 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2466 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2473 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt)
2478 char * name = tape_name(STp);
2480 position = osst_get_frame_position(STp, aSRpnt);
2483 STp->header_ok = STp->linux_media = 1;
2484 STp->linux_media_version = 0;
2487 STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2488 STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2489 STp->eod_frame_ppos = STp->first_data_ppos = -1;
2490 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2492 printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2495 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2496 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2498 first = position==10?0xbae: 5;
2499 last = position==10?0xbb3:10;
2501 for (ppos = first; ppos < last; ppos++)
2502 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2505 first = position==10? 5:0xbae;
2506 last = position==10?10:0xbb3;
2508 for (ppos = first; ppos < last; ppos++)
2509 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2513 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2514 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2515 osst_set_frame_position(STp, aSRpnt, 10, 0);
2518 if (position <= STp->first_data_ppos) {
2519 position = STp->first_data_ppos;
2520 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2522 osst_set_frame_position(STp, aSRpnt, position, 0);
2528 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt)
2530 int frame_position = STp->first_frame_position;
2531 int frame_seq_numbr = STp->frame_seq_number;
2532 int logical_blk_num = STp->logical_blk_num;
2533 int halfway_frame = STp->frame_in_buffer;
2534 int read_pointer = STp->buffer->read_pointer;
2535 int prev_mark_ppos = -1;
2536 int actual_mark_ppos, i, n;
2538 char * name = tape_name(STp);
2540 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2542 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2543 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2545 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2549 if (STp->linux_media_version >= 4) {
2550 for (i=0; i<STp->filemark_cnt; i++)
2551 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2554 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2555 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2556 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2557 if (frame_position != STp->first_frame_position ||
2558 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2559 prev_mark_ppos != actual_mark_ppos ) {
2561 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2562 STp->first_frame_position, frame_position,
2563 STp->frame_seq_number + (halfway_frame?0:1),
2564 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2568 if (halfway_frame) {
2569 /* prepare buffer for append and rewrite on top of original */
2570 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2571 STp->buffer->buffer_bytes = read_pointer;
2572 STp->ps[STp->partition].rw = ST_WRITING;
2575 STp->frame_in_buffer = halfway_frame;
2576 STp->frame_seq_number = frame_seq_numbr;
2577 STp->logical_blk_num = logical_blk_num;
2581 /* Acc. to OnStream, the vers. numbering is the following:
2582 * X.XX for released versions (X=digit),
2583 * XXXY for unreleased versions (Y=letter)
2584 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2585 * This fn makes monoton numbers out of this scheme ...
2587 static unsigned int osst_parse_firmware_rev (const char * str)
2589 if (str[1] == '.') {
2590 return (str[0]-'0')*10000
2594 return (str[0]-'0')*10000
2596 +(str[2]-'0')*100 - 100
2602 * Configure the OnStream SCII tape drive for default operation
2604 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
2606 unsigned char cmd[MAX_COMMAND_SIZE];
2607 char * name = tape_name(STp);
2608 struct osst_request * SRpnt = * aSRpnt;
2609 osst_mode_parameter_header_t * header;
2610 osst_block_size_page_t * bs;
2611 osst_capabilities_page_t * cp;
2612 osst_tape_paramtr_page_t * prm;
2613 int drive_buffer_size;
2615 if (STp->ready != ST_READY) {
2617 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2622 if (STp->os_fw_rev < 10600) {
2623 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2624 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2628 * Configure 32.5KB (data+aux) frame size.
2629 * Get the current frame size from the block size mode page
2631 memset(cmd, 0, MAX_COMMAND_SIZE);
2632 cmd[0] = MODE_SENSE;
2634 cmd[2] = BLOCK_SIZE_PAGE;
2635 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2637 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2638 if (SRpnt == NULL) {
2640 printk(OSST_DEB_MSG "osst :D: Busy\n");
2645 if ((STp->buffer)->syscall_result != 0) {
2646 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2650 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2651 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2654 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2655 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No");
2656 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2657 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2661 * Configure default auto columns mode, 32.5KB transfer mode
2669 memset(cmd, 0, MAX_COMMAND_SIZE);
2670 cmd[0] = MODE_SELECT;
2672 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2674 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2676 if ((STp->buffer)->syscall_result != 0) {
2677 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2682 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2684 * In debug mode, we want to see as many errors as possible
2685 * to test the error recovery mechanism.
2687 osst_set_retries(STp, aSRpnt, 0);
2692 * Set vendor name to 'LIN4' for "Linux support version 4".
2695 memset(cmd, 0, MAX_COMMAND_SIZE);
2696 cmd[0] = MODE_SELECT;
2698 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2700 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2701 header->medium_type = 0; /* Medium Type - ignoring */
2702 header->dsp = 0; /* Reserved */
2703 header->bdl = 0; /* Block Descriptor Length */
2705 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2706 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2707 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2708 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2709 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2710 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2711 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2712 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2714 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2717 if ((STp->buffer)->syscall_result != 0) {
2718 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2719 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2723 memset(cmd, 0, MAX_COMMAND_SIZE);
2724 cmd[0] = MODE_SENSE;
2726 cmd[2] = CAPABILITIES_PAGE;
2727 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2729 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2732 if ((STp->buffer)->syscall_result != 0) {
2733 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2737 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2738 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2739 sizeof(osst_mode_parameter_header_t) + header->bdl);
2741 drive_buffer_size = ntohs(cp->buffer_size) / 2;
2743 memset(cmd, 0, MAX_COMMAND_SIZE);
2744 cmd[0] = MODE_SENSE;
2746 cmd[2] = TAPE_PARAMTR_PAGE;
2747 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2749 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2752 if ((STp->buffer)->syscall_result != 0) {
2753 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2757 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2758 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2759 sizeof(osst_mode_parameter_header_t) + header->bdl);
2761 STp->density = prm->density;
2762 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2764 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2765 name, STp->density, STp->capacity / 32, drive_buffer_size);
2773 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2774 it messes up the block number). */
2775 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward)
2778 char * name = tape_name(STp);
2782 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2783 name, forward ? "forward" : "backward");
2787 /* assumes that the filemark is already read by the drive, so this is low cost */
2788 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2791 /* assumes this is only called if we just read the filemark! */
2792 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2795 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2796 name, forward ? "forward" : "backward");
2802 /* Get the tape position. */
2804 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
2806 unsigned char scmd[MAX_COMMAND_SIZE];
2807 struct osst_request * SRpnt;
2809 char * name = tape_name(STp);
2811 /* KG: We want to be able to use it for checking Write Buffer availability
2812 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2814 char * olddata = STp->buffer->b_data;
2815 int oldsize = STp->buffer->buffer_size;
2817 if (STp->ready != ST_READY) return (-EIO);
2819 memset (scmd, 0, MAX_COMMAND_SIZE);
2820 scmd[0] = READ_POSITION;
2822 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2823 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2824 STp->timeout, MAX_RETRIES, 1);
2826 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2831 if (STp->buffer->syscall_result)
2832 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */
2834 if (result == -EINVAL)
2835 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2837 if (result == -EIO) { /* re-read position - this needs to preserve media errors */
2838 unsigned char mysense[16];
2839 memcpy (mysense, SRpnt->sense, 16);
2840 memset (scmd, 0, MAX_COMMAND_SIZE);
2841 scmd[0] = READ_POSITION;
2842 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2843 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2844 STp->timeout, MAX_RETRIES, 1);
2846 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2847 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2848 SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]);
2850 if (!STp->buffer->syscall_result)
2851 memcpy (SRpnt->sense, mysense, 16);
2853 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2855 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2856 + ((STp->buffer)->b_data[5] << 16)
2857 + ((STp->buffer)->b_data[6] << 8)
2858 + (STp->buffer)->b_data[7];
2859 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2860 + ((STp->buffer)->b_data[ 9] << 16)
2861 + ((STp->buffer)->b_data[10] << 8)
2862 + (STp->buffer)->b_data[11];
2863 STp->cur_frames = (STp->buffer)->b_data[15];
2866 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2867 STp->first_frame_position, STp->last_frame_position,
2868 ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2869 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2873 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2875 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2876 STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2878 STp->first_frame_position = STp->last_frame_position;
2881 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2883 return (result == 0 ? STp->first_frame_position : result);
2887 /* Set the tape block */
2888 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip)
2890 unsigned char scmd[MAX_COMMAND_SIZE];
2891 struct osst_request * SRpnt;
2892 struct st_partstat * STps;
2894 int pp = (ppos == 3000 && !skip)? 0 : ppos;
2895 char * name = tape_name(STp);
2897 if (STp->ready != ST_READY) return (-EIO);
2899 STps = &(STp->ps[STp->partition]);
2901 if (ppos < 0 || ppos > STp->capacity) {
2902 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2903 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2910 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2912 memset (scmd, 0, MAX_COMMAND_SIZE);
2915 scmd[3] = (pp >> 24);
2916 scmd[4] = (pp >> 16);
2917 scmd[5] = (pp >> 8);
2922 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
2928 if ((STp->buffer)->syscall_result != 0) {
2930 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
2931 name, STp->first_frame_position, pp);
2936 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
2937 } while ((pp != ppos) && (pp = ppos));
2938 STp->first_frame_position = STp->last_frame_position = ppos;
2939 STps->eof = ST_NOEOF;
2942 STp->frame_in_buffer = 0;
2946 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT)
2948 struct st_partstat * STps = &(STp->ps[STp->partition]);
2951 if (STp->write_type != OS_WRITE_NEW_MARK) {
2952 /* true unless the user wrote the filemark for us */
2953 result = osst_flush_drive_buffer(STp, aSRpnt);
2954 if (result < 0) goto out;
2955 result = osst_write_filemark(STp, aSRpnt);
2956 if (result < 0) goto out;
2958 if (STps->drv_file >= 0)
2960 STps->drv_block = 0;
2962 result = osst_write_eod(STp, aSRpnt);
2963 osst_write_header(STp, aSRpnt, leave_at_EOT);
2970 /* osst versions of st functions - augmented and stripped to suit OnStream only */
2972 /* Flush the write buffer (never need to write if variable blocksize). */
2973 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt)
2975 int offset, transfer, blks = 0;
2977 unsigned char cmd[MAX_COMMAND_SIZE];
2978 struct osst_request * SRpnt = *aSRpnt;
2979 struct st_partstat * STps;
2980 char * name = tape_name(STp);
2982 if ((STp->buffer)->writing) {
2983 if (SRpnt == (STp->buffer)->last_SRpnt)
2985 { printk(OSST_DEB_MSG
2986 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name);
2988 *aSRpnt = SRpnt = NULL;
2992 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name);
2994 osst_write_behind_check(STp);
2995 if ((STp->buffer)->syscall_result) {
2998 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
2999 name, (STp->buffer)->midlevel_result);
3001 if ((STp->buffer)->midlevel_result == INT_MAX)
3008 if (STp->dirty == 1) {
3011 STps = &(STp->ps[STp->partition]);
3012 STps->rw = ST_WRITING;
3013 offset = STp->buffer->buffer_bytes;
3014 blks = (offset + STp->block_size - 1) / STp->block_size;
3015 transfer = OS_FRAME_SIZE;
3017 if (offset < OS_DATA_SIZE)
3018 osst_zero_buffer_tail(STp->buffer);
3021 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
3022 result = osst_recover_wait_frame(STp, aSRpnt, 1);
3024 memset(cmd, 0, MAX_COMMAND_SIZE);
3029 switch (STp->write_type) {
3033 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
3034 name, blks, STp->frame_seq_number,
3035 STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3037 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3038 STp->logical_blk_num - blks, STp->block_size, blks);
3041 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
3042 STp->logical_blk_num, 0, 0);
3044 case OS_WRITE_NEW_MARK:
3045 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
3046 STp->logical_blk_num++, 0, blks=1);
3048 case OS_WRITE_HEADER:
3049 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
3051 default: /* probably FILLER */
3052 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
3056 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
3057 name, offset, transfer, blks);
3060 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3061 STp->timeout, MAX_RETRIES, 1);
3066 if ((STp->buffer)->syscall_result != 0) {
3069 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3070 name, SRpnt->sense[0], SRpnt->sense[2],
3071 SRpnt->sense[12], SRpnt->sense[13]);
3073 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3074 (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3075 (SRpnt->sense[2] & 0x0f) == NO_SENSE) {
3077 (STp->buffer)->buffer_bytes = 0;
3081 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3082 printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3086 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
3089 STp->first_frame_position++;
3091 (STp->buffer)->buffer_bytes = 0;
3095 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3101 /* Flush the tape buffer. The tape will be positioned correctly unless
3102 seek_next is true. */
3103 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next)
3105 struct st_partstat * STps;
3106 int backspace = 0, result = 0;
3108 char * name = tape_name(STp);
3112 * If there was a bus reset, block further access
3115 if( STp->pos_unknown)
3118 if (STp->ready != ST_READY)
3121 STps = &(STp->ps[STp->partition]);
3122 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
3123 STp->write_type = OS_WRITE_DATA;
3124 return osst_flush_write_buffer(STp, aSRpnt);
3126 if (STp->block_size == 0)
3130 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3133 if (!STp->can_bsr) {
3134 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3135 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3136 (STp->buffer)->buffer_bytes = 0;
3137 (STp->buffer)->read_pointer = 0;
3138 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3142 if (STps->eof == ST_FM_HIT) {
3143 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3145 STps->eof = ST_NOEOF;
3147 if (STps->drv_file >= 0)
3149 STps->drv_block = 0;
3152 if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3153 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3155 else if (STps->eof == ST_FM_HIT) {
3156 if (STps->drv_file >= 0)
3158 STps->drv_block = 0;
3159 STps->eof = ST_NOEOF;
3165 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous)
3167 unsigned char cmd[MAX_COMMAND_SIZE];
3168 struct osst_request * SRpnt;
3171 char * name = tape_name(STp);
3174 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3176 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3178 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3181 /* error recovery may have bumped us past the header partition */
3182 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3184 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3186 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3191 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3192 if (osst_recover_wait_frame(STp, aSRpnt, 1))
3195 // osst_build_stats(STp, &SRpnt);
3197 STp->ps[STp->partition].rw = ST_WRITING;
3198 STp->write_type = OS_WRITE_DATA;
3200 memset(cmd, 0, MAX_COMMAND_SIZE);
3203 cmd[4] = 1; /* one frame at a time... */
3204 blks = STp->buffer->buffer_bytes / STp->block_size;
3207 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3208 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3210 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3211 STp->logical_blk_num - blks, STp->block_size, blks);
3215 STp->write_pending = 1;
3217 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3218 MAX_RETRIES, synchronous);
3224 if (STp->buffer->syscall_result != 0) {
3227 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3229 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3230 (SRpnt->sense[2] & 0x40)) {
3231 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW)
3235 if (osst_write_error_recovery(STp, aSRpnt, 1))
3240 STp->first_frame_position++;
3248 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */
3249 static int do_door_lock(struct osst_tape * STp, int do_lock)
3253 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
3255 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3257 retval = scsi_ioctl(STp->device, cmd, NULL);
3259 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3262 STp->door_locked = ST_LOCK_FAILS;
3267 /* Set the internal state after reset */
3268 static void reset_state(struct osst_tape *STp)
3271 struct st_partstat *STps;
3273 STp->pos_unknown = 0;
3274 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3275 STps = &(STp->ps[i]);
3277 STps->eof = ST_NOEOF;
3279 STps->last_block_valid = 0;
3280 STps->drv_block = -1;
3281 STps->drv_file = -1;
3286 /* Entry points to osst */
3289 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3291 ssize_t total, retval = 0;
3292 ssize_t i, do_count, blks, transfer;
3293 int write_threshold;
3294 int doing_write = 0;
3295 const char __user * b_point;
3296 struct osst_request * SRpnt = NULL;
3297 struct st_modedef * STm;
3298 struct st_partstat * STps;
3299 struct osst_tape * STp = filp->private_data;
3300 char * name = tape_name(STp);
3303 if (mutex_lock_interruptible(&STp->lock))
3304 return (-ERESTARTSYS);
3307 * If we are in the middle of error recovery, don't let anyone
3308 * else try and use this device. Also, if error recovery fails, it
3309 * may try and take the device offline, in which case all further
3310 * access to the device is prohibited.
3312 if( !scsi_block_when_processing_errors(STp->device) ) {
3317 if (STp->ready != ST_READY) {
3318 if (STp->ready == ST_NO_TAPE)
3319 retval = (-ENOMEDIUM);
3324 STm = &(STp->modes[STp->current_mode]);
3325 if (!STm->defined) {
3333 * If there was a bus reset, block further access
3336 if (STp->pos_unknown) {
3343 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3349 if (STp->write_prot) {
3354 /* Write must be integral number of blocks */
3355 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3356 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3357 name, count, STp->block_size<1024?
3358 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3363 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3364 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3365 name, STp->first_frame_position);
3370 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3371 STp->door_locked = ST_LOCKED_AUTO;
3373 STps = &(STp->ps[STp->partition]);
3375 if (STps->rw == ST_READING) {
3377 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3378 STps->drv_file, STps->drv_block);
3380 retval = osst_flush_buffer(STp, &SRpnt, 0);
3385 if (STps->rw != ST_WRITING) {
3386 /* Are we totally rewriting this tape? */
3387 if (!STp->header_ok ||
3388 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3389 (STps->drv_file == 0 && STps->drv_block == 0)) {
3390 STp->wrt_pass_cntr++;
3392 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3393 name, STp->wrt_pass_cntr);
3395 osst_reset_header(STp, &SRpnt);
3396 STps->drv_file = STps->drv_block = 0;
3398 /* Do we know where we'll be writing on the tape? */
3400 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3401 STps->drv_file < 0 || STps->drv_block < 0) {
3402 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3403 STps->drv_file = STp->filemark_cnt;
3404 STps->drv_block = 0;
3407 /* We have no idea where the tape is positioned - give up */
3410 "%s:D: Cannot write at indeterminate position.\n", name);
3416 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3417 STp->filemark_cnt = STps->drv_file;
3418 STp->last_mark_ppos =
3419 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3421 "%s:W: Overwriting file %d with old write pass counter %d\n",
3422 name, STps->drv_file, STp->wrt_pass_cntr);
3424 "%s:W: may lead to stale data being accepted on reading back!\n",
3428 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3429 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3435 if (!STp->header_ok) {
3437 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3443 if ((STp->buffer)->writing) {
3444 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3445 osst_write_behind_check(STp);
3446 if ((STp->buffer)->syscall_result) {
3449 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3450 (STp->buffer)->midlevel_result);
3452 if ((STp->buffer)->midlevel_result == INT_MAX)
3453 STps->eof = ST_EOM_OK;
3455 STps->eof = ST_EOM_ERROR;
3458 if (STps->eof == ST_EOM_OK) {
3462 else if (STps->eof == ST_EOM_ERROR) {
3467 /* Check the buffer readability in cases where copy_user might catch
3468 the problems after some tape movement. */
3469 if ((copy_from_user(&i, buf, 1) != 0 ||
3470 copy_from_user(&i, buf + count - 1, 1) != 0)) {
3475 if (!STm->do_buffer_writes) {
3476 write_threshold = 1;
3479 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3480 if (!STm->do_async_writes)
3486 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3487 name, (int) count, STps->drv_file, STps->drv_block,
3488 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3491 while ((STp->buffer)->buffer_bytes + count > write_threshold)
3494 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3495 (STp->buffer)->buffer_bytes;
3496 if (do_count > count)
3499 i = append_to_buffer(b_point, STp->buffer, do_count);
3505 blks = do_count / STp->block_size;
3506 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3508 i = osst_write_frame(STp, &SRpnt, 1);
3510 if (i == (-ENOSPC)) {
3511 transfer = STp->buffer->writing; /* FIXME -- check this logic */
3512 if (transfer <= do_count) {
3513 filp->f_pos += do_count - transfer;
3514 count -= do_count - transfer;
3515 if (STps->drv_block >= 0) {
3516 STps->drv_block += (do_count - transfer) / STp->block_size;
3518 STps->eof = ST_EOM_OK;
3519 retval = (-ENOSPC); /* EOM within current request */
3522 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3523 name, (int) transfer);
3527 STps->eof = ST_EOM_ERROR;
3528 STps->drv_block = (-1); /* Too cautious? */
3529 retval = (-EIO); /* EOM for old data */
3532 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3540 if (SRpnt != NULL) {
3541 osst_release_request(SRpnt);
3544 STp->buffer->buffer_bytes = 0;
3547 retval = total - count;
3551 filp->f_pos += do_count;
3552 b_point += do_count;
3554 if (STps->drv_block >= 0) {
3555 STps->drv_block += blks;
3557 STp->buffer->buffer_bytes = 0;
3559 } /* end while write threshold exceeded */
3563 i = append_to_buffer(b_point, STp->buffer, count);
3568 blks = count / STp->block_size;
3569 STp->logical_blk_num += blks;
3570 if (STps->drv_block >= 0) {
3571 STps->drv_block += blks;
3573 filp->f_pos += count;
3577 if (doing_write && (STp->buffer)->syscall_result != 0) {
3578 retval = (STp->buffer)->syscall_result;
3582 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3583 /* Schedule an asynchronous write */
3584 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3585 STp->block_size) * STp->block_size;
3586 STp->dirty = !((STp->buffer)->writing ==
3587 (STp->buffer)->buffer_bytes);
3589 i = osst_write_frame(STp, &SRpnt, 0);
3594 SRpnt = NULL; /* Prevent releasing this request! */
3596 STps->at_sm &= (total == 0);
3598 STps->eof = ST_NOEOF;
3603 if (SRpnt != NULL) osst_release_request(SRpnt);
3605 mutex_unlock(&STp->lock);
3612 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3614 ssize_t total, retval = 0;
3615 ssize_t i, transfer;
3617 struct st_modedef * STm;
3618 struct st_partstat * STps;
3619 struct osst_request * SRpnt = NULL;
3620 struct osst_tape * STp = filp->private_data;
3621 char * name = tape_name(STp);
3624 if (mutex_lock_interruptible(&STp->lock))
3625 return (-ERESTARTSYS);
3628 * If we are in the middle of error recovery, don't let anyone
3629 * else try and use this device. Also, if error recovery fails, it
3630 * may try and take the device offline, in which case all further
3631 * access to the device is prohibited.
3633 if( !scsi_block_when_processing_errors(STp->device) ) {
3638 if (STp->ready != ST_READY) {
3639 if (STp->ready == ST_NO_TAPE)
3640 retval = (-ENOMEDIUM);
3645 STm = &(STp->modes[STp->current_mode]);
3646 if (!STm->defined) {
3652 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3657 /* Must have initialized medium */
3658 if (!STp->header_ok) {
3663 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3664 STp->door_locked = ST_LOCKED_AUTO;
3666 STps = &(STp->ps[STp->partition]);
3667 if (STps->rw == ST_WRITING) {
3668 retval = osst_flush_buffer(STp, &SRpnt, 0);
3672 /* FIXME -- this may leave the tape without EOD and up2date headers */
3675 if ((count % STp->block_size) != 0) {
3677 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3678 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3682 if (debugging && STps->eof != ST_NOEOF)
3683 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3684 STps->eof, (STp->buffer)->buffer_bytes);
3686 if ((STp->buffer)->buffer_bytes == 0 &&
3687 STps->eof >= ST_EOD_1) {
3688 if (STps->eof < ST_EOD) {
3693 retval = (-EIO); /* EOM or Blank Check */
3697 /* Check the buffer writability before any tape movement. Don't alter
3699 if (copy_from_user(&i, buf, 1) != 0 ||
3700 copy_to_user (buf, &i, 1) != 0 ||
3701 copy_from_user(&i, buf + count - 1, 1) != 0 ||
3702 copy_to_user (buf + count - 1, &i, 1) != 0) {
3707 /* Loop until enough data in buffer or a special condition found */
3708 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3710 /* Get new data if the buffer is empty */
3711 if ((STp->buffer)->buffer_bytes == 0) {
3712 if (STps->eof == ST_FM_HIT)
3714 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3715 if (special < 0) { /* No need to continue read */
3716 STp->frame_in_buffer = 0;
3722 /* Move the data from driver buffer to user buffer */
3723 if ((STp->buffer)->buffer_bytes > 0) {
3725 if (debugging && STps->eof != ST_NOEOF)
3726 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3727 STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total));
3729 /* force multiple of block size, note block_size may have been adjusted */
3730 transfer = (((STp->buffer)->buffer_bytes < count - total ?
3731 (STp->buffer)->buffer_bytes : count - total)/
3732 STp->block_size) * STp->block_size;
3734 if (transfer == 0) {
3736 "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
3737 name, count, STp->block_size < 1024?
3738 STp->block_size:STp->block_size/1024,
3739 STp->block_size<1024?'b':'k');
3742 i = from_buffer(STp->buffer, buf, transfer);
3747 STp->logical_blk_num += transfer / STp->block_size;
3748 STps->drv_block += transfer / STp->block_size;
3749 filp->f_pos += transfer;
3754 if ((STp->buffer)->buffer_bytes == 0) {
3757 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3758 name, STp->frame_seq_number);
3760 STp->frame_in_buffer = 0;
3761 STp->frame_seq_number++; /* frame to look for next time */
3763 } /* for (total = 0, special = 0; total < count && !special; ) */
3765 /* Change the eof state if no data from tape or buffer */
3767 if (STps->eof == ST_FM_HIT) {
3768 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3769 STps->drv_block = 0;
3770 if (STps->drv_file >= 0)
3773 else if (STps->eof == ST_EOD_1) {
3774 STps->eof = ST_EOD_2;
3775 if (STps->drv_block > 0 && STps->drv_file >= 0)
3777 STps->drv_block = 0;
3779 else if (STps->eof == ST_EOD_2)
3782 else if (STps->eof == ST_FM)
3783 STps->eof = ST_NOEOF;
3788 if (SRpnt != NULL) osst_release_request(SRpnt);
3790 mutex_unlock(&STp->lock);
3796 /* Set the driver options */
3797 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3800 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3801 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3802 STm->do_read_ahead);
3804 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3805 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3807 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3808 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3809 STp->scsi2_logical);
3811 "%s:I: sysv: %d\n", name, STm->sysv);
3814 "%s:D: debugging: %d\n",
3820 static int osst_set_options(struct osst_tape *STp, long options)
3824 struct st_modedef * STm;
3825 char * name = tape_name(STp);
3827 STm = &(STp->modes[STp->current_mode]);
3828 if (!STm->defined) {
3829 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3833 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3834 name, STp->current_mode);
3838 code = options & MT_ST_OPTIONS;
3839 if (code == MT_ST_BOOLEANS) {
3840 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3841 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3842 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3843 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3844 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3845 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3846 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3847 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3848 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3849 if ((STp->device)->scsi_level >= SCSI_2)
3850 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3851 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3852 STm->sysv = (options & MT_ST_SYSV) != 0;
3854 debugging = (options & MT_ST_DEBUGGING) != 0;
3856 osst_log_options(STp, STm, name);
3858 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3859 value = (code == MT_ST_SETBOOLEANS);
3860 if ((options & MT_ST_BUFFER_WRITES) != 0)
3861 STm->do_buffer_writes = value;
3862 if ((options & MT_ST_ASYNC_WRITES) != 0)
3863 STm->do_async_writes = value;
3864 if ((options & MT_ST_DEF_WRITES) != 0)
3865 STm->defaults_for_writes = value;
3866 if ((options & MT_ST_READ_AHEAD) != 0)
3867 STm->do_read_ahead = value;
3868 if ((options & MT_ST_TWO_FM) != 0)
3869 STp->two_fm = value;
3870 if ((options & MT_ST_FAST_MTEOM) != 0)
3871 STp->fast_mteom = value;
3872 if ((options & MT_ST_AUTO_LOCK) != 0)
3873 STp->do_auto_lock = value;
3874 if ((options & MT_ST_CAN_BSR) != 0)
3875 STp->can_bsr = value;
3876 if ((options & MT_ST_NO_BLKLIMS) != 0)
3877 STp->omit_blklims = value;
3878 if ((STp->device)->scsi_level >= SCSI_2 &&
3879 (options & MT_ST_CAN_PARTITIONS) != 0)
3880 STp->can_partitions = value;
3881 if ((options & MT_ST_SCSI2LOGICAL) != 0)
3882 STp->scsi2_logical = value;
3883 if ((options & MT_ST_SYSV) != 0)
3886 if ((options & MT_ST_DEBUGGING) != 0)
3889 osst_log_options(STp, STm, name);
3891 else if (code == MT_ST_WRITE_THRESHOLD) {
3892 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3893 if (value < 1 || value > osst_buffer_size) {
3894 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3898 STp->write_threshold = value;
3899 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3902 else if (code == MT_ST_DEF_BLKSIZE) {
3903 value = (options & ~MT_ST_OPTIONS);
3904 if (value == ~MT_ST_OPTIONS) {
3905 STm->default_blksize = (-1);
3906 printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3909 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3910 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3914 STm->default_blksize = value;
3915 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
3916 name, STm->default_blksize);
3919 else if (code == MT_ST_TIMEOUTS) {
3920 value = (options & ~MT_ST_OPTIONS);
3921 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
3922 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
3923 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
3924 (value & ~MT_ST_SET_LONG_TIMEOUT));
3927 STp->timeout = value * HZ;
3928 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
3931 else if (code == MT_ST_DEF_OPTIONS) {
3932 code = (options & ~MT_ST_CLEAR_DEFAULT);
3933 value = (options & MT_ST_CLEAR_DEFAULT);
3934 if (code == MT_ST_DEF_DENSITY) {
3935 if (value == MT_ST_CLEAR_DEFAULT) {
3936 STm->default_density = (-1);
3937 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
3940 STm->default_density = value & 0xff;
3941 printk(KERN_INFO "%s:I: Density default set to %x\n",
3942 name, STm->default_density);
3945 else if (code == MT_ST_DEF_DRVBUFFER) {
3946 if (value == MT_ST_CLEAR_DEFAULT) {
3947 STp->default_drvbuffer = 0xff;
3948 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
3951 STp->default_drvbuffer = value & 7;
3952 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
3953 name, STp->default_drvbuffer);
3956 else if (code == MT_ST_DEF_COMPRESSION) {
3957 if (value == MT_ST_CLEAR_DEFAULT) {
3958 STm->default_compression = ST_DONT_TOUCH;
3959 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
3962 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
3963 printk(KERN_INFO "%s:I: Compression default set to %x\n",
3975 /* Internal ioctl function */
3976 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt,
3977 unsigned int cmd_in, unsigned long arg)
3981 int i, ioctl_result;
3983 unsigned char cmd[MAX_COMMAND_SIZE];
3984 struct osst_request * SRpnt = * aSRpnt;
3985 struct st_partstat * STps;
3986 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
3987 int datalen = 0, direction = DMA_NONE;
3988 char * name = tape_name(STp);
3990 if (STp->ready != ST_READY && cmd_in != MTLOAD) {
3991 if (STp->ready == ST_NO_TAPE)
3992 return (-ENOMEDIUM);
3996 timeout = STp->long_timeout;
3997 STps = &(STp->ps[STp->partition]);
3998 fileno = STps->drv_file;
3999 blkno = STps->drv_block;
4000 at_sm = STps->at_sm;
4001 frame_seq_numbr = STp->frame_seq_number;
4002 logical_blk_num = STp->logical_blk_num;
4004 memset(cmd, 0, MAX_COMMAND_SIZE);
4007 chg_eof = 0; /* Changed from the FSF after this */
4011 if (STp->linux_media)
4012 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
4014 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
4018 at_sm &= (arg == 0);
4022 chg_eof = 0; /* Changed from the FSF after this */
4026 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
4029 blkno = (-1); /* We can't know the block number */
4030 at_sm &= (arg == 0);
4037 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
4038 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
4040 if (cmd_in == MTFSR) {
4041 logical_blk_num += arg;
4042 if (blkno >= 0) blkno += arg;
4045 logical_blk_num -= arg;
4046 if (blkno >= 0) blkno -= arg;
4048 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
4049 fileno = STps->drv_file;
4050 blkno = STps->drv_block;
4051 at_sm &= (arg == 0);
4056 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4057 cmd[2] = (arg >> 16);
4058 cmd[3] = (arg >> 8);
4062 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4063 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4066 blkno = fileno = (-1);
4072 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4074 cmd[2] = (ltmp >> 16);
4075 cmd[3] = (ltmp >> 8);
4081 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4082 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4087 blkno = fileno = (-1);
4092 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4093 STp->write_type = OS_WRITE_DATA;
4094 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4099 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4101 for (i=0; i<arg; i++)
4102 ioctl_result |= osst_write_filemark(STp, &SRpnt);
4103 if (fileno >= 0) fileno += arg;
4104 if (blkno >= 0) blkno = 0;
4108 if (STp->write_prot)
4112 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
4113 if (cmd_in == MTWSM)
4115 cmd[2] = (arg >> 16);
4116 cmd[3] = (arg >> 8);
4118 timeout = STp->timeout;
4121 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4122 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4127 at_sm = (cmd_in == MTWSM);
4133 cmd[0] = START_STOP;
4134 cmd[1] = 1; /* Don't wait for completion */
4135 if (cmd_in == MTLOAD) {
4136 if (STp->ready == ST_NO_TAPE)
4137 cmd[4] = 4; /* open tray */
4139 cmd[4] = 1; /* load */
4141 if (cmd_in == MTRETEN)
4142 cmd[4] = 3; /* retension then mount */
4143 if (cmd_in == MTOFFL)
4144 cmd[4] = 4; /* rewind then eject */
4145 timeout = STp->timeout;
4150 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4153 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4156 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4159 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4164 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4169 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4171 return 0; /* Should do something ? */
4176 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4178 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4179 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4180 ioctl_result = -EIO;
4183 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4185 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4187 ioctl_result = -EIO;
4190 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4191 fileno = STp->filemark_cnt;
4196 if (STp->write_prot)
4198 ioctl_result = osst_reset_header(STp, &SRpnt);
4199 i = osst_write_eod(STp, &SRpnt);
4200 if (i < ioctl_result) ioctl_result = i;
4201 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4202 if (i < ioctl_result) ioctl_result = i;
4203 fileno = blkno = at_sm = 0 ;
4207 cmd[0] = REZERO_UNIT; /* rewind */
4211 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4213 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4216 case MTSETBLK: /* Set block length */
4217 if ((STps->drv_block == 0 ) &&
4219 ((STp->buffer)->buffer_bytes == 0) &&
4220 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4221 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4222 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4224 * Only allowed to change the block size if you opened the
4225 * device at the beginning of a file before writing anything.
4226 * Note, that when reading, changing block_size is futile,
4227 * as the size used when writing overrides it.
4229 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4230 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4231 name, STp->block_size);
4234 case MTSETDENSITY: /* Set tape density */
4235 case MTSETDRVBUFFER: /* Set drive buffering */
4236 case SET_DENS_AND_BLK: /* Set density and block size */
4238 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4239 return (-EIO); /* Not allowed if data in buffer */
4240 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4241 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4242 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4243 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4244 name, (int)(arg & MT_ST_BLKSIZE_MASK),
4245 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4248 return 0; /* FIXME silently ignore if block size didn't change */
4254 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4256 ioctl_result = (STp->buffer)->syscall_result;
4260 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4262 return ioctl_result;
4265 if (!ioctl_result) { /* SCSI command successful */
4266 STp->frame_seq_number = frame_seq_numbr;
4267 STp->logical_blk_num = logical_blk_num;
4273 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4276 if (!ioctl_result) { /* success */
4278 if (cmd_in == MTFSFM) {
4282 if (cmd_in == MTBSFM) {
4286 STps->drv_block = blkno;
4287 STps->drv_file = fileno;
4288 STps->at_sm = at_sm;
4290 if (cmd_in == MTEOM)
4292 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4293 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4295 STp->logical_blk_num++;
4296 STp->frame_seq_number++;
4297 STp->frame_in_buffer = 0;
4298 STp->buffer->read_pointer = 0;
4300 else if (cmd_in == MTFSF)
4301 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4303 STps->eof = ST_NOEOF;
4305 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4306 STp->rew_at_close = 0;
4307 else if (cmd_in == MTLOAD) {
4308 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4309 STp->ps[i].rw = ST_IDLE;
4310 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4315 if (cmd_in == MTREW) {
4316 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4317 if (ioctl_result > 0)
4321 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4322 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4323 STps->drv_file = STps->drv_block = -1;
4325 STps->drv_file = STps->drv_block = 0;
4326 STps->eof = ST_NOEOF;
4327 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4328 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4329 STps->drv_file = STps->drv_block = -1;
4331 STps->drv_file = STp->filemark_cnt;
4332 STps->drv_block = 0;
4335 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4336 STps->drv_file = STps->drv_block = (-1);
4337 STps->eof = ST_NOEOF;
4339 } else if (cmd_in == MTERASE) {
4341 } else if (SRpnt) { /* SCSI command was not completely successful. */
4342 if (SRpnt->sense[2] & 0x40) {
4343 STps->eof = ST_EOM_OK;
4344 STps->drv_block = 0;
4347 STps->eof = ST_NOEOF;
4349 if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK)
4352 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4353 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4357 return ioctl_result;
4361 /* Open the device */
4362 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4364 unsigned short flags;
4365 int i, b_size, new_session = 0, retval = 0;
4366 unsigned char cmd[MAX_COMMAND_SIZE];
4367 struct osst_request * SRpnt = NULL;
4368 struct osst_tape * STp;
4369 struct st_modedef * STm;
4370 struct st_partstat * STps;
4372 int dev = TAPE_NR(inode);
4373 int mode = TAPE_MODE(inode);
4376 * We really want to do nonseekable_open(inode, filp); here, but some
4377 * versions of tar incorrectly call lseek on tapes and bail out if that
4378 * fails. So we disallow pread() and pwrite(), but permit lseeks.
4380 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
4382 write_lock(&os_scsi_tapes_lock);
4383 if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4384 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4385 write_unlock(&os_scsi_tapes_lock);
4389 name = tape_name(STp);
4392 write_unlock(&os_scsi_tapes_lock);
4394 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4398 if (scsi_device_get(STp->device)) {
4399 write_unlock(&os_scsi_tapes_lock);
4401 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4405 filp->private_data = STp;
4407 write_unlock(&os_scsi_tapes_lock);
4408 STp->rew_at_close = TAPE_REWIND(inode);
4410 if( !scsi_block_when_processing_errors(STp->device) ) {
4414 if (mode != STp->current_mode) {
4417 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4418 name, STp->current_mode, mode);
4421 STp->current_mode = mode;
4423 STm = &(STp->modes[STp->current_mode]);
4425 flags = filp->f_flags;
4426 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4428 STp->raw = TAPE_IS_RAW(inode);
4432 /* Allocate data segments for this device's tape buffer */
4433 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4434 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4435 retval = (-EOVERFLOW);
4438 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4439 for (i = 0, b_size = 0;
4440 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4441 b_size += STp->buffer->sg[i++].length);
4442 STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
4444 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4445 STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4446 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4447 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4450 STp->buffer->aux = NULL; /* this had better never happen! */
4451 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4455 STp->buffer->writing = 0;
4456 STp->buffer->syscall_result = 0;
4458 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4459 STps = &(STp->ps[i]);
4462 STp->ready = ST_READY;
4464 STp->nbr_waits = STp->nbr_finished = 0;
4467 memset (cmd, 0, MAX_COMMAND_SIZE);
4468 cmd[0] = TEST_UNIT_READY;
4470 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4472 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
4475 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4476 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4477 SRpnt->sense[12] == 4 ) {
4479 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]);
4481 if (filp->f_flags & O_NONBLOCK) {
4485 if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */
4486 memset (cmd, 0, MAX_COMMAND_SIZE);
4487 cmd[0] = START_STOP;
4490 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4491 STp->timeout, MAX_RETRIES, 1);
4493 osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
4495 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4496 (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4498 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4502 for (i=0; i < 10; i++) {
4504 memset (cmd, 0, MAX_COMMAND_SIZE);
4505 cmd[0] = TEST_UNIT_READY;
4507 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4508 STp->timeout, MAX_RETRIES, 1);
4509 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4510 (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
4514 STp->pos_unknown = 0;
4515 STp->partition = STp->new_partition = 0;
4516 if (STp->can_partitions)
4517 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4518 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4519 STps = &(STp->ps[i]);
4520 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4521 STps->eof = ST_NOEOF;
4523 STps->last_block_valid = 0;
4524 STps->drv_block = 0;
4525 STps->drv_file = 0 ;
4528 STp->recover_count = 0;
4529 STp->abort_count = 0;
4532 * if we have valid headers from before, and the drive/tape seem untouched,
4533 * open without reconfiguring and re-reading the headers
4535 if (!STp->buffer->syscall_result && STp->header_ok &&
4536 !SRpnt->result && SRpnt->sense[0] == 0) {
4538 memset(cmd, 0, MAX_COMMAND_SIZE);
4539 cmd[0] = MODE_SENSE;
4541 cmd[2] = VENDOR_IDENT_PAGE;
4542 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4544 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4546 if (STp->buffer->syscall_result ||
4547 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4548 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4549 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4550 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4552 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4553 STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4554 STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4555 STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4556 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4560 i = STp->first_frame_position;
4561 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4562 if (STp->door_locked == ST_UNLOCKED) {
4563 if (do_door_lock(STp, 1))
4564 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4566 STp->door_locked = ST_LOCKED_AUTO;
4568 if (!STp->frame_in_buffer) {
4569 STp->block_size = (STm->default_blksize > 0) ?
4570 STm->default_blksize : OS_DATA_SIZE;
4571 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4573 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4575 osst_release_request(SRpnt);
4579 if (i != STp->first_frame_position)
4580 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4581 name, i, STp->first_frame_position);
4587 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4588 (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) {
4590 memset(cmd, 0, MAX_COMMAND_SIZE);
4591 cmd[0] = MODE_SELECT;
4593 cmd[4] = 4 + MODE_HEADER_LENGTH;
4595 (STp->buffer)->b_data[0] = cmd[4] - 1;
4596 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4597 (STp->buffer)->b_data[2] = 0; /* Reserved */
4598 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4599 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4600 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4601 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4602 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4605 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4607 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4611 for (i=0; i < 10; i++) {
4613 memset (cmd, 0, MAX_COMMAND_SIZE);
4614 cmd[0] = TEST_UNIT_READY;
4616 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4617 STp->timeout, MAX_RETRIES, 1);
4618 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4619 (SRpnt->sense[2] & 0x0f) == NOT_READY)
4622 if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
4623 STp->pos_unknown = 0;
4624 STp->partition = STp->new_partition = 0;
4625 if (STp->can_partitions)
4626 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4627 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4628 STps = &(STp->ps[i]);
4630 STps->eof = ST_NOEOF;
4632 STps->last_block_valid = 0;
4633 STps->drv_block = 0;
4634 STps->drv_file = 0 ;
4641 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4642 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4644 if ((STp->buffer)->syscall_result != 0) {
4645 if ((STp->device)->scsi_level >= SCSI_2 &&
4646 (SRpnt->sense[0] & 0x70) == 0x70 &&
4647 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4648 SRpnt->sense[12] == 0x3a) { /* Check ASC */
4649 STp->ready = ST_NO_TAPE;
4651 STp->ready = ST_NOT_READY;
4652 osst_release_request(SRpnt);
4654 STp->density = 0; /* Clear the erroneous "residue" */
4655 STp->write_prot = 0;
4656 STp->block_size = 0;
4657 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4658 STp->partition = STp->new_partition = 0;
4659 STp->door_locked = ST_UNLOCKED;
4663 osst_configure_onstream(STp, &SRpnt);
4665 STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4666 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4667 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4668 STp->buffer->buffer_bytes =
4669 STp->buffer->read_pointer =
4670 STp->frame_in_buffer = 0;
4674 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4675 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4676 (STp->buffer)->buffer_blocks);
4679 if (STp->drv_write_prot) {
4680 STp->write_prot = 1;
4683 printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4685 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4691 if (new_session) { /* Change the drive parameters for the new mode */
4694 printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4696 STp->density_changed = STp->blksize_changed = 0;
4697 STp->compression_changed = 0;
4701 * properly position the tape and check the ADR headers
4703 if (STp->door_locked == ST_UNLOCKED) {
4704 if (do_door_lock(STp, 1))
4705 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4707 STp->door_locked = ST_LOCKED_AUTO;
4710 osst_analyze_headers(STp, &SRpnt);
4712 osst_release_request(SRpnt);
4719 osst_release_request(SRpnt);
4720 normalize_buffer(STp->buffer);
4723 scsi_device_put(STp->device);
4729 /* Flush the tape buffer before close */
4730 static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
4732 int result = 0, result2;
4733 struct osst_tape * STp = filp->private_data;
4734 struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4735 struct st_partstat * STps = &(STp->ps[STp->partition]);
4736 struct osst_request * SRpnt = NULL;
4737 char * name = tape_name(STp);
4739 if (file_count(filp) > 1)
4742 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4743 STp->write_type = OS_WRITE_DATA;
4744 result = osst_flush_write_buffer(STp, &SRpnt);
4745 if (result != 0 && result != (-ENOSPC))
4748 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4752 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4753 name, (long)(filp->f_pos));
4754 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4755 name, STp->nbr_waits, STp->nbr_finished);
4758 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4761 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4762 name, 1+STp->two_fm);
4765 else if (!STp->rew_at_close) {
4766 STps = &(STp->ps[STp->partition]);
4767 if (!STm->sysv || STps->rw != ST_READING) {
4769 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4770 else if (STps->eof == ST_FM_HIT) {
4771 result = cross_eof(STp, &SRpnt, 0);
4773 if (STps->drv_file >= 0)
4775 STps->drv_block = 0;
4779 STps->eof = ST_NOEOF;
4782 else if ((STps->eof == ST_NOEOF &&
4783 !(result = cross_eof(STp, &SRpnt, 1))) ||
4784 STps->eof == ST_FM_HIT) {
4785 if (STps->drv_file >= 0)
4787 STps->drv_block = 0;
4793 if (STp->rew_at_close) {
4794 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4795 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4796 if (result == 0 && result2 < 0)
4799 if (SRpnt) osst_release_request(SRpnt);
4801 if (STp->abort_count || STp->recover_count) {
4802 printk(KERN_INFO "%s:I:", name);
4803 if (STp->abort_count)
4804 printk(" %d unrecovered errors", STp->abort_count);
4805 if (STp->recover_count)
4806 printk(" %d recovered errors", STp->recover_count);
4807 if (STp->write_count)
4808 printk(" in %d frames written", STp->write_count);
4809 if (STp->read_count)
4810 printk(" in %d frames read", STp->read_count);
4812 STp->recover_count = 0;
4813 STp->abort_count = 0;
4815 STp->write_count = 0;
4816 STp->read_count = 0;
4822 /* Close the device and release it */
4823 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4826 struct osst_tape * STp = filp->private_data;
4828 if (STp->door_locked == ST_LOCKED_AUTO)
4829 do_door_lock(STp, 0);
4834 normalize_buffer(STp->buffer);
4835 write_lock(&os_scsi_tapes_lock);
4837 write_unlock(&os_scsi_tapes_lock);
4839 scsi_device_put(STp->device);
4845 /* The ioctl command */
4846 static int osst_ioctl(struct inode * inode,struct file * file,
4847 unsigned int cmd_in, unsigned long arg)
4849 int i, cmd_nr, cmd_type, blk, retval = 0;
4850 struct st_modedef * STm;
4851 struct st_partstat * STps;
4852 struct osst_request * SRpnt = NULL;
4853 struct osst_tape * STp = file->private_data;
4854 char * name = tape_name(STp);
4855 void __user * p = (void __user *)arg;
4857 if (mutex_lock_interruptible(&STp->lock))
4858 return -ERESTARTSYS;
4861 if (debugging && !STp->in_use) {
4862 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4867 STm = &(STp->modes[STp->current_mode]);
4868 STps = &(STp->ps[STp->partition]);
4871 * If we are in the middle of error recovery, don't let anyone
4872 * else try and use this device. Also, if error recovery fails, it
4873 * may try and take the device offline, in which case all further
4874 * access to the device is prohibited.
4876 if( !scsi_block_when_processing_errors(STp->device) ) {
4881 cmd_type = _IOC_TYPE(cmd_in);
4882 cmd_nr = _IOC_NR(cmd_in);
4884 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4885 cmd_type, cmd_nr, STp->raw?"raw":"normal");
4887 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4891 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
4896 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
4902 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
4903 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
4908 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
4913 if (!STp->pos_unknown) {
4915 if (STps->eof == ST_FM_HIT) {
4916 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
4918 if (STps->drv_file >= 0)
4919 STps->drv_file += 1;
4921 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
4923 if (STps->drv_file >= 0)
4924 STps->drv_file += 1;
4928 if (mtc.mt_op == MTSEEK) {
4929 /* Old position must be restored if partition will be changed */
4930 i = !STp->can_partitions || (STp->new_partition != STp->partition);
4933 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
4934 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
4935 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
4936 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
4937 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
4938 mtc.mt_op == MTCOMPRESSION;
4940 i = osst_flush_buffer(STp, &SRpnt, i);
4948 * If there was a bus reset, block further access
4949 * to this device. If the user wants to rewind the tape,
4950 * then reset the flag and allow access again.
4952 if(mtc.mt_op != MTREW &&
4953 mtc.mt_op != MTOFFL &&
4954 mtc.mt_op != MTRETEN &&
4955 mtc.mt_op != MTERASE &&
4956 mtc.mt_op != MTSEEK &&
4957 mtc.mt_op != MTEOM) {
4962 /* remove this when the midlevel properly clears was_reset */
4963 STp->device->was_reset = 0;
4966 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK &&
4967 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
4968 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER &&
4969 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART &&
4970 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) {
4973 * The user tells us to move to another position on the tape.
4974 * If we were appending to the tape content, that would leave
4975 * the tape without proper end, in that case write EOD and
4976 * update the header to reflect its position.
4979 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
4980 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
4981 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
4982 STp->logical_blk_num, STps->drv_file, STps->drv_block );
4984 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
4985 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
4986 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4987 i = osst_write_trailer(STp, &SRpnt,
4988 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4990 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
4991 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
4992 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
5002 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
5003 do_door_lock(STp, 0); /* Ignore result! */
5005 if (mtc.mt_op == MTSETDRVBUFFER &&
5006 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
5007 retval = osst_set_options(STp, mtc.mt_count);
5011 if (mtc.mt_op == MTSETPART) {
5012 if (mtc.mt_count >= STp->nbr_partitions)
5015 STp->new_partition = mtc.mt_count;
5021 if (mtc.mt_op == MTMKPART) {
5022 if (!STp->can_partitions) {
5026 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
5027 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
5031 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5032 STp->ps[i].rw = ST_IDLE;
5033 STp->ps[i].at_sm = 0;
5034 STp->ps[i].last_block_valid = 0;
5036 STp->partition = STp->new_partition = 0;
5037 STp->nbr_partitions = 1; /* Bad guess ?-) */
5038 STps->drv_block = STps->drv_file = 0;
5043 if (mtc.mt_op == MTSEEK) {
5045 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
5047 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
5048 if (!STp->can_partitions)
5049 STp->ps[0].rw = ST_IDLE;
5054 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
5055 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
5060 cross_eof(STp, &SRpnt, 0);
5062 if (mtc.mt_op == MTCOMPRESSION)
5063 retval = -EINVAL; /* OnStream drives don't have compression hardware */
5065 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5066 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5067 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5071 if (!STm->defined) {
5076 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5081 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
5082 struct mtget mt_status;
5084 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
5089 mt_status.mt_type = MT_ISONSTREAM_SC;
5090 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
5091 mt_status.mt_dsreg =
5092 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
5093 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
5094 mt_status.mt_blkno = STps->drv_block;
5095 mt_status.mt_fileno = STps->drv_file;
5096 if (STp->block_size != 0) {
5097 if (STps->rw == ST_WRITING)
5098 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
5099 else if (STps->rw == ST_READING)
5100 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
5101 STp->block_size - 1) / STp->block_size;
5104 mt_status.mt_gstat = 0;
5105 if (STp->drv_write_prot)
5106 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
5107 if (mt_status.mt_blkno == 0) {
5108 if (mt_status.mt_fileno == 0)
5109 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
5111 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
5113 mt_status.mt_resid = STp->partition;
5114 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
5115 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
5116 else if (STps->eof >= ST_EOM_OK)
5117 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
5118 if (STp->density == 1)
5119 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
5120 else if (STp->density == 2)
5121 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
5122 else if (STp->density == 3)
5123 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
5124 if (STp->ready == ST_READY)
5125 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
5126 if (STp->ready == ST_NO_TAPE)
5127 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
5129 mt_status.mt_gstat |= GMT_SM(0xffffffff);
5130 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
5131 STp->drv_buffer != 0)
5132 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
5134 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
5140 STp->recover_erreg = 0; /* Clear after read */
5143 } /* End of MTIOCGET */
5145 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5146 struct mtpos mt_pos;
5148 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5153 blk = osst_get_frame_position(STp, &SRpnt);
5155 blk = osst_get_sector(STp, &SRpnt);
5160 mt_pos.mt_blkno = blk;
5161 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5166 if (SRpnt) osst_release_request(SRpnt);
5168 mutex_unlock(&STp->lock);
5170 return scsi_ioctl(STp->device, cmd_in, p);
5173 if (SRpnt) osst_release_request(SRpnt);
5175 mutex_unlock(&STp->lock);
5180 #ifdef CONFIG_COMPAT
5181 static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg)
5183 struct osst_tape *STp = file->private_data;
5184 struct scsi_device *sdev = STp->device;
5185 int ret = -ENOIOCTLCMD;
5186 if (sdev->host->hostt->compat_ioctl) {
5188 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
5197 /* Memory handling routines */
5199 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5200 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5204 struct osst_buffer *tb;
5206 if (from_initialization)
5207 priority = GFP_ATOMIC;
5209 priority = GFP_KERNEL;
5211 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5212 tb = kzalloc(i, priority);
5214 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5218 tb->sg_segs = tb->orig_sg_segs = 0;
5219 tb->use_sg = max_sg;
5222 tb->buffer_size = 0;
5226 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5227 i, max_sg, need_dma);
5232 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5233 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5235 int segs, nbr, max_segs, b_size, order, got;
5238 if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5241 if (STbuffer->sg_segs) {
5242 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5243 normalize_buffer(STbuffer);
5245 /* See how many segments we can use -- need at least two */
5246 nbr = max_segs = STbuffer->use_sg;
5250 priority = GFP_KERNEL /* | __GFP_NOWARN */;
5252 priority |= GFP_DMA;
5254 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5255 big enough to reach the goal (code assumes no segments in place) */
5256 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5257 struct page *page = alloc_pages(priority, order);
5259 STbuffer->sg[0].offset = 0;
5261 sg_set_page(&STbuffer->sg[0], page, b_size, 0);
5262 STbuffer->b_data = page_address(page);
5266 if (sg_page(&STbuffer->sg[0]) == NULL) {
5267 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5270 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5271 for (segs=STbuffer->sg_segs=1, got=b_size;
5272 segs < max_segs && got < OS_FRAME_SIZE; ) {
5273 struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5274 STbuffer->sg[segs].offset = 0;
5276 if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
5277 b_size /= 2; /* Large enough for the rest of the buffers */
5281 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5284 STbuffer->buffer_size = got;
5286 normalize_buffer(STbuffer);
5289 sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0);
5290 got += STbuffer->sg[segs].length;
5291 STbuffer->buffer_size = got;
5292 STbuffer->sg_segs = ++segs;
5297 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5298 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5300 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5301 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5302 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5310 /* Release the segments */
5311 static void normalize_buffer(struct osst_buffer *STbuffer)
5313 int i, order, b_size;
5315 for (i=0; i < STbuffer->sg_segs; i++) {
5317 for (b_size = PAGE_SIZE, order = 0;
5318 b_size < STbuffer->sg[i].length;
5319 b_size *= 2, order++);
5321 __free_pages(sg_page(&STbuffer->sg[i]), order);
5322 STbuffer->buffer_size -= STbuffer->sg[i].length;
5325 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5326 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5327 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5329 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5333 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5334 negative error code. */
5335 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
5337 int i, cnt, res, offset;
5339 for (i=0, offset=st_bp->buffer_bytes;
5340 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5341 offset -= st_bp->sg[i].length;
5342 if (i == st_bp->sg_segs) { /* Should never happen */
5343 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5346 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5347 cnt = st_bp->sg[i].length - offset < do_count ?
5348 st_bp->sg[i].length - offset : do_count;
5349 res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
5353 st_bp->buffer_bytes += cnt;
5357 if (do_count) { /* Should never happen */
5358 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5366 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5367 negative error code. */
5368 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
5370 int i, cnt, res, offset;
5372 for (i=0, offset=st_bp->read_pointer;
5373 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5374 offset -= st_bp->sg[i].length;
5375 if (i == st_bp->sg_segs) { /* Should never happen */
5376 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5379 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5380 cnt = st_bp->sg[i].length - offset < do_count ?
5381 st_bp->sg[i].length - offset : do_count;
5382 res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
5386 st_bp->buffer_bytes -= cnt;
5387 st_bp->read_pointer += cnt;
5391 if (do_count) { /* Should never happen */
5392 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5398 /* Sets the tail of the buffer after fill point to zero.
5399 Returns zero (success) or negative error code. */
5400 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
5402 int i, offset, do_count, cnt;
5404 for (i = 0, offset = st_bp->buffer_bytes;
5405 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5406 offset -= st_bp->sg[i].length;
5407 if (i == st_bp->sg_segs) { /* Should never happen */
5408 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5411 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5412 i < st_bp->sg_segs && do_count > 0; i++) {
5413 cnt = st_bp->sg[i].length - offset < do_count ?
5414 st_bp->sg[i].length - offset : do_count ;
5415 memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
5419 if (do_count) { /* Should never happen */
5420 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5426 /* Copy a osst 32K chunk of memory into the buffer.
5427 Returns zero (success) or negative error code. */
5428 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5430 int i, cnt, do_count = OS_DATA_SIZE;
5432 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5433 cnt = st_bp->sg[i].length < do_count ?
5434 st_bp->sg[i].length : do_count ;
5435 memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
5439 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5440 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5447 /* Copy a osst 32K chunk of memory from the buffer.
5448 Returns zero (success) or negative error code. */
5449 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5451 int i, cnt, do_count = OS_DATA_SIZE;
5453 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5454 cnt = st_bp->sg[i].length < do_count ?
5455 st_bp->sg[i].length : do_count ;
5456 memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
5460 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5461 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5469 /* Module housekeeping */
5471 static void validate_options (void)
5474 osst_max_dev = max_dev;
5475 if (write_threshold_kbs > 0)
5476 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5477 if (osst_write_threshold > osst_buffer_size)
5478 osst_write_threshold = osst_buffer_size;
5479 if (max_sg_segs >= OSST_FIRST_SG)
5480 osst_max_sg_segs = max_sg_segs;
5482 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5483 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5488 /* Set the boot options. Syntax: osst=xxx,yyy,...
5489 where xxx is write threshold in 1024 byte blocks,
5490 and yyy is number of s/g segments to use. */
5491 static int __init osst_setup (char *str)
5496 stp = get_options(str, ARRAY_SIZE(ints), ints);
5499 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5500 *parms[i].val = ints[i + 1];
5502 while (stp != NULL) {
5503 for (i = 0; i < ARRAY_SIZE(parms); i++) {
5504 int len = strlen(parms[i].name);
5505 if (!strncmp(stp, parms[i].name, len) &&
5506 (*(stp + len) == ':' || *(stp + len) == '=')) {
5508 simple_strtoul(stp + len + 1, NULL, 0);
5512 if (i >= ARRAY_SIZE(parms))
5513 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5515 stp = strchr(stp, ',');
5524 __setup("osst=", osst_setup);
5528 static const struct file_operations osst_fops = {
5529 .owner = THIS_MODULE,
5531 .write = osst_write,
5532 .ioctl = osst_ioctl,
5533 #ifdef CONFIG_COMPAT
5534 .compat_ioctl = osst_compat_ioctl,
5536 .open = os_scsi_tape_open,
5537 .flush = os_scsi_tape_flush,
5538 .release = os_scsi_tape_close,
5541 static int osst_supports(struct scsi_device * SDp)
5543 struct osst_support_data {
5547 char *driver_hint; /* Name of the correct driver, NULL if unknown */
5550 static struct osst_support_data support_list[] = {
5551 /* {"XXX", "Yy-", "", NULL}, example */
5555 struct osst_support_data *rp;
5557 /* We are willing to drive OnStream SC-x0 as well as the
5558 * * IDE, ParPort, FireWire, USB variants, if accessible by
5559 * * emulation layer (ide-scsi, usb-storage, ...) */
5561 for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5562 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5563 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5564 !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5570 * sysfs support for osst driver parameter information
5573 static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
5575 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
5578 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
5580 static int osst_create_sysfs_files(struct device_driver *sysfs)
5582 return driver_create_file(sysfs, &driver_attr_version);
5585 static void osst_remove_sysfs_files(struct device_driver *sysfs)
5587 driver_remove_file(sysfs, &driver_attr_version);
5591 * sysfs support for accessing ADR header information
5594 static ssize_t osst_adr_rev_show(struct device *dev,
5595 struct device_attribute *attr, char *buf)
5597 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5600 if (STp && STp->header_ok && STp->linux_media)
5601 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
5605 DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
5607 static ssize_t osst_linux_media_version_show(struct device *dev,
5608 struct device_attribute *attr,
5611 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5614 if (STp && STp->header_ok && STp->linux_media)
5615 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
5619 DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
5621 static ssize_t osst_capacity_show(struct device *dev,
5622 struct device_attribute *attr, char *buf)
5624 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5627 if (STp && STp->header_ok && STp->linux_media)
5628 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
5632 DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
5634 static ssize_t osst_first_data_ppos_show(struct device *dev,
5635 struct device_attribute *attr,
5638 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5641 if (STp && STp->header_ok && STp->linux_media)
5642 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
5646 DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
5648 static ssize_t osst_eod_frame_ppos_show(struct device *dev,
5649 struct device_attribute *attr,
5652 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5655 if (STp && STp->header_ok && STp->linux_media)
5656 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
5660 DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
5662 static ssize_t osst_filemark_cnt_show(struct device *dev,
5663 struct device_attribute *attr, char *buf)
5665 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5668 if (STp && STp->header_ok && STp->linux_media)
5669 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
5673 DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5675 static struct class *osst_sysfs_class;
5677 static int osst_sysfs_init(void)
5679 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
5680 if (IS_ERR(osst_sysfs_class)) {
5681 printk(KERN_ERR "osst :W: Unable to register sysfs class\n");
5682 return PTR_ERR(osst_sysfs_class);
5688 static void osst_sysfs_destroy(dev_t dev)
5690 device_destroy(osst_sysfs_class, dev);
5693 static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5695 struct device *osst_member;
5698 osst_member = device_create_drvdata(osst_sysfs_class, device, dev, STp, "%s", name);
5699 if (IS_ERR(osst_member)) {
5700 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5701 return PTR_ERR(osst_member);
5704 err = device_create_file(osst_member, &dev_attr_ADR_rev);
5707 err = device_create_file(osst_member, &dev_attr_media_version);
5710 err = device_create_file(osst_member, &dev_attr_capacity);
5713 err = device_create_file(osst_member, &dev_attr_BOT_frame);
5716 err = device_create_file(osst_member, &dev_attr_EOD_frame);
5719 err = device_create_file(osst_member, &dev_attr_file_count);
5726 osst_sysfs_destroy(dev);
5730 static void osst_sysfs_cleanup(void)
5732 class_destroy(osst_sysfs_class);
5736 * osst startup / cleanup code
5739 static int osst_probe(struct device *dev)
5741 struct scsi_device * SDp = to_scsi_device(dev);
5742 struct osst_tape * tpnt;
5743 struct st_modedef * STm;
5744 struct st_partstat * STps;
5745 struct osst_buffer * buffer;
5746 struct gendisk * drive;
5747 int i, dev_num, err = -ENODEV;
5749 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5752 drive = alloc_disk(1);
5754 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5758 /* if this is the first attach, build the infrastructure */
5759 write_lock(&os_scsi_tapes_lock);
5760 if (os_scsi_tapes == NULL) {
5762 (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *),
5764 if (os_scsi_tapes == NULL) {
5765 write_unlock(&os_scsi_tapes_lock);
5766 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5769 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5772 if (osst_nr_dev >= osst_max_dev) {
5773 write_unlock(&os_scsi_tapes_lock);
5774 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5778 /* find a free minor number */
5779 for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++);
5780 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5783 /* allocate a struct osst_tape for this device */
5784 tpnt = kzalloc(sizeof(struct osst_tape), GFP_ATOMIC);
5786 write_unlock(&os_scsi_tapes_lock);
5787 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5791 /* allocate a buffer for this device */
5792 i = SDp->host->sg_tablesize;
5793 if (osst_max_sg_segs < i)
5794 i = osst_max_sg_segs;
5795 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
5796 if (buffer == NULL) {
5797 write_unlock(&os_scsi_tapes_lock);
5798 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5802 os_scsi_tapes[dev_num] = tpnt;
5803 tpnt->buffer = buffer;
5805 drive->private_data = &tpnt->driver;
5806 sprintf(drive->disk_name, "osst%d", dev_num);
5807 tpnt->driver = &osst_template;
5808 tpnt->drive = drive;
5810 tpnt->capacity = 0xfffff;
5812 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
5813 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5815 tpnt->do_auto_lock = OSST_AUTO_LOCK;
5816 tpnt->can_bsr = OSST_IN_FILE_POS;
5817 tpnt->can_partitions = 0;
5818 tpnt->two_fm = OSST_TWO_FM;
5819 tpnt->fast_mteom = OSST_FAST_MTEOM;
5820 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5821 tpnt->write_threshold = osst_write_threshold;
5822 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5823 tpnt->partition = 0;
5824 tpnt->new_partition = 0;
5825 tpnt->nbr_partitions = 0;
5826 tpnt->min_block = 512;
5827 tpnt->max_block = OS_DATA_SIZE;
5828 tpnt->timeout = OSST_TIMEOUT;
5829 tpnt->long_timeout = OSST_LONG_TIMEOUT;
5831 /* Recognize OnStream tapes */
5832 /* We don't need to test for OnStream, as this has been done in detect () */
5833 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5834 tpnt->omit_blklims = 1;
5836 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5837 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5838 tpnt->frame_in_buffer = 0;
5839 tpnt->header_ok = 0;
5840 tpnt->linux_media = 0;
5841 tpnt->header_cache = NULL;
5843 for (i=0; i < ST_NBR_MODES; i++) {
5844 STm = &(tpnt->modes[i]);
5846 STm->sysv = OSST_SYSV;
5847 STm->defaults_for_writes = 0;
5848 STm->do_async_writes = OSST_ASYNC_WRITES;
5849 STm->do_buffer_writes = OSST_BUFFER_WRITES;
5850 STm->do_read_ahead = OSST_READ_AHEAD;
5851 STm->default_compression = ST_DONT_TOUCH;
5852 STm->default_blksize = 512;
5853 STm->default_density = (-1); /* No forced density */
5856 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5857 STps = &(tpnt->ps[i]);
5859 STps->eof = ST_NOEOF;
5861 STps->last_block_valid = 0;
5862 STps->drv_block = (-1);
5863 STps->drv_file = (-1);
5866 tpnt->current_mode = 0;
5867 tpnt->modes[0].defined = 1;
5868 tpnt->modes[2].defined = 1;
5869 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
5871 mutex_init(&tpnt->lock);
5873 write_unlock(&os_scsi_tapes_lock);
5879 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5881 goto out_free_buffer;
5883 /* No-rewind entry */
5884 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5885 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5887 goto out_free_sysfs1;
5890 sdev_printk(KERN_INFO, SDp,
5891 "osst :I: Attached OnStream %.5s tape as %s\n",
5892 SDp->model, tape_name(tpnt));
5897 osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num));
5905 static int osst_remove(struct device *dev)
5907 struct scsi_device * SDp = to_scsi_device(dev);
5908 struct osst_tape * tpnt;
5911 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
5914 write_lock(&os_scsi_tapes_lock);
5915 for(i=0; i < osst_max_dev; i++) {
5916 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
5917 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
5918 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
5919 tpnt->device = NULL;
5920 put_disk(tpnt->drive);
5921 os_scsi_tapes[i] = NULL;
5923 write_unlock(&os_scsi_tapes_lock);
5924 vfree(tpnt->header_cache);
5926 normalize_buffer(tpnt->buffer);
5927 kfree(tpnt->buffer);
5933 write_unlock(&os_scsi_tapes_lock);
5937 static int __init init_osst(void)
5941 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
5945 err = osst_sysfs_init();
5949 err = register_chrdev(OSST_MAJOR, "osst", &osst_fops);
5951 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
5955 err = scsi_register_driver(&osst_template.gendrv);
5957 goto err_out_chrdev;
5959 err = osst_create_sysfs_files(&osst_template.gendrv);
5961 goto err_out_scsidrv;
5966 scsi_unregister_driver(&osst_template.gendrv);
5968 unregister_chrdev(OSST_MAJOR, "osst");
5970 osst_sysfs_cleanup();
5974 static void __exit exit_osst (void)
5977 struct osst_tape * STp;
5979 osst_remove_sysfs_files(&osst_template.gendrv);
5980 scsi_unregister_driver(&osst_template.gendrv);
5981 unregister_chrdev(OSST_MAJOR, "osst");
5982 osst_sysfs_cleanup();
5984 if (os_scsi_tapes) {
5985 for (i=0; i < osst_max_dev; ++i) {
5986 if (!(STp = os_scsi_tapes[i])) continue;
5987 /* This is defensive, supposed to happen during detach */
5988 vfree(STp->header_cache);
5990 normalize_buffer(STp->buffer);
5993 put_disk(STp->drive);
5996 kfree(os_scsi_tapes);
5998 printk(KERN_INFO "osst :I: Unloaded.\n");
6001 module_init(init_osst);
6002 module_exit(exit_osst);