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);
91 module_param(max_dev, int, 0444);
92 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
94 module_param(write_threshold_kbs, int, 0644);
95 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
97 module_param(max_sg_segs, int, 0644);
98 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
100 static struct osst_dev_parm {
103 } parms[] __initdata = {
104 { "max_dev", &max_dev },
105 { "write_threshold_kbs", &write_threshold_kbs },
106 { "max_sg_segs", &max_sg_segs }
110 /* Some default definitions have been moved to osst_options.h */
111 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
112 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
114 /* The buffer size should fit into the 24 bits for length in the
115 6-byte SCSI read and write commands. */
116 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
117 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
121 static int debugging = 1;
122 /* uncomment define below to test error recovery */
123 // #define OSST_INJECT_ERRORS 1
126 /* Do not retry! The drive firmware already retries when appropriate,
127 and when it tries to tell us something, we had better listen... */
128 #define MAX_RETRIES 0
130 #define NO_TAPE NOT_READY
132 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
133 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
134 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
136 #define OSST_TIMEOUT (200 * HZ)
137 #define OSST_LONG_TIMEOUT (1800 * HZ)
139 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
140 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
141 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
142 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
144 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
146 #define SET_DENS_AND_BLK 0x10001
148 static int osst_buffer_size = OSST_BUFFER_SIZE;
149 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
150 static int osst_max_sg_segs = OSST_MAX_SG;
151 static int osst_max_dev = OSST_MAX_TAPES;
152 static int osst_nr_dev;
154 static struct osst_tape **os_scsi_tapes = NULL;
155 static DEFINE_RWLOCK(os_scsi_tapes_lock);
157 static int modes_defined = 0;
159 static struct osst_buffer *new_tape_buffer(int, int, int);
160 static int enlarge_buffer(struct osst_buffer *, int);
161 static void normalize_buffer(struct osst_buffer *);
162 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
163 static int from_buffer(struct osst_buffer *, char __user *, int);
164 static int osst_zero_buffer_tail(struct osst_buffer *);
165 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
166 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
168 static int osst_probe(struct device *);
169 static int osst_remove(struct device *);
171 static struct scsi_driver osst_template = {
172 .owner = THIS_MODULE,
176 .remove = osst_remove,
180 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt,
181 unsigned int cmd_in, unsigned long arg);
183 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip);
185 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt);
187 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt);
189 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending);
191 static inline char *tape_name(struct osst_tape *tape)
193 return tape->drive->disk_name;
196 /* Routines that handle the interaction with mid-layer SCSI routines */
199 /* Normalize Sense */
200 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s)
203 const u8 *sense = SRpnt->sense;
205 s->have_sense = scsi_normalize_sense(SRpnt->sense,
206 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
212 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
213 switch (sense[0] & 0x7f) {
218 s->flags = sense[2] & 0xe0;
224 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
225 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
231 /* Convert the result to success code */
232 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
234 char *name = tape_name(STp);
235 int result = SRpnt->result;
236 u8 * sense = SRpnt->sense, scode;
240 struct st_cmdstatus *cmdstatp;
245 cmdstatp = &STp->buffer->cmdstat;
246 osst_analyze_sense(SRpnt, cmdstatp);
248 if (cmdstatp->have_sense)
249 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
254 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
256 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
257 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
258 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
259 name, scode, sense[12], sense[13]);
260 if (cmdstatp->have_sense)
261 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
265 if (cmdstatp->have_sense && (
267 scode != RECOVERED_ERROR &&
268 /* scode != UNIT_ATTENTION && */
269 scode != BLANK_CHECK &&
270 scode != VOLUME_OVERFLOW &&
271 SRpnt->cmd[0] != MODE_SENSE &&
272 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
273 if (cmdstatp->have_sense) {
274 printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
275 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
278 static int notyetprinted = 1;
281 "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
282 name, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
287 "%s:I: This warning may be caused by your scsi controller,\n", name);
289 "%s:I: it has been reported with some Buslogic cards.\n", name);
293 STp->pos_unknown |= STp->device->was_reset;
295 if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
296 STp->recover_count++;
297 STp->recover_erreg++;
300 if (SRpnt->cmd[0] == READ_6)
302 else if (SRpnt->cmd[0] == WRITE_6)
306 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
310 if ((sense[2] & 0xe0) == 0)
317 /* Wakeup from interrupt */
318 static void osst_sleep_done(void *data, char *sense, int result, int resid)
320 struct osst_request *SRpnt = data;
321 struct osst_tape *STp = SRpnt->stp;
323 memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
324 STp->buffer->cmdstat.midlevel_result = SRpnt->result = result;
326 STp->write_pending = 0;
329 complete(SRpnt->waiting);
332 /* osst_request memory management */
333 static struct osst_request *osst_allocate_request(void)
335 return kzalloc(sizeof(struct osst_request), GFP_KERNEL);
338 static void osst_release_request(struct osst_request *streq)
343 /* Do the scsi command. Waits until command performed if do_wait is true.
344 Otherwise osst_write_behind_check() is used to check that the command
346 static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp,
347 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
350 unsigned short use_sg;
351 #ifdef OSST_INJECT_ERRORS
352 static int inject = 0;
353 static int repeat = 0;
355 struct completion *waiting;
357 /* if async, make sure there's no command outstanding */
358 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
359 printk(KERN_ERR "%s: Async command already active.\n",
361 if (signal_pending(current))
362 (STp->buffer)->syscall_result = (-EINTR);
364 (STp->buffer)->syscall_result = (-EBUSY);
369 SRpnt = osst_allocate_request();
371 printk(KERN_ERR "%s: Can't allocate SCSI request.\n",
373 if (signal_pending(current))
374 (STp->buffer)->syscall_result = (-EINTR);
376 (STp->buffer)->syscall_result = (-EBUSY);
382 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
383 which IO is outstanding. It's nulled out when the IO completes. */
385 (STp->buffer)->last_SRpnt = SRpnt;
387 waiting = &STp->wait;
388 init_completion(waiting);
389 SRpnt->waiting = waiting;
391 use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0;
393 bp = (char *)&(STp->buffer->sg[0]);
394 if (STp->buffer->sg_segs < use_sg)
395 use_sg = STp->buffer->sg_segs;
398 bp = (STp->buffer)->b_data;
400 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
401 STp->buffer->cmdstat.have_sense = 0;
402 STp->buffer->syscall_result = 0;
404 if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
405 use_sg, timeout, retries, SRpnt, osst_sleep_done, GFP_KERNEL))
406 /* could not allocate the buffer or request was too large */
407 (STp->buffer)->syscall_result = (-EBUSY);
409 wait_for_completion(waiting);
410 SRpnt->waiting = NULL;
411 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
412 #ifdef OSST_INJECT_ERRORS
413 if (STp->buffer->syscall_result == 0 &&
416 ( (++ inject % 83) == 29 ||
417 (STp->first_frame_position == 240
418 /* or STp->read_error_frame to fail again on the block calculated above */ &&
420 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
421 STp->buffer->last_result_fatal = 1;
429 /* Handle the write-behind checking (downs the semaphore) */
430 static void osst_write_behind_check(struct osst_tape *STp)
432 struct osst_buffer * STbuffer;
434 STbuffer = STp->buffer;
437 if (STp->write_pending)
442 wait_for_completion(&(STp->wait));
443 STp->buffer->last_SRpnt->waiting = NULL;
445 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
447 if (STp->buffer->syscall_result)
448 STp->buffer->syscall_result =
449 osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1);
451 STp->first_frame_position++;
453 osst_release_request(STp->buffer->last_SRpnt);
455 if (STbuffer->writing < STbuffer->buffer_bytes)
456 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
458 STbuffer->last_SRpnt = NULL;
459 STbuffer->buffer_bytes -= STbuffer->writing;
460 STbuffer->writing = 0;
467 /* Onstream specific Routines */
469 * Initialize the OnStream AUX
471 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
472 int logical_blk_num, int blk_sz, int blk_cnt)
474 os_aux_t *aux = STp->buffer->aux;
475 os_partition_t *par = &aux->partition;
476 os_dat_t *dat = &aux->dat;
478 if (STp->raw) return;
480 memset(aux, 0, sizeof(*aux));
481 aux->format_id = htonl(0);
482 memcpy(aux->application_sig, "LIN4", 4);
483 aux->hdwr = htonl(0);
484 aux->frame_type = frame_type;
486 switch (frame_type) {
487 case OS_FRAME_TYPE_HEADER:
488 aux->update_frame_cntr = htonl(STp->update_frame_cntr);
489 par->partition_num = OS_CONFIG_PARTITION;
490 par->par_desc_ver = OS_PARTITION_VERSION;
491 par->wrt_pass_cntr = htons(0xffff);
492 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
493 par->first_frame_ppos = htonl(0);
494 par->last_frame_ppos = htonl(0xbb7);
495 aux->frame_seq_num = htonl(0);
496 aux->logical_blk_num_high = htonl(0);
497 aux->logical_blk_num = htonl(0);
498 aux->next_mark_ppos = htonl(STp->first_mark_ppos);
500 case OS_FRAME_TYPE_DATA:
501 case OS_FRAME_TYPE_MARKER:
506 dat->dat_list[0].blk_sz = htonl(blk_sz);
507 dat->dat_list[0].blk_cnt = htons(blk_cnt);
508 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
509 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
510 dat->dat_list[0].reserved = 0;
511 case OS_FRAME_TYPE_EOD:
512 aux->update_frame_cntr = htonl(0);
513 par->partition_num = OS_DATA_PARTITION;
514 par->par_desc_ver = OS_PARTITION_VERSION;
515 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
516 par->first_frame_ppos = htonl(STp->first_data_ppos);
517 par->last_frame_ppos = htonl(STp->capacity);
518 aux->frame_seq_num = htonl(frame_seq_number);
519 aux->logical_blk_num_high = htonl(0);
520 aux->logical_blk_num = htonl(logical_blk_num);
522 default: ; /* probably FILL */
524 aux->filemark_cnt = ntohl(STp->filemark_cnt);
525 aux->phys_fm = ntohl(0xffffffff);
526 aux->last_mark_ppos = ntohl(STp->last_mark_ppos);
527 aux->last_mark_lbn = ntohl(STp->last_mark_lbn);
531 * Verify that we have the correct tape frame
533 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
535 char * name = tape_name(STp);
536 os_aux_t * aux = STp->buffer->aux;
537 os_partition_t * par = &(aux->partition);
538 struct st_partstat * STps = &(STp->ps[STp->partition]);
539 int blk_cnt, blk_sz, i;
542 if (STp->buffer->syscall_result) {
543 for (i=0; i < STp->buffer->sg_segs; i++)
544 memset(page_address(STp->buffer->sg[i].page),
545 0, STp->buffer->sg[i].length);
546 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
548 STp->buffer->buffer_bytes = OS_FRAME_SIZE;
551 if (STp->buffer->syscall_result) {
553 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
557 if (ntohl(aux->format_id) != 0) {
559 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
563 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
564 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
566 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
570 if (par->partition_num != OS_DATA_PARTITION) {
571 if (!STp->linux_media || STp->linux_media_version != 2) {
573 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
574 name, par->partition_num);
579 if (par->par_desc_ver != OS_PARTITION_VERSION) {
581 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
585 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
587 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
588 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
592 if (aux->frame_type != OS_FRAME_TYPE_DATA &&
593 aux->frame_type != OS_FRAME_TYPE_EOD &&
594 aux->frame_type != OS_FRAME_TYPE_MARKER) {
597 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
601 if (aux->frame_type == OS_FRAME_TYPE_EOD &&
602 STp->first_frame_position < STp->eod_frame_ppos) {
603 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
604 STp->first_frame_position);
607 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
610 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
611 name, ntohl(aux->frame_seq_num), frame_seq_number);
615 if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
616 STps->eof = ST_FM_HIT;
618 i = ntohl(aux->filemark_cnt);
619 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
620 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
622 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
623 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
624 i, STp->first_frame_position - 1);
626 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
627 if (i >= STp->filemark_cnt)
628 STp->filemark_cnt = i+1;
631 if (aux->frame_type == OS_FRAME_TYPE_EOD) {
632 STps->eof = ST_EOD_1;
633 STp->frame_in_buffer = 1;
635 if (aux->frame_type == OS_FRAME_TYPE_DATA) {
636 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
637 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
638 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
639 STp->buffer->read_pointer = 0;
640 STp->frame_in_buffer = 1;
642 /* See what block size was used to write file */
643 if (STp->block_size != blk_sz && blk_sz > 0) {
645 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
646 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
647 STp->block_size<1024?STp->block_size:STp->block_size/1024,
648 STp->block_size<1024?'b':'k');
649 STp->block_size = blk_sz;
650 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
652 STps->eof = ST_NOEOF;
654 STp->frame_seq_number = ntohl(aux->frame_seq_num);
655 STp->logical_blk_num = ntohl(aux->logical_blk_num);
659 if (STp->read_error_frame == 0)
660 STp->read_error_frame = STp->first_frame_position - 1;
665 * Wait for the unit to become Ready
667 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
668 unsigned timeout, int initial_delay)
670 unsigned char cmd[MAX_COMMAND_SIZE];
671 struct osst_request * SRpnt;
672 unsigned long startwait = jiffies;
675 char * name = tape_name(STp);
677 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
680 if (initial_delay > 0)
681 msleep(jiffies_to_msecs(initial_delay));
683 memset(cmd, 0, MAX_COMMAND_SIZE);
684 cmd[0] = TEST_UNIT_READY;
686 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
688 if (!SRpnt) return (-EBUSY);
690 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
691 (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
692 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) ||
693 ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 &&
694 SRpnt->sense[13] == 0 ) )) {
697 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
698 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
704 memset(cmd, 0, MAX_COMMAND_SIZE);
705 cmd[0] = TEST_UNIT_READY;
707 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
713 if ( STp->buffer->syscall_result &&
714 osst_write_error_recovery(STp, aSRpnt, 0) ) {
716 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
717 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
718 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
719 SRpnt->sense[12], SRpnt->sense[13]);
724 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
730 * Wait for a tape to be inserted in the unit
732 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
734 unsigned char cmd[MAX_COMMAND_SIZE];
735 struct osst_request * SRpnt;
736 unsigned long startwait = jiffies;
739 char * name = tape_name(STp);
741 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
744 memset(cmd, 0, MAX_COMMAND_SIZE);
745 cmd[0] = TEST_UNIT_READY;
747 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
749 if (!SRpnt) return (-EBUSY);
751 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
752 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) {
755 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
756 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
762 memset(cmd, 0, MAX_COMMAND_SIZE);
763 cmd[0] = TEST_UNIT_READY;
765 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
771 if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 &&
772 SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) {
774 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
775 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
776 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
777 SRpnt->sense[12], SRpnt->sense[13]);
782 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
787 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame)
791 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
792 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
793 if (retval) return (retval);
794 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
795 return (osst_get_frame_position(STp, aSRpnt));
799 * Wait for write(s) to complete
801 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
803 unsigned char cmd[MAX_COMMAND_SIZE];
804 struct osst_request * SRpnt;
806 int delay = OSST_WAIT_WRITE_COMPLETE;
808 char * name = tape_name(STp);
810 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
813 memset(cmd, 0, MAX_COMMAND_SIZE);
814 cmd[0] = WRITE_FILEMARKS;
817 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
819 if (!SRpnt) return (-EBUSY);
820 if (STp->buffer->syscall_result) {
821 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) {
822 if (SRpnt->sense[13] == 8) {
823 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
826 result = osst_write_error_recovery(STp, aSRpnt, 0);
828 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
829 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
834 #define OSST_POLL_PER_SEC 10
835 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to)
837 unsigned long startwait = jiffies;
838 char * name = tape_name(STp);
840 char notyetprinted = 1;
842 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
843 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
845 while (time_before (jiffies, startwait + to*HZ))
848 result = osst_get_frame_position(STp, aSRpnt);
850 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
851 return 0; /* successful recovery leaves drive ready for frame */
852 if (result < 0) break;
853 if (STp->first_frame_position == curr &&
855 (signed)STp->last_frame_position > (signed)curr + minlast) ||
856 (minlast >= 0 && STp->cur_frames > minlast)
860 if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC))
862 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
863 name, curr, curr+minlast, STp->first_frame_position,
864 STp->last_frame_position, STp->cur_frames,
865 result, (jiffies-startwait)/HZ,
866 (((jiffies-startwait)%HZ)*10)/HZ);
871 if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted)
873 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
874 name, curr, curr+minlast, STp->first_frame_position,
875 STp->last_frame_position, STp->cur_frames, result);
879 msleep(1000 / OSST_POLL_PER_SEC);
882 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
883 name, curr, curr+minlast, STp->first_frame_position,
884 STp->last_frame_position, STp->cur_frames,
885 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
890 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
892 struct osst_request * SRpnt;
893 unsigned char cmd[MAX_COMMAND_SIZE];
894 unsigned long startwait = jiffies;
896 char * name = tape_name(STp);
900 char * olddata = STp->buffer->b_data;
901 int oldsize = STp->buffer->buffer_size;
903 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
905 memset(cmd, 0, MAX_COMMAND_SIZE);
906 cmd[0] = WRITE_FILEMARKS;
908 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
911 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
913 if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) {
915 /* some failure - not just not-ready */
916 retval = osst_write_error_recovery(STp, aSRpnt, 0);
919 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
921 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
922 memset(cmd, 0, MAX_COMMAND_SIZE);
923 cmd[0] = READ_POSITION;
925 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
928 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
929 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
932 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
934 /* TODO - figure out which error conditions can be handled */
935 if (STp->buffer->syscall_result)
937 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
938 (*aSRpnt)->sense[ 2] & 0x0f,
939 (*aSRpnt)->sense[12],
940 (*aSRpnt)->sense[13]);
946 * Read the next OnStream tape frame at the current location
948 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
950 unsigned char cmd[MAX_COMMAND_SIZE];
951 struct osst_request * SRpnt;
954 os_aux_t * aux = STp->buffer->aux;
955 char * name = tape_name(STp);
959 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
960 retval = osst_recover_wait_frame(STp, aSRpnt, 0);
962 memset(cmd, 0, MAX_COMMAND_SIZE);
969 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
971 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
972 STp->timeout, MAX_RETRIES, 1);
977 if ((STp->buffer)->syscall_result) {
979 if (STp->read_error_frame == 0) {
980 STp->read_error_frame = STp->first_frame_position;
982 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
987 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
989 SRpnt->sense[0], SRpnt->sense[1],
990 SRpnt->sense[2], SRpnt->sense[3],
991 SRpnt->sense[4], SRpnt->sense[5],
992 SRpnt->sense[6], SRpnt->sense[7]);
996 STp->first_frame_position++;
1001 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
1004 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
1005 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
1006 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
1007 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
1008 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
1009 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
1010 if (aux->frame_type==2)
1011 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
1012 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
1013 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
1019 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
1021 struct st_partstat * STps = &(STp->ps[STp->partition]);
1022 struct osst_request * SRpnt ;
1023 unsigned char cmd[MAX_COMMAND_SIZE];
1025 char * name = tape_name(STp);
1027 if (STps->rw != ST_READING) { /* Initialize read operation */
1028 if (STps->rw == ST_WRITING || STp->dirty) {
1029 STp->write_type = OS_WRITE_DATA;
1030 osst_flush_write_buffer(STp, aSRpnt);
1031 osst_flush_drive_buffer(STp, aSRpnt);
1033 STps->rw = ST_READING;
1034 STp->frame_in_buffer = 0;
1037 * Issue a read 0 command to get the OnStream drive
1038 * read frames into its buffer.
1040 memset(cmd, 0, MAX_COMMAND_SIZE);
1045 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
1047 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
1049 if ((retval = STp->buffer->syscall_result))
1050 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
1056 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt,
1057 int frame_seq_number, int quiet)
1059 struct st_partstat * STps = &(STp->ps[STp->partition]);
1060 char * name = tape_name(STp);
1068 * If we want just any frame (-1) and there is a frame in the buffer, return it
1070 if (frame_seq_number == -1 && STp->frame_in_buffer) {
1072 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1077 * Search and wait for the next logical tape frame
1081 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1082 name, frame_seq_number);
1083 if (STp->read_error_frame) {
1084 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1086 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1087 name, STp->read_error_frame);
1089 STp->read_error_frame = 0;
1096 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1097 name, frame_seq_number, cnt);
1099 if ( osst_initiate_read(STp, aSRpnt)
1100 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1103 position = osst_get_frame_position(STp, aSRpnt);
1104 if (position >= 0xbae && position < 0xbb8)
1106 else if (position > STp->eod_frame_ppos || ++bad == 10) {
1107 position = STp->read_error_frame - 1;
1115 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1118 osst_set_frame_position(STp, aSRpnt, position, 0);
1121 if (osst_verify_frame(STp, frame_seq_number, quiet))
1123 if (osst_verify_frame(STp, -1, quiet)) {
1124 x = ntohl(STp->buffer->aux->frame_seq_num);
1125 if (STp->fast_open) {
1127 "%s:W: Found logical frame %d instead of %d after fast open\n",
1128 name, x, frame_seq_number);
1130 STp->read_error_frame = 0;
1133 if (x > frame_seq_number) {
1135 /* positioning backwards did not bring us to the desired frame */
1136 position = STp->read_error_frame - 1;
1139 position = osst_get_frame_position(STp, aSRpnt)
1140 + frame_seq_number - x - 1;
1142 if (STp->first_frame_position >= 3000 && position < 3000)
1147 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1148 name, x, frame_seq_number,
1149 STp->first_frame_position - position);
1151 osst_set_frame_position(STp, aSRpnt, position, 0);
1157 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1159 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1161 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1164 STp->frame_in_buffer = 0;
1167 STp->recover_count++;
1168 STp->recover_erreg++;
1169 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1170 name, STp->read_error_frame);
1175 if (debugging || STps->eof)
1177 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1178 name, frame_seq_number, STp->frame_seq_number, STps->eof);
1181 STp->read_error_frame = 0;
1185 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num)
1187 struct st_partstat * STps = &(STp->ps[STp->partition]);
1188 char * name = tape_name(STp);
1190 int frame_seq_estimate, ppos_estimate, move;
1192 if (logical_blk_num < 0) logical_blk_num = 0;
1194 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1195 name, logical_blk_num, STp->logical_blk_num,
1196 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1197 STp->block_size<1024?'b':'k');
1199 /* Do we know where we are? */
1200 if (STps->drv_block >= 0) {
1201 move = logical_blk_num - STp->logical_blk_num;
1202 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1203 move /= (OS_DATA_SIZE / STp->block_size);
1204 frame_seq_estimate = STp->frame_seq_number + move;
1206 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1208 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1209 else ppos_estimate = frame_seq_estimate + 20;
1210 while (++retries < 10) {
1211 if (ppos_estimate > STp->eod_frame_ppos-2) {
1212 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1213 ppos_estimate = STp->eod_frame_ppos - 2;
1215 if (frame_seq_estimate < 0) {
1216 frame_seq_estimate = 0;
1219 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1220 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1221 /* we've located the estimated frame, now does it have our block? */
1222 if (logical_blk_num < STp->logical_blk_num ||
1223 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1224 if (STps->eof == ST_FM_HIT)
1225 move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1227 move = logical_blk_num - STp->logical_blk_num;
1228 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1229 move /= (OS_DATA_SIZE / STp->block_size);
1231 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1234 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1235 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1236 STp->logical_blk_num, logical_blk_num, move);
1238 frame_seq_estimate += move;
1239 ppos_estimate += move;
1242 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1243 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1244 STp->logical_blk_num = logical_blk_num;
1247 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1248 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1249 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1252 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1253 if (STps->eof == ST_FM_HIT) {
1255 STps->drv_block = 0;
1257 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1258 STp->logical_blk_num -
1259 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1262 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1266 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1268 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1270 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1271 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1272 STp->logical_blk_num, logical_blk_num);
1274 if (frame_seq_estimate != STp->frame_seq_number)
1275 ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1280 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1281 name, logical_blk_num, STp->logical_blk_num, retries);
1285 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1286 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1287 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1288 * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1290 #define OSST_FRAME_SHIFT 6
1291 #define OSST_SECTOR_SHIFT 9
1292 #define OSST_SECTOR_MASK 0x03F
1294 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt)
1298 char * name = tape_name(STp);
1301 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1302 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1303 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1304 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1305 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1306 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1308 /* do we know where we are inside a file? */
1309 if (STp->ps[STp->partition].drv_block >= 0) {
1310 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1311 STp->first_frame_position) << OSST_FRAME_SHIFT;
1312 if (STp->ps[STp->partition].rw == ST_WRITING)
1313 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1315 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1317 sector = osst_get_frame_position(STp, aSRpnt);
1319 sector <<= OSST_FRAME_SHIFT;
1324 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector)
1326 struct st_partstat * STps = &(STp->ps[STp->partition]);
1327 int frame = sector >> OSST_FRAME_SHIFT,
1328 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1331 char * name = tape_name(STp);
1333 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1334 name, sector, frame, offset);
1336 if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1338 if (frame <= STp->first_data_ppos) {
1339 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1340 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1342 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1343 if (r < 0) return r;
1345 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1346 if (r < 0) return r;
1348 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1351 STp->logical_blk_num += offset / STp->block_size;
1352 STp->buffer->read_pointer = offset;
1353 STp->buffer->buffer_bytes -= offset;
1355 STp->frame_seq_number++;
1356 STp->frame_in_buffer = 0;
1357 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1358 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1360 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1361 if (STps->eof == ST_FM_HIT) {
1363 STps->drv_block = 0;
1365 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1366 STp->logical_blk_num -
1367 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1370 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1373 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1374 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1375 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1381 * Read back the drive's internal buffer contents, as a part
1382 * of the write error recovery mechanism for old OnStream
1383 * firmware revisions.
1384 * Precondition for this function to work: all frames in the
1385 * drive's buffer must be of one type (DATA, MARK or EOD)!
1387 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
1388 unsigned int frame, unsigned int skip, int pending)
1390 struct osst_request * SRpnt = * aSRpnt;
1391 unsigned char * buffer, * p;
1392 unsigned char cmd[MAX_COMMAND_SIZE];
1393 int flag, new_frame, i;
1394 int nframes = STp->cur_frames;
1395 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1396 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1397 - (nframes + pending - 1);
1398 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1399 - (nframes + pending - 1) * blks_per_frame;
1400 char * name = tape_name(STp);
1401 unsigned long startwait = jiffies;
1403 int dbg = debugging;
1406 if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
1409 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1410 name, nframes, pending?" and one that was pending":"");
1412 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1414 if (pending && debugging)
1415 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1416 name, frame_seq_number + nframes,
1417 logical_blk_num + nframes * blks_per_frame,
1418 p[0], p[1], p[2], p[3]);
1420 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1422 memset(cmd, 0, MAX_COMMAND_SIZE);
1423 cmd[0] = 0x3C; /* Buffer Read */
1424 cmd[1] = 6; /* Retrieve Faulty Block */
1425 cmd[7] = 32768 >> 8;
1426 cmd[8] = 32768 & 0xff;
1428 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1429 STp->timeout, MAX_RETRIES, 1);
1431 if ((STp->buffer)->syscall_result || !SRpnt) {
1432 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1437 osst_copy_from_buffer(STp->buffer, p);
1440 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1441 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1445 osst_get_frame_position(STp, aSRpnt);
1448 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1450 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1451 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1453 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1456 if (STp->write_type == OS_WRITE_HEADER) {
1458 p += skip * OS_DATA_SIZE;
1460 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1465 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1466 name, new_frame+i, frame_seq_number+i);
1468 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1469 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1470 osst_get_frame_position(STp, aSRpnt);
1473 if (new_frame > frame + 1000) {
1474 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1478 if ( i >= nframes + pending ) break;
1481 osst_copy_to_buffer(STp->buffer, p);
1483 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1485 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1486 logical_blk_num + i*blks_per_frame,
1487 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1488 memset(cmd, 0, MAX_COMMAND_SIZE);
1496 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1497 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1498 p[0], p[1], p[2], p[3]);
1500 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1501 STp->timeout, MAX_RETRIES, 1);
1503 if (STp->buffer->syscall_result)
1506 p += OS_DATA_SIZE; i++;
1508 /* if we just sent the last frame, wait till all successfully written */
1509 if ( i == nframes + pending ) {
1511 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1513 memset(cmd, 0, MAX_COMMAND_SIZE);
1514 cmd[0] = WRITE_FILEMARKS;
1516 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1517 STp->timeout, MAX_RETRIES, 1);
1520 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1521 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1525 flag = STp->buffer->syscall_result;
1526 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1528 memset(cmd, 0, MAX_COMMAND_SIZE);
1529 cmd[0] = TEST_UNIT_READY;
1531 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1534 if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
1535 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
1536 /* in the process of becoming ready */
1540 if (STp->buffer->syscall_result)
1546 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1552 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1553 SRpnt->sense[12] == 0 &&
1554 SRpnt->sense[13] == 2) {
1555 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1557 return (-EIO); /* hit end of tape = fail */
1559 i = ((SRpnt->sense[3] << 24) |
1560 (SRpnt->sense[4] << 16) |
1561 (SRpnt->sense[5] << 8) |
1562 SRpnt->sense[6] ) - new_frame;
1563 p = &buffer[i * OS_DATA_SIZE];
1565 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1567 osst_get_frame_position(STp, aSRpnt);
1569 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1570 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1575 /* error recovery did not successfully complete */
1576 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1577 STp->write_type == OS_WRITE_HEADER?"header":"body");
1580 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1585 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
1586 unsigned int frame, unsigned int skip, int pending)
1588 unsigned char cmd[MAX_COMMAND_SIZE];
1589 struct osst_request * SRpnt;
1590 char * name = tape_name(STp);
1592 int attempts = 1000 / skip;
1594 unsigned long startwait = jiffies;
1596 int dbg = debugging;
1599 while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1604 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1606 expected = frame+skip+STp->cur_frames+pending;
1608 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1609 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1611 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1614 schedule_timeout_interruptible(msecs_to_jiffies(100));
1616 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1618 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1619 name, STp->first_frame_position,
1620 STp->last_frame_position, STp->cur_frames);
1622 frame = STp->last_frame_position;
1626 if (pending && STp->cur_frames < 50) {
1628 memset(cmd, 0, MAX_COMMAND_SIZE);
1633 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1634 name, STp->frame_seq_number-1, STp->first_frame_position);
1636 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1637 STp->timeout, MAX_RETRIES, 1);
1640 if (STp->buffer->syscall_result) { /* additional write error */
1641 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1642 SRpnt->sense[12] == 0 &&
1643 SRpnt->sense[13] == 2) {
1645 "%s:E: Volume overflow in write error recovery\n",
1647 break; /* hit end of tape = fail */
1656 if (STp->cur_frames == 0) {
1659 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1661 if (STp->first_frame_position != expected) {
1662 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1663 name, STp->first_frame_position, expected);
1670 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1671 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1675 schedule_timeout_interruptible(msecs_to_jiffies(100));
1677 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1685 * Error recovery algorithm for the OnStream tape.
1688 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending)
1690 struct osst_request * SRpnt = * aSRpnt;
1691 struct st_partstat * STps = & STp->ps[STp->partition];
1692 char * name = tape_name(STp);
1695 unsigned int frame, skip;
1697 rw_state = STps->rw;
1699 if ((SRpnt->sense[ 2] & 0x0f) != 3
1700 || SRpnt->sense[12] != 12
1701 || SRpnt->sense[13] != 0) {
1703 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1704 SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]);
1708 frame = (SRpnt->sense[3] << 24) |
1709 (SRpnt->sense[4] << 16) |
1710 (SRpnt->sense[5] << 8) |
1712 skip = SRpnt->sense[9];
1715 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1717 osst_get_frame_position(STp, aSRpnt);
1719 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1720 name, STp->first_frame_position, STp->last_frame_position);
1722 switch (STp->write_type) {
1725 case OS_WRITE_NEW_MARK:
1727 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1728 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1729 if (STp->os_fw_rev >= 10600)
1730 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1732 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1733 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1735 retval?"" :"Don't worry, ",
1736 retval?" not ":" ");
1738 case OS_WRITE_LAST_MARK:
1739 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1740 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1743 case OS_WRITE_HEADER:
1744 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1745 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1748 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1749 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1751 osst_get_frame_position(STp, aSRpnt);
1753 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1754 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1755 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1758 STp->recover_count++;
1759 STp->recover_erreg++;
1763 STps->rw = rw_state;
1767 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt,
1768 int mt_op, int mt_count)
1770 char * name = tape_name(STp);
1772 int last_mark_ppos = -1;
1775 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1777 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1779 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1783 if (STp->linux_media_version >= 4) {
1785 * direct lookup in header filemark list
1787 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1788 if (STp->header_ok &&
1789 STp->header_cache != NULL &&
1790 (cnt - mt_count) >= 0 &&
1791 (cnt - mt_count) < OS_FM_TAB_MAX &&
1792 (cnt - mt_count) < STp->filemark_cnt &&
1793 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1795 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1797 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1798 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1799 STp->header_cache == NULL?"lack of header cache":"count out of range");
1801 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1803 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1804 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1805 STp->buffer->aux->last_mark_ppos))?"match":"error",
1806 mt_count, last_mark_ppos);
1808 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1809 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1810 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1813 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1817 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1818 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1819 name, last_mark_ppos);
1825 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1829 while (cnt != mt_count) {
1830 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1831 if (last_mark_ppos == -1)
1834 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1836 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1838 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1840 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1844 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1845 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1846 name, last_mark_ppos);
1851 if (mt_op == MTBSFM) {
1852 STp->frame_seq_number++;
1853 STp->frame_in_buffer = 0;
1854 STp->buffer->buffer_bytes = 0;
1855 STp->buffer->read_pointer = 0;
1856 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1862 * ADRL 1.1 compatible "slow" space filemarks fwd version
1864 * Just scans for the filemark sequentially.
1866 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt,
1867 int mt_op, int mt_count)
1871 char * name = tape_name(STp);
1873 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1875 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1877 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1882 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1884 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1888 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1890 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1892 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1894 if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1896 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1897 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1899 STp->eod_frame_ppos = STp->first_frame_position-1;
1903 if (cnt == mt_count)
1905 STp->frame_in_buffer = 0;
1907 if (mt_op == MTFSF) {
1908 STp->frame_seq_number++;
1909 STp->frame_in_buffer = 0;
1910 STp->buffer->buffer_bytes = 0;
1911 STp->buffer->read_pointer = 0;
1912 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1918 * Fast linux specific version of OnStream FSF
1920 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt,
1921 int mt_op, int mt_count)
1923 char * name = tape_name(STp);
1925 next_mark_ppos = -1;
1928 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
1930 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1932 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1937 if (STp->linux_media_version >= 4) {
1939 * direct lookup in header filemark list
1941 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
1942 if (STp->header_ok &&
1943 STp->header_cache != NULL &&
1944 (cnt + mt_count) < OS_FM_TAB_MAX &&
1945 (cnt + mt_count) < STp->filemark_cnt &&
1946 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1947 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
1949 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
1951 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
1952 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1953 STp->header_cache == NULL?"lack of header cache":"count out of range");
1955 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1957 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1958 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
1959 STp->buffer->aux->last_mark_ppos))?"match":"error",
1960 mt_count, next_mark_ppos);
1962 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
1964 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1966 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1968 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
1969 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1971 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
1976 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1977 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1978 name, next_mark_ppos);
1981 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
1982 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
1983 name, cnt+mt_count, next_mark_ppos,
1984 ntohl(STp->buffer->aux->filemark_cnt));
1990 * Find nearest (usually previous) marker, then jump from marker to marker
1993 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1995 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1997 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
2001 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
2002 if (STp->first_mark_ppos == -1) {
2004 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2006 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2008 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
2009 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2012 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2017 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2018 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
2019 name, STp->first_mark_ppos);
2023 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
2029 while (cnt != mt_count) {
2030 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
2031 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
2033 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2035 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
2038 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
2040 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2042 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2044 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2049 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2050 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2051 name, next_mark_ppos);
2056 if (mt_op == MTFSF) {
2057 STp->frame_seq_number++;
2058 STp->frame_in_buffer = 0;
2059 STp->buffer->buffer_bytes = 0;
2060 STp->buffer->read_pointer = 0;
2061 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2067 * In debug mode, we want to see as many errors as possible
2068 * to test the error recovery mechanism.
2071 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries)
2073 unsigned char cmd[MAX_COMMAND_SIZE];
2074 struct osst_request * SRpnt = * aSRpnt;
2075 char * name = tape_name(STp);
2077 memset(cmd, 0, MAX_COMMAND_SIZE);
2078 cmd[0] = MODE_SELECT;
2080 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2082 (STp->buffer)->b_data[0] = cmd[4] - 1;
2083 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
2084 (STp->buffer)->b_data[2] = 0; /* Reserved */
2085 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
2086 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2087 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2088 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2089 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2092 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2094 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2097 if ((STp->buffer)->syscall_result)
2098 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2103 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt)
2106 int this_mark_ppos = STp->first_frame_position;
2107 int this_mark_lbn = STp->logical_blk_num;
2109 char * name = tape_name(STp);
2112 if (STp->raw) return 0;
2114 STp->write_type = OS_WRITE_NEW_MARK;
2116 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2117 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2120 result = osst_flush_write_buffer(STp, aSRpnt);
2121 result |= osst_flush_drive_buffer(STp, aSRpnt);
2122 STp->last_mark_ppos = this_mark_ppos;
2123 STp->last_mark_lbn = this_mark_lbn;
2124 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2125 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2126 if (STp->filemark_cnt++ == 0)
2127 STp->first_mark_ppos = this_mark_ppos;
2131 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt)
2135 char * name = tape_name(STp);
2138 if (STp->raw) return 0;
2140 STp->write_type = OS_WRITE_EOD;
2141 STp->eod_frame_ppos = STp->first_frame_position;
2143 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2144 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2148 result = osst_flush_write_buffer(STp, aSRpnt);
2149 result |= osst_flush_drive_buffer(STp, aSRpnt);
2150 STp->eod_frame_lfa = --(STp->frame_seq_number);
2154 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2156 char * name = tape_name(STp);
2159 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2161 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2162 osst_set_frame_position(STp, aSRpnt, where, 0);
2163 STp->write_type = OS_WRITE_FILLER;
2165 memcpy(STp->buffer->b_data, "Filler", 6);
2166 STp->buffer->buffer_bytes = 6;
2168 if (osst_flush_write_buffer(STp, aSRpnt)) {
2169 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2174 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2176 return osst_flush_drive_buffer(STp, aSRpnt);
2179 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2181 char * name = tape_name(STp);
2185 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2187 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2188 osst_set_frame_position(STp, aSRpnt, where, 0);
2189 STp->write_type = OS_WRITE_HEADER;
2191 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2192 STp->buffer->buffer_bytes = sizeof(os_header_t);
2194 if (osst_flush_write_buffer(STp, aSRpnt)) {
2195 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2199 result = osst_flush_drive_buffer(STp, aSRpnt);
2201 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2206 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod)
2208 os_header_t * header;
2210 char * name = tape_name(STp);
2213 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2215 if (STp->raw) return 0;
2217 if (STp->header_cache == NULL) {
2218 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2219 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2222 memset(STp->header_cache, 0, sizeof(os_header_t));
2224 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2227 if (STp->header_ok) STp->update_frame_cntr++;
2228 else STp->update_frame_cntr = 0;
2230 header = STp->header_cache;
2231 strcpy(header->ident_str, "ADR_SEQ");
2232 header->major_rev = 1;
2233 header->minor_rev = 4;
2234 header->ext_trk_tb_off = htons(17192);
2235 header->pt_par_num = 1;
2236 header->partition[0].partition_num = OS_DATA_PARTITION;
2237 header->partition[0].par_desc_ver = OS_PARTITION_VERSION;
2238 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2239 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2240 header->partition[0].last_frame_ppos = htonl(STp->capacity);
2241 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2242 header->cfg_col_width = htonl(20);
2243 header->dat_col_width = htonl(1500);
2244 header->qfa_col_width = htonl(0);
2245 header->ext_track_tb.nr_stream_part = 1;
2246 header->ext_track_tb.et_ent_sz = 32;
2247 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2248 header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2249 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2250 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2251 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa);
2252 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
2253 header->dat_fm_tab.fm_part_num = 0;
2254 header->dat_fm_tab.fm_tab_ent_sz = 4;
2255 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2256 STp->filemark_cnt:OS_FM_TAB_MAX);
2258 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2259 if (STp->update_frame_cntr == 0)
2260 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2261 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2265 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2267 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2270 printk(KERN_ERR "%s:E: Write header failed\n", name);
2272 memcpy(STp->application_sig, "LIN4", 4);
2273 STp->linux_media = 1;
2274 STp->linux_media_version = 4;
2280 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt)
2282 if (STp->header_cache != NULL)
2283 memset(STp->header_cache, 0, sizeof(os_header_t));
2285 STp->logical_blk_num = STp->frame_seq_number = 0;
2286 STp->frame_in_buffer = 0;
2287 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2288 STp->filemark_cnt = 0;
2289 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2290 return osst_write_header(STp, aSRpnt, 1);
2293 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos)
2295 char * name = tape_name(STp);
2296 os_header_t * header;
2299 int linux_media_version,
2305 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2306 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2307 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2308 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2309 if (osst_initiate_read (STp, aSRpnt)) {
2310 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2314 if (osst_read_frame(STp, aSRpnt, 180)) {
2316 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2320 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2321 aux = STp->buffer->aux;
2322 if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2324 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2328 if (ntohl(aux->frame_seq_num) != 0 ||
2329 ntohl(aux->logical_blk_num) != 0 ||
2330 aux->partition.partition_num != OS_CONFIG_PARTITION ||
2331 ntohl(aux->partition.first_frame_ppos) != 0 ||
2332 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2334 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2335 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2336 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2337 ntohl(aux->partition.last_frame_ppos));
2341 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2342 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2343 strlcpy(id_string, header->ident_str, 8);
2345 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2349 update_frame_cntr = ntohl(aux->update_frame_cntr);
2350 if (update_frame_cntr < STp->update_frame_cntr) {
2352 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2353 name, ppos, update_frame_cntr, STp->update_frame_cntr);
2357 if (header->major_rev != 1 || header->minor_rev != 4 ) {
2359 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2360 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2361 header->minor_rev > 4 )? "Invalid" : "Warning:",
2362 header->major_rev, header->minor_rev);
2364 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2368 if (header->pt_par_num != 1)
2369 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2370 name, header->pt_par_num);
2372 memcpy(id_string, aux->application_sig, 4);
2374 if (memcmp(id_string, "LIN", 3) == 0) {
2375 STp->linux_media = 1;
2376 linux_media_version = id_string[3] - '0';
2377 if (linux_media_version != 4)
2378 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2379 name, linux_media_version);
2381 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2384 if (linux_media_version < STp->linux_media_version) {
2386 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2387 name, ppos, linux_media_version);
2391 if (linux_media_version > STp->linux_media_version) {
2393 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2394 name, ppos, linux_media_version);
2396 memcpy(STp->application_sig, id_string, 5);
2397 STp->linux_media_version = linux_media_version;
2398 STp->update_frame_cntr = -1;
2400 if (update_frame_cntr > STp->update_frame_cntr) {
2402 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2403 name, ppos, update_frame_cntr);
2405 if (STp->header_cache == NULL) {
2406 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2407 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2411 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2414 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2415 header = STp->header_cache; /* further accesses from cached (full) copy */
2417 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2418 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2419 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2420 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2421 STp->filemark_cnt = ntohl(aux->filemark_cnt);
2422 STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2423 STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2424 STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2425 STp->update_frame_cntr = update_frame_cntr;
2427 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2428 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2429 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2430 STp->first_data_ppos,
2431 ntohl(header->partition[0].last_frame_ppos),
2432 ntohl(header->partition[0].eod_frame_ppos));
2433 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2434 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2436 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2438 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2440 memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2441 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2442 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2444 if (header->minor_rev == 4 &&
2445 (header->ext_trk_tb_off != htons(17192) ||
2446 header->partition[0].partition_num != OS_DATA_PARTITION ||
2447 header->partition[0].par_desc_ver != OS_PARTITION_VERSION ||
2448 header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2449 header->cfg_col_width != htonl(20) ||
2450 header->dat_col_width != htonl(1500) ||
2451 header->qfa_col_width != htonl(0) ||
2452 header->ext_track_tb.nr_stream_part != 1 ||
2453 header->ext_track_tb.et_ent_sz != 32 ||
2454 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION ||
2455 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2456 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2457 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2458 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) ||
2459 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION ||
2460 header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2461 header->dat_fm_tab.fm_tab_ent_cnt !=
2462 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2463 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2470 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt)
2475 char * name = tape_name(STp);
2477 position = osst_get_frame_position(STp, aSRpnt);
2480 STp->header_ok = STp->linux_media = 1;
2481 STp->linux_media_version = 0;
2484 STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2485 STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2486 STp->eod_frame_ppos = STp->first_data_ppos = -1;
2487 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2489 printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2492 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2493 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2495 first = position==10?0xbae: 5;
2496 last = position==10?0xbb3:10;
2498 for (ppos = first; ppos < last; ppos++)
2499 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2502 first = position==10? 5:0xbae;
2503 last = position==10?10:0xbb3;
2505 for (ppos = first; ppos < last; ppos++)
2506 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2510 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2511 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2512 osst_set_frame_position(STp, aSRpnt, 10, 0);
2515 if (position <= STp->first_data_ppos) {
2516 position = STp->first_data_ppos;
2517 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2519 osst_set_frame_position(STp, aSRpnt, position, 0);
2525 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt)
2527 int frame_position = STp->first_frame_position;
2528 int frame_seq_numbr = STp->frame_seq_number;
2529 int logical_blk_num = STp->logical_blk_num;
2530 int halfway_frame = STp->frame_in_buffer;
2531 int read_pointer = STp->buffer->read_pointer;
2532 int prev_mark_ppos = -1;
2533 int actual_mark_ppos, i, n;
2535 char * name = tape_name(STp);
2537 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2539 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2540 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2542 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2546 if (STp->linux_media_version >= 4) {
2547 for (i=0; i<STp->filemark_cnt; i++)
2548 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2551 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2552 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2553 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2554 if (frame_position != STp->first_frame_position ||
2555 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2556 prev_mark_ppos != actual_mark_ppos ) {
2558 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2559 STp->first_frame_position, frame_position,
2560 STp->frame_seq_number + (halfway_frame?0:1),
2561 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2565 if (halfway_frame) {
2566 /* prepare buffer for append and rewrite on top of original */
2567 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2568 STp->buffer->buffer_bytes = read_pointer;
2569 STp->ps[STp->partition].rw = ST_WRITING;
2572 STp->frame_in_buffer = halfway_frame;
2573 STp->frame_seq_number = frame_seq_numbr;
2574 STp->logical_blk_num = logical_blk_num;
2578 /* Acc. to OnStream, the vers. numbering is the following:
2579 * X.XX for released versions (X=digit),
2580 * XXXY for unreleased versions (Y=letter)
2581 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2582 * This fn makes monoton numbers out of this scheme ...
2584 static unsigned int osst_parse_firmware_rev (const char * str)
2586 if (str[1] == '.') {
2587 return (str[0]-'0')*10000
2591 return (str[0]-'0')*10000
2593 +(str[2]-'0')*100 - 100
2599 * Configure the OnStream SCII tape drive for default operation
2601 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
2603 unsigned char cmd[MAX_COMMAND_SIZE];
2604 char * name = tape_name(STp);
2605 struct osst_request * SRpnt = * aSRpnt;
2606 osst_mode_parameter_header_t * header;
2607 osst_block_size_page_t * bs;
2608 osst_capabilities_page_t * cp;
2609 osst_tape_paramtr_page_t * prm;
2610 int drive_buffer_size;
2612 if (STp->ready != ST_READY) {
2614 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2619 if (STp->os_fw_rev < 10600) {
2620 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2621 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2625 * Configure 32.5KB (data+aux) frame size.
2626 * Get the current frame size from the block size mode page
2628 memset(cmd, 0, MAX_COMMAND_SIZE);
2629 cmd[0] = MODE_SENSE;
2631 cmd[2] = BLOCK_SIZE_PAGE;
2632 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2634 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2635 if (SRpnt == NULL) {
2637 printk(OSST_DEB_MSG "osst :D: Busy\n");
2642 if ((STp->buffer)->syscall_result != 0) {
2643 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2647 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2648 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2651 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2652 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No");
2653 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2654 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2658 * Configure default auto columns mode, 32.5KB transfer mode
2666 memset(cmd, 0, MAX_COMMAND_SIZE);
2667 cmd[0] = MODE_SELECT;
2669 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2671 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2673 if ((STp->buffer)->syscall_result != 0) {
2674 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2679 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2681 * In debug mode, we want to see as many errors as possible
2682 * to test the error recovery mechanism.
2684 osst_set_retries(STp, aSRpnt, 0);
2689 * Set vendor name to 'LIN4' for "Linux support version 4".
2692 memset(cmd, 0, MAX_COMMAND_SIZE);
2693 cmd[0] = MODE_SELECT;
2695 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2697 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2698 header->medium_type = 0; /* Medium Type - ignoring */
2699 header->dsp = 0; /* Reserved */
2700 header->bdl = 0; /* Block Descriptor Length */
2702 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2703 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2704 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2705 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2706 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2707 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2708 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2709 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2711 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2714 if ((STp->buffer)->syscall_result != 0) {
2715 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2716 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2720 memset(cmd, 0, MAX_COMMAND_SIZE);
2721 cmd[0] = MODE_SENSE;
2723 cmd[2] = CAPABILITIES_PAGE;
2724 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2726 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2729 if ((STp->buffer)->syscall_result != 0) {
2730 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2734 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2735 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2736 sizeof(osst_mode_parameter_header_t) + header->bdl);
2738 drive_buffer_size = ntohs(cp->buffer_size) / 2;
2740 memset(cmd, 0, MAX_COMMAND_SIZE);
2741 cmd[0] = MODE_SENSE;
2743 cmd[2] = TAPE_PARAMTR_PAGE;
2744 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2746 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2749 if ((STp->buffer)->syscall_result != 0) {
2750 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2754 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2755 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2756 sizeof(osst_mode_parameter_header_t) + header->bdl);
2758 STp->density = prm->density;
2759 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2761 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2762 name, STp->density, STp->capacity / 32, drive_buffer_size);
2770 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2771 it messes up the block number). */
2772 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward)
2775 char * name = tape_name(STp);
2779 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2780 name, forward ? "forward" : "backward");
2784 /* assumes that the filemark is already read by the drive, so this is low cost */
2785 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2788 /* assumes this is only called if we just read the filemark! */
2789 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2792 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2793 name, forward ? "forward" : "backward");
2799 /* Get the tape position. */
2801 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
2803 unsigned char scmd[MAX_COMMAND_SIZE];
2804 struct osst_request * SRpnt;
2806 char * name = tape_name(STp);
2808 /* KG: We want to be able to use it for checking Write Buffer availability
2809 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2811 char * olddata = STp->buffer->b_data;
2812 int oldsize = STp->buffer->buffer_size;
2814 if (STp->ready != ST_READY) return (-EIO);
2816 memset (scmd, 0, MAX_COMMAND_SIZE);
2817 scmd[0] = READ_POSITION;
2819 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2820 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2821 STp->timeout, MAX_RETRIES, 1);
2823 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2828 if (STp->buffer->syscall_result)
2829 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */
2831 if (result == -EINVAL)
2832 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2834 if (result == -EIO) { /* re-read position - this needs to preserve media errors */
2835 unsigned char mysense[16];
2836 memcpy (mysense, SRpnt->sense, 16);
2837 memset (scmd, 0, MAX_COMMAND_SIZE);
2838 scmd[0] = READ_POSITION;
2839 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2840 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2841 STp->timeout, MAX_RETRIES, 1);
2843 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2844 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2845 SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]);
2847 if (!STp->buffer->syscall_result)
2848 memcpy (SRpnt->sense, mysense, 16);
2850 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2852 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2853 + ((STp->buffer)->b_data[5] << 16)
2854 + ((STp->buffer)->b_data[6] << 8)
2855 + (STp->buffer)->b_data[7];
2856 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2857 + ((STp->buffer)->b_data[ 9] << 16)
2858 + ((STp->buffer)->b_data[10] << 8)
2859 + (STp->buffer)->b_data[11];
2860 STp->cur_frames = (STp->buffer)->b_data[15];
2863 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2864 STp->first_frame_position, STp->last_frame_position,
2865 ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2866 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2870 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2872 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2873 STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2875 STp->first_frame_position = STp->last_frame_position;
2878 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2880 return (result == 0 ? STp->first_frame_position : result);
2884 /* Set the tape block */
2885 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip)
2887 unsigned char scmd[MAX_COMMAND_SIZE];
2888 struct osst_request * SRpnt;
2889 struct st_partstat * STps;
2891 int pp = (ppos == 3000 && !skip)? 0 : ppos;
2892 char * name = tape_name(STp);
2894 if (STp->ready != ST_READY) return (-EIO);
2896 STps = &(STp->ps[STp->partition]);
2898 if (ppos < 0 || ppos > STp->capacity) {
2899 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2900 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2907 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2909 memset (scmd, 0, MAX_COMMAND_SIZE);
2912 scmd[3] = (pp >> 24);
2913 scmd[4] = (pp >> 16);
2914 scmd[5] = (pp >> 8);
2919 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
2925 if ((STp->buffer)->syscall_result != 0) {
2927 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
2928 name, STp->first_frame_position, pp);
2933 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
2934 } while ((pp != ppos) && (pp = ppos));
2935 STp->first_frame_position = STp->last_frame_position = ppos;
2936 STps->eof = ST_NOEOF;
2939 STp->frame_in_buffer = 0;
2943 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT)
2945 struct st_partstat * STps = &(STp->ps[STp->partition]);
2948 if (STp->write_type != OS_WRITE_NEW_MARK) {
2949 /* true unless the user wrote the filemark for us */
2950 result = osst_flush_drive_buffer(STp, aSRpnt);
2951 if (result < 0) goto out;
2952 result = osst_write_filemark(STp, aSRpnt);
2953 if (result < 0) goto out;
2955 if (STps->drv_file >= 0)
2957 STps->drv_block = 0;
2959 result = osst_write_eod(STp, aSRpnt);
2960 osst_write_header(STp, aSRpnt, leave_at_EOT);
2967 /* osst versions of st functions - augmented and stripped to suit OnStream only */
2969 /* Flush the write buffer (never need to write if variable blocksize). */
2970 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt)
2972 int offset, transfer, blks = 0;
2974 unsigned char cmd[MAX_COMMAND_SIZE];
2975 struct osst_request * SRpnt = *aSRpnt;
2976 struct st_partstat * STps;
2977 char * name = tape_name(STp);
2979 if ((STp->buffer)->writing) {
2980 if (SRpnt == (STp->buffer)->last_SRpnt)
2982 { printk(OSST_DEB_MSG
2983 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name);
2985 *aSRpnt = SRpnt = NULL;
2989 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name);
2991 osst_write_behind_check(STp);
2992 if ((STp->buffer)->syscall_result) {
2995 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
2996 name, (STp->buffer)->midlevel_result);
2998 if ((STp->buffer)->midlevel_result == INT_MAX)
3005 if (STp->dirty == 1) {
3008 STps = &(STp->ps[STp->partition]);
3009 STps->rw = ST_WRITING;
3010 offset = STp->buffer->buffer_bytes;
3011 blks = (offset + STp->block_size - 1) / STp->block_size;
3012 transfer = OS_FRAME_SIZE;
3014 if (offset < OS_DATA_SIZE)
3015 osst_zero_buffer_tail(STp->buffer);
3018 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
3019 result = osst_recover_wait_frame(STp, aSRpnt, 1);
3021 memset(cmd, 0, MAX_COMMAND_SIZE);
3026 switch (STp->write_type) {
3030 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
3031 name, blks, STp->frame_seq_number,
3032 STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3034 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3035 STp->logical_blk_num - blks, STp->block_size, blks);
3038 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
3039 STp->logical_blk_num, 0, 0);
3041 case OS_WRITE_NEW_MARK:
3042 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
3043 STp->logical_blk_num++, 0, blks=1);
3045 case OS_WRITE_HEADER:
3046 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
3048 default: /* probably FILLER */
3049 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
3053 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
3054 name, offset, transfer, blks);
3057 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3058 STp->timeout, MAX_RETRIES, 1);
3063 if ((STp->buffer)->syscall_result != 0) {
3066 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3067 name, SRpnt->sense[0], SRpnt->sense[2],
3068 SRpnt->sense[12], SRpnt->sense[13]);
3070 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3071 (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3072 (SRpnt->sense[2] & 0x0f) == NO_SENSE) {
3074 (STp->buffer)->buffer_bytes = 0;
3078 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3079 printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3083 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
3086 STp->first_frame_position++;
3088 (STp->buffer)->buffer_bytes = 0;
3092 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3098 /* Flush the tape buffer. The tape will be positioned correctly unless
3099 seek_next is true. */
3100 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next)
3102 struct st_partstat * STps;
3103 int backspace = 0, result = 0;
3105 char * name = tape_name(STp);
3109 * If there was a bus reset, block further access
3112 if( STp->pos_unknown)
3115 if (STp->ready != ST_READY)
3118 STps = &(STp->ps[STp->partition]);
3119 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
3120 STp->write_type = OS_WRITE_DATA;
3121 return osst_flush_write_buffer(STp, aSRpnt);
3123 if (STp->block_size == 0)
3127 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3130 if (!STp->can_bsr) {
3131 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3132 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3133 (STp->buffer)->buffer_bytes = 0;
3134 (STp->buffer)->read_pointer = 0;
3135 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3139 if (STps->eof == ST_FM_HIT) {
3140 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3142 STps->eof = ST_NOEOF;
3144 if (STps->drv_file >= 0)
3146 STps->drv_block = 0;
3149 if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3150 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3152 else if (STps->eof == ST_FM_HIT) {
3153 if (STps->drv_file >= 0)
3155 STps->drv_block = 0;
3156 STps->eof = ST_NOEOF;
3162 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous)
3164 unsigned char cmd[MAX_COMMAND_SIZE];
3165 struct osst_request * SRpnt;
3168 char * name = tape_name(STp);
3171 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3173 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3175 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3178 /* error recovery may have bumped us past the header partition */
3179 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3181 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3183 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3188 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3189 if (osst_recover_wait_frame(STp, aSRpnt, 1))
3192 // osst_build_stats(STp, &SRpnt);
3194 STp->ps[STp->partition].rw = ST_WRITING;
3195 STp->write_type = OS_WRITE_DATA;
3197 memset(cmd, 0, MAX_COMMAND_SIZE);
3200 cmd[4] = 1; /* one frame at a time... */
3201 blks = STp->buffer->buffer_bytes / STp->block_size;
3204 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3205 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3207 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3208 STp->logical_blk_num - blks, STp->block_size, blks);
3212 STp->write_pending = 1;
3214 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3215 MAX_RETRIES, synchronous);
3221 if (STp->buffer->syscall_result != 0) {
3224 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3226 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3227 (SRpnt->sense[2] & 0x40)) {
3228 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW)
3232 if (osst_write_error_recovery(STp, aSRpnt, 1))
3237 STp->first_frame_position++;
3245 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */
3246 static int do_door_lock(struct osst_tape * STp, int do_lock)
3250 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
3252 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3254 retval = scsi_ioctl(STp->device, cmd, NULL);
3256 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3259 STp->door_locked = ST_LOCK_FAILS;
3264 /* Set the internal state after reset */
3265 static void reset_state(struct osst_tape *STp)
3268 struct st_partstat *STps;
3270 STp->pos_unknown = 0;
3271 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3272 STps = &(STp->ps[i]);
3274 STps->eof = ST_NOEOF;
3276 STps->last_block_valid = 0;
3277 STps->drv_block = -1;
3278 STps->drv_file = -1;
3283 /* Entry points to osst */
3286 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3288 ssize_t total, retval = 0;
3289 ssize_t i, do_count, blks, transfer;
3290 int write_threshold;
3291 int doing_write = 0;
3292 const char __user * b_point;
3293 struct osst_request * SRpnt = NULL;
3294 struct st_modedef * STm;
3295 struct st_partstat * STps;
3296 struct osst_tape * STp = filp->private_data;
3297 char * name = tape_name(STp);
3300 if (down_interruptible(&STp->lock))
3301 return (-ERESTARTSYS);
3304 * If we are in the middle of error recovery, don't let anyone
3305 * else try and use this device. Also, if error recovery fails, it
3306 * may try and take the device offline, in which case all further
3307 * access to the device is prohibited.
3309 if( !scsi_block_when_processing_errors(STp->device) ) {
3314 if (STp->ready != ST_READY) {
3315 if (STp->ready == ST_NO_TAPE)
3316 retval = (-ENOMEDIUM);
3321 STm = &(STp->modes[STp->current_mode]);
3322 if (!STm->defined) {
3330 * If there was a bus reset, block further access
3333 if (STp->pos_unknown) {
3340 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3346 if (STp->write_prot) {
3351 /* Write must be integral number of blocks */
3352 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3353 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3354 name, count, STp->block_size<1024?
3355 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3360 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3361 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3362 name, STp->first_frame_position);
3367 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3368 STp->door_locked = ST_LOCKED_AUTO;
3370 STps = &(STp->ps[STp->partition]);
3372 if (STps->rw == ST_READING) {
3374 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3375 STps->drv_file, STps->drv_block);
3377 retval = osst_flush_buffer(STp, &SRpnt, 0);
3382 if (STps->rw != ST_WRITING) {
3383 /* Are we totally rewriting this tape? */
3384 if (!STp->header_ok ||
3385 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3386 (STps->drv_file == 0 && STps->drv_block == 0)) {
3387 STp->wrt_pass_cntr++;
3389 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3390 name, STp->wrt_pass_cntr);
3392 osst_reset_header(STp, &SRpnt);
3393 STps->drv_file = STps->drv_block = 0;
3395 /* Do we know where we'll be writing on the tape? */
3397 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3398 STps->drv_file < 0 || STps->drv_block < 0) {
3399 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3400 STps->drv_file = STp->filemark_cnt;
3401 STps->drv_block = 0;
3404 /* We have no idea where the tape is positioned - give up */
3407 "%s:D: Cannot write at indeterminate position.\n", name);
3413 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3414 STp->filemark_cnt = STps->drv_file;
3415 STp->last_mark_ppos =
3416 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3418 "%s:W: Overwriting file %d with old write pass counter %d\n",
3419 name, STps->drv_file, STp->wrt_pass_cntr);
3421 "%s:W: may lead to stale data being accepted on reading back!\n",
3425 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3426 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3432 if (!STp->header_ok) {
3434 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3440 if ((STp->buffer)->writing) {
3441 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3442 osst_write_behind_check(STp);
3443 if ((STp->buffer)->syscall_result) {
3446 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3447 (STp->buffer)->midlevel_result);
3449 if ((STp->buffer)->midlevel_result == INT_MAX)
3450 STps->eof = ST_EOM_OK;
3452 STps->eof = ST_EOM_ERROR;
3455 if (STps->eof == ST_EOM_OK) {
3459 else if (STps->eof == ST_EOM_ERROR) {
3464 /* Check the buffer readability in cases where copy_user might catch
3465 the problems after some tape movement. */
3466 if ((copy_from_user(&i, buf, 1) != 0 ||
3467 copy_from_user(&i, buf + count - 1, 1) != 0)) {
3472 if (!STm->do_buffer_writes) {
3473 write_threshold = 1;
3476 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3477 if (!STm->do_async_writes)
3483 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3484 name, (int) count, STps->drv_file, STps->drv_block,
3485 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3488 while ((STp->buffer)->buffer_bytes + count > write_threshold)
3491 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3492 (STp->buffer)->buffer_bytes;
3493 if (do_count > count)
3496 i = append_to_buffer(b_point, STp->buffer, do_count);
3502 blks = do_count / STp->block_size;
3503 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3505 i = osst_write_frame(STp, &SRpnt, 1);
3507 if (i == (-ENOSPC)) {
3508 transfer = STp->buffer->writing; /* FIXME -- check this logic */
3509 if (transfer <= do_count) {
3510 filp->f_pos += do_count - transfer;
3511 count -= do_count - transfer;
3512 if (STps->drv_block >= 0) {
3513 STps->drv_block += (do_count - transfer) / STp->block_size;
3515 STps->eof = ST_EOM_OK;
3516 retval = (-ENOSPC); /* EOM within current request */
3519 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3520 name, (int) transfer);
3524 STps->eof = ST_EOM_ERROR;
3525 STps->drv_block = (-1); /* Too cautious? */
3526 retval = (-EIO); /* EOM for old data */
3529 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3537 if (SRpnt != NULL) {
3538 osst_release_request(SRpnt);
3541 STp->buffer->buffer_bytes = 0;
3544 retval = total - count;
3548 filp->f_pos += do_count;
3549 b_point += do_count;
3551 if (STps->drv_block >= 0) {
3552 STps->drv_block += blks;
3554 STp->buffer->buffer_bytes = 0;
3556 } /* end while write threshold exceeded */
3560 i = append_to_buffer(b_point, STp->buffer, count);
3565 blks = count / STp->block_size;
3566 STp->logical_blk_num += blks;
3567 if (STps->drv_block >= 0) {
3568 STps->drv_block += blks;
3570 filp->f_pos += count;
3574 if (doing_write && (STp->buffer)->syscall_result != 0) {
3575 retval = (STp->buffer)->syscall_result;
3579 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3580 /* Schedule an asynchronous write */
3581 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3582 STp->block_size) * STp->block_size;
3583 STp->dirty = !((STp->buffer)->writing ==
3584 (STp->buffer)->buffer_bytes);
3586 i = osst_write_frame(STp, &SRpnt, 0);
3591 SRpnt = NULL; /* Prevent releasing this request! */
3593 STps->at_sm &= (total == 0);
3595 STps->eof = ST_NOEOF;
3600 if (SRpnt != NULL) osst_release_request(SRpnt);
3609 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3611 ssize_t total, retval = 0;
3612 ssize_t i, transfer;
3614 struct st_modedef * STm;
3615 struct st_partstat * STps;
3616 struct osst_request * SRpnt = NULL;
3617 struct osst_tape * STp = filp->private_data;
3618 char * name = tape_name(STp);
3621 if (down_interruptible(&STp->lock))
3622 return (-ERESTARTSYS);
3625 * If we are in the middle of error recovery, don't let anyone
3626 * else try and use this device. Also, if error recovery fails, it
3627 * may try and take the device offline, in which case all further
3628 * access to the device is prohibited.
3630 if( !scsi_block_when_processing_errors(STp->device) ) {
3635 if (STp->ready != ST_READY) {
3636 if (STp->ready == ST_NO_TAPE)
3637 retval = (-ENOMEDIUM);
3642 STm = &(STp->modes[STp->current_mode]);
3643 if (!STm->defined) {
3649 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3654 /* Must have initialized medium */
3655 if (!STp->header_ok) {
3660 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3661 STp->door_locked = ST_LOCKED_AUTO;
3663 STps = &(STp->ps[STp->partition]);
3664 if (STps->rw == ST_WRITING) {
3665 retval = osst_flush_buffer(STp, &SRpnt, 0);
3669 /* FIXME -- this may leave the tape without EOD and up2date headers */
3672 if ((count % STp->block_size) != 0) {
3674 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3675 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3679 if (debugging && STps->eof != ST_NOEOF)
3680 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3681 STps->eof, (STp->buffer)->buffer_bytes);
3683 if ((STp->buffer)->buffer_bytes == 0 &&
3684 STps->eof >= ST_EOD_1) {
3685 if (STps->eof < ST_EOD) {
3690 retval = (-EIO); /* EOM or Blank Check */
3694 /* Check the buffer writability before any tape movement. Don't alter
3696 if (copy_from_user(&i, buf, 1) != 0 ||
3697 copy_to_user (buf, &i, 1) != 0 ||
3698 copy_from_user(&i, buf + count - 1, 1) != 0 ||
3699 copy_to_user (buf + count - 1, &i, 1) != 0) {
3704 /* Loop until enough data in buffer or a special condition found */
3705 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3707 /* Get new data if the buffer is empty */
3708 if ((STp->buffer)->buffer_bytes == 0) {
3709 if (STps->eof == ST_FM_HIT)
3711 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3712 if (special < 0) { /* No need to continue read */
3713 STp->frame_in_buffer = 0;
3719 /* Move the data from driver buffer to user buffer */
3720 if ((STp->buffer)->buffer_bytes > 0) {
3722 if (debugging && STps->eof != ST_NOEOF)
3723 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3724 STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total));
3726 /* force multiple of block size, note block_size may have been adjusted */
3727 transfer = (((STp->buffer)->buffer_bytes < count - total ?
3728 (STp->buffer)->buffer_bytes : count - total)/
3729 STp->block_size) * STp->block_size;
3731 if (transfer == 0) {
3733 "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
3734 name, count, STp->block_size < 1024?
3735 STp->block_size:STp->block_size/1024,
3736 STp->block_size<1024?'b':'k');
3739 i = from_buffer(STp->buffer, buf, transfer);
3744 STp->logical_blk_num += transfer / STp->block_size;
3745 STps->drv_block += transfer / STp->block_size;
3746 filp->f_pos += transfer;
3751 if ((STp->buffer)->buffer_bytes == 0) {
3754 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3755 name, STp->frame_seq_number);
3757 STp->frame_in_buffer = 0;
3758 STp->frame_seq_number++; /* frame to look for next time */
3760 } /* for (total = 0, special = 0; total < count && !special; ) */
3762 /* Change the eof state if no data from tape or buffer */
3764 if (STps->eof == ST_FM_HIT) {
3765 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3766 STps->drv_block = 0;
3767 if (STps->drv_file >= 0)
3770 else if (STps->eof == ST_EOD_1) {
3771 STps->eof = ST_EOD_2;
3772 if (STps->drv_block > 0 && STps->drv_file >= 0)
3774 STps->drv_block = 0;
3776 else if (STps->eof == ST_EOD_2)
3779 else if (STps->eof == ST_FM)
3780 STps->eof = ST_NOEOF;
3785 if (SRpnt != NULL) osst_release_request(SRpnt);
3793 /* Set the driver options */
3794 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3797 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3798 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3799 STm->do_read_ahead);
3801 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3802 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3804 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3805 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3806 STp->scsi2_logical);
3808 "%s:I: sysv: %d\n", name, STm->sysv);
3811 "%s:D: debugging: %d\n",
3817 static int osst_set_options(struct osst_tape *STp, long options)
3821 struct st_modedef * STm;
3822 char * name = tape_name(STp);
3824 STm = &(STp->modes[STp->current_mode]);
3825 if (!STm->defined) {
3826 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3830 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3831 name, STp->current_mode);
3835 code = options & MT_ST_OPTIONS;
3836 if (code == MT_ST_BOOLEANS) {
3837 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3838 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3839 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3840 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3841 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3842 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3843 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3844 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3845 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3846 if ((STp->device)->scsi_level >= SCSI_2)
3847 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3848 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3849 STm->sysv = (options & MT_ST_SYSV) != 0;
3851 debugging = (options & MT_ST_DEBUGGING) != 0;
3853 osst_log_options(STp, STm, name);
3855 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3856 value = (code == MT_ST_SETBOOLEANS);
3857 if ((options & MT_ST_BUFFER_WRITES) != 0)
3858 STm->do_buffer_writes = value;
3859 if ((options & MT_ST_ASYNC_WRITES) != 0)
3860 STm->do_async_writes = value;
3861 if ((options & MT_ST_DEF_WRITES) != 0)
3862 STm->defaults_for_writes = value;
3863 if ((options & MT_ST_READ_AHEAD) != 0)
3864 STm->do_read_ahead = value;
3865 if ((options & MT_ST_TWO_FM) != 0)
3866 STp->two_fm = value;
3867 if ((options & MT_ST_FAST_MTEOM) != 0)
3868 STp->fast_mteom = value;
3869 if ((options & MT_ST_AUTO_LOCK) != 0)
3870 STp->do_auto_lock = value;
3871 if ((options & MT_ST_CAN_BSR) != 0)
3872 STp->can_bsr = value;
3873 if ((options & MT_ST_NO_BLKLIMS) != 0)
3874 STp->omit_blklims = value;
3875 if ((STp->device)->scsi_level >= SCSI_2 &&
3876 (options & MT_ST_CAN_PARTITIONS) != 0)
3877 STp->can_partitions = value;
3878 if ((options & MT_ST_SCSI2LOGICAL) != 0)
3879 STp->scsi2_logical = value;
3880 if ((options & MT_ST_SYSV) != 0)
3883 if ((options & MT_ST_DEBUGGING) != 0)
3886 osst_log_options(STp, STm, name);
3888 else if (code == MT_ST_WRITE_THRESHOLD) {
3889 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3890 if (value < 1 || value > osst_buffer_size) {
3891 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3895 STp->write_threshold = value;
3896 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3899 else if (code == MT_ST_DEF_BLKSIZE) {
3900 value = (options & ~MT_ST_OPTIONS);
3901 if (value == ~MT_ST_OPTIONS) {
3902 STm->default_blksize = (-1);
3903 printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3906 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3907 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3911 STm->default_blksize = value;
3912 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
3913 name, STm->default_blksize);
3916 else if (code == MT_ST_TIMEOUTS) {
3917 value = (options & ~MT_ST_OPTIONS);
3918 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
3919 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
3920 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
3921 (value & ~MT_ST_SET_LONG_TIMEOUT));
3924 STp->timeout = value * HZ;
3925 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
3928 else if (code == MT_ST_DEF_OPTIONS) {
3929 code = (options & ~MT_ST_CLEAR_DEFAULT);
3930 value = (options & MT_ST_CLEAR_DEFAULT);
3931 if (code == MT_ST_DEF_DENSITY) {
3932 if (value == MT_ST_CLEAR_DEFAULT) {
3933 STm->default_density = (-1);
3934 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
3937 STm->default_density = value & 0xff;
3938 printk(KERN_INFO "%s:I: Density default set to %x\n",
3939 name, STm->default_density);
3942 else if (code == MT_ST_DEF_DRVBUFFER) {
3943 if (value == MT_ST_CLEAR_DEFAULT) {
3944 STp->default_drvbuffer = 0xff;
3945 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
3948 STp->default_drvbuffer = value & 7;
3949 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
3950 name, STp->default_drvbuffer);
3953 else if (code == MT_ST_DEF_COMPRESSION) {
3954 if (value == MT_ST_CLEAR_DEFAULT) {
3955 STm->default_compression = ST_DONT_TOUCH;
3956 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
3959 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
3960 printk(KERN_INFO "%s:I: Compression default set to %x\n",
3972 /* Internal ioctl function */
3973 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt,
3974 unsigned int cmd_in, unsigned long arg)
3978 int i, ioctl_result;
3980 unsigned char cmd[MAX_COMMAND_SIZE];
3981 struct osst_request * SRpnt = * aSRpnt;
3982 struct st_partstat * STps;
3983 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
3984 int datalen = 0, direction = DMA_NONE;
3985 char * name = tape_name(STp);
3987 if (STp->ready != ST_READY && cmd_in != MTLOAD) {
3988 if (STp->ready == ST_NO_TAPE)
3989 return (-ENOMEDIUM);
3993 timeout = STp->long_timeout;
3994 STps = &(STp->ps[STp->partition]);
3995 fileno = STps->drv_file;
3996 blkno = STps->drv_block;
3997 at_sm = STps->at_sm;
3998 frame_seq_numbr = STp->frame_seq_number;
3999 logical_blk_num = STp->logical_blk_num;
4001 memset(cmd, 0, MAX_COMMAND_SIZE);
4004 chg_eof = 0; /* Changed from the FSF after this */
4008 if (STp->linux_media)
4009 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
4011 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
4015 at_sm &= (arg == 0);
4019 chg_eof = 0; /* Changed from the FSF after this */
4023 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
4026 blkno = (-1); /* We can't know the block number */
4027 at_sm &= (arg == 0);
4034 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
4035 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
4037 if (cmd_in == MTFSR) {
4038 logical_blk_num += arg;
4039 if (blkno >= 0) blkno += arg;
4042 logical_blk_num -= arg;
4043 if (blkno >= 0) blkno -= arg;
4045 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
4046 fileno = STps->drv_file;
4047 blkno = STps->drv_block;
4048 at_sm &= (arg == 0);
4053 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4054 cmd[2] = (arg >> 16);
4055 cmd[3] = (arg >> 8);
4059 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4060 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4063 blkno = fileno = (-1);
4069 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4071 cmd[2] = (ltmp >> 16);
4072 cmd[3] = (ltmp >> 8);
4078 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4079 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4084 blkno = fileno = (-1);
4089 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4090 STp->write_type = OS_WRITE_DATA;
4091 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4096 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4098 for (i=0; i<arg; i++)
4099 ioctl_result |= osst_write_filemark(STp, &SRpnt);
4100 if (fileno >= 0) fileno += arg;
4101 if (blkno >= 0) blkno = 0;
4105 if (STp->write_prot)
4109 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
4110 if (cmd_in == MTWSM)
4112 cmd[2] = (arg >> 16);
4113 cmd[3] = (arg >> 8);
4115 timeout = STp->timeout;
4118 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4119 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4124 at_sm = (cmd_in == MTWSM);
4130 cmd[0] = START_STOP;
4131 cmd[1] = 1; /* Don't wait for completion */
4132 if (cmd_in == MTLOAD) {
4133 if (STp->ready == ST_NO_TAPE)
4134 cmd[4] = 4; /* open tray */
4136 cmd[4] = 1; /* load */
4138 if (cmd_in == MTRETEN)
4139 cmd[4] = 3; /* retension then mount */
4140 if (cmd_in == MTOFFL)
4141 cmd[4] = 4; /* rewind then eject */
4142 timeout = STp->timeout;
4147 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4150 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4153 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4156 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4161 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4166 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4168 return 0; /* Should do something ? */
4173 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4175 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4176 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4177 ioctl_result = -EIO;
4180 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4182 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4184 ioctl_result = -EIO;
4187 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4188 fileno = STp->filemark_cnt;
4193 if (STp->write_prot)
4195 ioctl_result = osst_reset_header(STp, &SRpnt);
4196 i = osst_write_eod(STp, &SRpnt);
4197 if (i < ioctl_result) ioctl_result = i;
4198 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4199 if (i < ioctl_result) ioctl_result = i;
4200 fileno = blkno = at_sm = 0 ;
4204 cmd[0] = REZERO_UNIT; /* rewind */
4208 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4210 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4213 case MTSETBLK: /* Set block length */
4214 if ((STps->drv_block == 0 ) &&
4216 ((STp->buffer)->buffer_bytes == 0) &&
4217 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4218 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4219 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4221 * Only allowed to change the block size if you opened the
4222 * device at the beginning of a file before writing anything.
4223 * Note, that when reading, changing block_size is futile,
4224 * as the size used when writing overrides it.
4226 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4227 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4228 name, STp->block_size);
4231 case MTSETDENSITY: /* Set tape density */
4232 case MTSETDRVBUFFER: /* Set drive buffering */
4233 case SET_DENS_AND_BLK: /* Set density and block size */
4235 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4236 return (-EIO); /* Not allowed if data in buffer */
4237 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4238 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4239 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4240 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4241 name, (int)(arg & MT_ST_BLKSIZE_MASK),
4242 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4245 return 0; /* FIXME silently ignore if block size didn't change */
4251 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4253 ioctl_result = (STp->buffer)->syscall_result;
4257 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4259 return ioctl_result;
4262 if (!ioctl_result) { /* SCSI command successful */
4263 STp->frame_seq_number = frame_seq_numbr;
4264 STp->logical_blk_num = logical_blk_num;
4270 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4273 if (!ioctl_result) { /* success */
4275 if (cmd_in == MTFSFM) {
4279 if (cmd_in == MTBSFM) {
4283 STps->drv_block = blkno;
4284 STps->drv_file = fileno;
4285 STps->at_sm = at_sm;
4287 if (cmd_in == MTEOM)
4289 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4290 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4292 STp->logical_blk_num++;
4293 STp->frame_seq_number++;
4294 STp->frame_in_buffer = 0;
4295 STp->buffer->read_pointer = 0;
4297 else if (cmd_in == MTFSF)
4298 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4300 STps->eof = ST_NOEOF;
4302 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4303 STp->rew_at_close = 0;
4304 else if (cmd_in == MTLOAD) {
4305 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4306 STp->ps[i].rw = ST_IDLE;
4307 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4312 if (cmd_in == MTREW) {
4313 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4314 if (ioctl_result > 0)
4318 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4319 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4320 STps->drv_file = STps->drv_block = -1;
4322 STps->drv_file = STps->drv_block = 0;
4323 STps->eof = ST_NOEOF;
4324 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4325 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4326 STps->drv_file = STps->drv_block = -1;
4328 STps->drv_file = STp->filemark_cnt;
4329 STps->drv_block = 0;
4332 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4333 STps->drv_file = STps->drv_block = (-1);
4334 STps->eof = ST_NOEOF;
4336 } else if (cmd_in == MTERASE) {
4338 } else if (SRpnt) { /* SCSI command was not completely successful. */
4339 if (SRpnt->sense[2] & 0x40) {
4340 STps->eof = ST_EOM_OK;
4341 STps->drv_block = 0;
4344 STps->eof = ST_NOEOF;
4346 if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK)
4349 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4350 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4354 return ioctl_result;
4358 /* Open the device */
4359 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4361 unsigned short flags;
4362 int i, b_size, new_session = 0, retval = 0;
4363 unsigned char cmd[MAX_COMMAND_SIZE];
4364 struct osst_request * SRpnt = NULL;
4365 struct osst_tape * STp;
4366 struct st_modedef * STm;
4367 struct st_partstat * STps;
4369 int dev = TAPE_NR(inode);
4370 int mode = TAPE_MODE(inode);
4373 * We really want to do nonseekable_open(inode, filp); here, but some
4374 * versions of tar incorrectly call lseek on tapes and bail out if that
4375 * fails. So we disallow pread() and pwrite(), but permit lseeks.
4377 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
4379 write_lock(&os_scsi_tapes_lock);
4380 if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4381 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4382 write_unlock(&os_scsi_tapes_lock);
4386 name = tape_name(STp);
4389 write_unlock(&os_scsi_tapes_lock);
4391 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4395 if (scsi_device_get(STp->device)) {
4396 write_unlock(&os_scsi_tapes_lock);
4398 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4402 filp->private_data = STp;
4404 write_unlock(&os_scsi_tapes_lock);
4405 STp->rew_at_close = TAPE_REWIND(inode);
4407 if( !scsi_block_when_processing_errors(STp->device) ) {
4411 if (mode != STp->current_mode) {
4414 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4415 name, STp->current_mode, mode);
4418 STp->current_mode = mode;
4420 STm = &(STp->modes[STp->current_mode]);
4422 flags = filp->f_flags;
4423 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4425 STp->raw = TAPE_IS_RAW(inode);
4429 /* Allocate data segments for this device's tape buffer */
4430 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4431 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4432 retval = (-EOVERFLOW);
4435 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4436 for (i = 0, b_size = 0;
4437 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4438 b_size += STp->buffer->sg[i++].length);
4439 STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
4441 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4442 STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4443 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4444 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4447 STp->buffer->aux = NULL; /* this had better never happen! */
4448 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4452 STp->buffer->writing = 0;
4453 STp->buffer->syscall_result = 0;
4455 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4456 STps = &(STp->ps[i]);
4459 STp->ready = ST_READY;
4461 STp->nbr_waits = STp->nbr_finished = 0;
4464 memset (cmd, 0, MAX_COMMAND_SIZE);
4465 cmd[0] = TEST_UNIT_READY;
4467 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4469 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
4472 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4473 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4474 SRpnt->sense[12] == 4 ) {
4476 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]);
4478 if (filp->f_flags & O_NONBLOCK) {
4482 if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */
4483 memset (cmd, 0, MAX_COMMAND_SIZE);
4484 cmd[0] = START_STOP;
4487 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4488 STp->timeout, MAX_RETRIES, 1);
4490 osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
4492 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4493 (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4495 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4499 for (i=0; i < 10; i++) {
4501 memset (cmd, 0, MAX_COMMAND_SIZE);
4502 cmd[0] = TEST_UNIT_READY;
4504 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4505 STp->timeout, MAX_RETRIES, 1);
4506 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4507 (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
4511 STp->pos_unknown = 0;
4512 STp->partition = STp->new_partition = 0;
4513 if (STp->can_partitions)
4514 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4515 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4516 STps = &(STp->ps[i]);
4517 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4518 STps->eof = ST_NOEOF;
4520 STps->last_block_valid = 0;
4521 STps->drv_block = 0;
4522 STps->drv_file = 0 ;
4525 STp->recover_count = 0;
4526 STp->abort_count = 0;
4529 * if we have valid headers from before, and the drive/tape seem untouched,
4530 * open without reconfiguring and re-reading the headers
4532 if (!STp->buffer->syscall_result && STp->header_ok &&
4533 !SRpnt->result && SRpnt->sense[0] == 0) {
4535 memset(cmd, 0, MAX_COMMAND_SIZE);
4536 cmd[0] = MODE_SENSE;
4538 cmd[2] = VENDOR_IDENT_PAGE;
4539 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4541 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4543 if (STp->buffer->syscall_result ||
4544 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4545 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4546 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4547 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4549 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4550 STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4551 STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4552 STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4553 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4557 i = STp->first_frame_position;
4558 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4559 if (STp->door_locked == ST_UNLOCKED) {
4560 if (do_door_lock(STp, 1))
4561 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4563 STp->door_locked = ST_LOCKED_AUTO;
4565 if (!STp->frame_in_buffer) {
4566 STp->block_size = (STm->default_blksize > 0) ?
4567 STm->default_blksize : OS_DATA_SIZE;
4568 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4570 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4572 osst_release_request(SRpnt);
4576 if (i != STp->first_frame_position)
4577 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4578 name, i, STp->first_frame_position);
4584 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4585 (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) {
4587 memset(cmd, 0, MAX_COMMAND_SIZE);
4588 cmd[0] = MODE_SELECT;
4590 cmd[4] = 4 + MODE_HEADER_LENGTH;
4592 (STp->buffer)->b_data[0] = cmd[4] - 1;
4593 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4594 (STp->buffer)->b_data[2] = 0; /* Reserved */
4595 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4596 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4597 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4598 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4599 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4602 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4604 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4608 for (i=0; i < 10; i++) {
4610 memset (cmd, 0, MAX_COMMAND_SIZE);
4611 cmd[0] = TEST_UNIT_READY;
4613 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4614 STp->timeout, MAX_RETRIES, 1);
4615 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4616 (SRpnt->sense[2] & 0x0f) == NOT_READY)
4619 if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
4620 STp->pos_unknown = 0;
4621 STp->partition = STp->new_partition = 0;
4622 if (STp->can_partitions)
4623 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4624 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4625 STps = &(STp->ps[i]);
4627 STps->eof = ST_NOEOF;
4629 STps->last_block_valid = 0;
4630 STps->drv_block = 0;
4631 STps->drv_file = 0 ;
4638 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4639 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4641 if ((STp->buffer)->syscall_result != 0) {
4642 if ((STp->device)->scsi_level >= SCSI_2 &&
4643 (SRpnt->sense[0] & 0x70) == 0x70 &&
4644 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4645 SRpnt->sense[12] == 0x3a) { /* Check ASC */
4646 STp->ready = ST_NO_TAPE;
4648 STp->ready = ST_NOT_READY;
4649 osst_release_request(SRpnt);
4651 STp->density = 0; /* Clear the erroneous "residue" */
4652 STp->write_prot = 0;
4653 STp->block_size = 0;
4654 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4655 STp->partition = STp->new_partition = 0;
4656 STp->door_locked = ST_UNLOCKED;
4660 osst_configure_onstream(STp, &SRpnt);
4662 STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4663 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4664 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4665 STp->buffer->buffer_bytes =
4666 STp->buffer->read_pointer =
4667 STp->frame_in_buffer = 0;
4671 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4672 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4673 (STp->buffer)->buffer_blocks);
4676 if (STp->drv_write_prot) {
4677 STp->write_prot = 1;
4680 printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4682 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4688 if (new_session) { /* Change the drive parameters for the new mode */
4691 printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4693 STp->density_changed = STp->blksize_changed = 0;
4694 STp->compression_changed = 0;
4698 * properly position the tape and check the ADR headers
4700 if (STp->door_locked == ST_UNLOCKED) {
4701 if (do_door_lock(STp, 1))
4702 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4704 STp->door_locked = ST_LOCKED_AUTO;
4707 osst_analyze_headers(STp, &SRpnt);
4709 osst_release_request(SRpnt);
4716 osst_release_request(SRpnt);
4717 normalize_buffer(STp->buffer);
4720 scsi_device_put(STp->device);
4726 /* Flush the tape buffer before close */
4727 static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
4729 int result = 0, result2;
4730 struct osst_tape * STp = filp->private_data;
4731 struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4732 struct st_partstat * STps = &(STp->ps[STp->partition]);
4733 struct osst_request * SRpnt = NULL;
4734 char * name = tape_name(STp);
4736 if (file_count(filp) > 1)
4739 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4740 STp->write_type = OS_WRITE_DATA;
4741 result = osst_flush_write_buffer(STp, &SRpnt);
4742 if (result != 0 && result != (-ENOSPC))
4745 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4749 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4750 name, (long)(filp->f_pos));
4751 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4752 name, STp->nbr_waits, STp->nbr_finished);
4755 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4758 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4759 name, 1+STp->two_fm);
4762 else if (!STp->rew_at_close) {
4763 STps = &(STp->ps[STp->partition]);
4764 if (!STm->sysv || STps->rw != ST_READING) {
4766 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4767 else if (STps->eof == ST_FM_HIT) {
4768 result = cross_eof(STp, &SRpnt, 0);
4770 if (STps->drv_file >= 0)
4772 STps->drv_block = 0;
4776 STps->eof = ST_NOEOF;
4779 else if ((STps->eof == ST_NOEOF &&
4780 !(result = cross_eof(STp, &SRpnt, 1))) ||
4781 STps->eof == ST_FM_HIT) {
4782 if (STps->drv_file >= 0)
4784 STps->drv_block = 0;
4790 if (STp->rew_at_close) {
4791 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4792 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4793 if (result == 0 && result2 < 0)
4796 if (SRpnt) osst_release_request(SRpnt);
4798 if (STp->abort_count || STp->recover_count) {
4799 printk(KERN_INFO "%s:I:", name);
4800 if (STp->abort_count)
4801 printk(" %d unrecovered errors", STp->abort_count);
4802 if (STp->recover_count)
4803 printk(" %d recovered errors", STp->recover_count);
4804 if (STp->write_count)
4805 printk(" in %d frames written", STp->write_count);
4806 if (STp->read_count)
4807 printk(" in %d frames read", STp->read_count);
4809 STp->recover_count = 0;
4810 STp->abort_count = 0;
4812 STp->write_count = 0;
4813 STp->read_count = 0;
4819 /* Close the device and release it */
4820 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4823 struct osst_tape * STp = filp->private_data;
4825 if (STp->door_locked == ST_LOCKED_AUTO)
4826 do_door_lock(STp, 0);
4831 normalize_buffer(STp->buffer);
4832 write_lock(&os_scsi_tapes_lock);
4834 write_unlock(&os_scsi_tapes_lock);
4836 scsi_device_put(STp->device);
4842 /* The ioctl command */
4843 static int osst_ioctl(struct inode * inode,struct file * file,
4844 unsigned int cmd_in, unsigned long arg)
4846 int i, cmd_nr, cmd_type, retval = 0;
4848 struct st_modedef * STm;
4849 struct st_partstat * STps;
4850 struct osst_request * SRpnt = NULL;
4851 struct osst_tape * STp = file->private_data;
4852 char * name = tape_name(STp);
4853 void __user * p = (void __user *)arg;
4855 if (down_interruptible(&STp->lock))
4856 return -ERESTARTSYS;
4859 if (debugging && !STp->in_use) {
4860 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4865 STm = &(STp->modes[STp->current_mode]);
4866 STps = &(STp->ps[STp->partition]);
4869 * If we are in the middle of error recovery, don't let anyone
4870 * else try and use this device. Also, if error recovery fails, it
4871 * may try and take the device offline, in which case all further
4872 * access to the device is prohibited.
4874 if( !scsi_block_when_processing_errors(STp->device) ) {
4879 cmd_type = _IOC_TYPE(cmd_in);
4880 cmd_nr = _IOC_NR(cmd_in);
4882 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4883 cmd_type, cmd_nr, STp->raw?"raw":"normal");
4885 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4889 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
4894 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
4900 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
4901 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
4906 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
4911 if (!STp->pos_unknown) {
4913 if (STps->eof == ST_FM_HIT) {
4914 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
4916 if (STps->drv_file >= 0)
4917 STps->drv_file += 1;
4919 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
4921 if (STps->drv_file >= 0)
4922 STps->drv_file += 1;
4926 if (mtc.mt_op == MTSEEK) {
4927 /* Old position must be restored if partition will be changed */
4928 i = !STp->can_partitions || (STp->new_partition != STp->partition);
4931 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
4932 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
4933 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
4934 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
4935 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
4936 mtc.mt_op == MTCOMPRESSION;
4938 i = osst_flush_buffer(STp, &SRpnt, i);
4946 * If there was a bus reset, block further access
4947 * to this device. If the user wants to rewind the tape,
4948 * then reset the flag and allow access again.
4950 if(mtc.mt_op != MTREW &&
4951 mtc.mt_op != MTOFFL &&
4952 mtc.mt_op != MTRETEN &&
4953 mtc.mt_op != MTERASE &&
4954 mtc.mt_op != MTSEEK &&
4955 mtc.mt_op != MTEOM) {
4960 /* remove this when the midlevel properly clears was_reset */
4961 STp->device->was_reset = 0;
4964 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK &&
4965 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
4966 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER &&
4967 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART &&
4968 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) {
4971 * The user tells us to move to another position on the tape.
4972 * If we were appending to the tape content, that would leave
4973 * the tape without proper end, in that case write EOD and
4974 * update the header to reflect its position.
4977 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
4978 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
4979 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
4980 STp->logical_blk_num, STps->drv_file, STps->drv_block );
4982 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
4983 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
4984 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4985 i = osst_write_trailer(STp, &SRpnt,
4986 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4988 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
4989 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
4990 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
5000 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
5001 do_door_lock(STp, 0); /* Ignore result! */
5003 if (mtc.mt_op == MTSETDRVBUFFER &&
5004 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
5005 retval = osst_set_options(STp, mtc.mt_count);
5009 if (mtc.mt_op == MTSETPART) {
5010 if (mtc.mt_count >= STp->nbr_partitions)
5013 STp->new_partition = mtc.mt_count;
5019 if (mtc.mt_op == MTMKPART) {
5020 if (!STp->can_partitions) {
5024 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
5025 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
5029 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5030 STp->ps[i].rw = ST_IDLE;
5031 STp->ps[i].at_sm = 0;
5032 STp->ps[i].last_block_valid = 0;
5034 STp->partition = STp->new_partition = 0;
5035 STp->nbr_partitions = 1; /* Bad guess ?-) */
5036 STps->drv_block = STps->drv_file = 0;
5041 if (mtc.mt_op == MTSEEK) {
5043 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
5045 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
5046 if (!STp->can_partitions)
5047 STp->ps[0].rw = ST_IDLE;
5052 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
5053 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
5058 cross_eof(STp, &SRpnt, 0);
5060 if (mtc.mt_op == MTCOMPRESSION)
5061 retval = -EINVAL; /* OnStream drives don't have compression hardware */
5063 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5064 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5065 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5069 if (!STm->defined) {
5074 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5079 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
5080 struct mtget mt_status;
5082 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
5087 mt_status.mt_type = MT_ISONSTREAM_SC;
5088 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
5089 mt_status.mt_dsreg =
5090 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
5091 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
5092 mt_status.mt_blkno = STps->drv_block;
5093 mt_status.mt_fileno = STps->drv_file;
5094 if (STp->block_size != 0) {
5095 if (STps->rw == ST_WRITING)
5096 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
5097 else if (STps->rw == ST_READING)
5098 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
5099 STp->block_size - 1) / STp->block_size;
5102 mt_status.mt_gstat = 0;
5103 if (STp->drv_write_prot)
5104 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
5105 if (mt_status.mt_blkno == 0) {
5106 if (mt_status.mt_fileno == 0)
5107 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
5109 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
5111 mt_status.mt_resid = STp->partition;
5112 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
5113 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
5114 else if (STps->eof >= ST_EOM_OK)
5115 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
5116 if (STp->density == 1)
5117 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
5118 else if (STp->density == 2)
5119 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
5120 else if (STp->density == 3)
5121 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
5122 if (STp->ready == ST_READY)
5123 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
5124 if (STp->ready == ST_NO_TAPE)
5125 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
5127 mt_status.mt_gstat |= GMT_SM(0xffffffff);
5128 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
5129 STp->drv_buffer != 0)
5130 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
5132 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
5138 STp->recover_erreg = 0; /* Clear after read */
5141 } /* End of MTIOCGET */
5143 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5144 struct mtpos mt_pos;
5146 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5151 blk = osst_get_frame_position(STp, &SRpnt);
5153 blk = osst_get_sector(STp, &SRpnt);
5158 mt_pos.mt_blkno = blk;
5159 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5164 if (SRpnt) osst_release_request(SRpnt);
5168 return scsi_ioctl(STp->device, cmd_in, p);
5171 if (SRpnt) osst_release_request(SRpnt);
5178 #ifdef CONFIG_COMPAT
5179 static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg)
5181 struct osst_tape *STp = file->private_data;
5182 struct scsi_device *sdev = STp->device;
5183 int ret = -ENOIOCTLCMD;
5184 if (sdev->host->hostt->compat_ioctl) {
5186 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
5195 /* Memory handling routines */
5197 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5198 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5202 struct osst_buffer *tb;
5204 if (from_initialization)
5205 priority = GFP_ATOMIC;
5207 priority = GFP_KERNEL;
5209 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5210 tb = (struct osst_buffer *)kmalloc(i, priority);
5212 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5216 tb->sg_segs = tb->orig_sg_segs = 0;
5217 tb->use_sg = max_sg;
5220 tb->buffer_size = 0;
5224 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5225 i, max_sg, need_dma);
5230 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5231 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5233 int segs, nbr, max_segs, b_size, order, got;
5236 if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5239 if (STbuffer->sg_segs) {
5240 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5241 normalize_buffer(STbuffer);
5243 /* See how many segments we can use -- need at least two */
5244 nbr = max_segs = STbuffer->use_sg;
5248 priority = GFP_KERNEL /* | __GFP_NOWARN */;
5250 priority |= GFP_DMA;
5252 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5253 big enough to reach the goal (code assumes no segments in place) */
5254 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5255 STbuffer->sg[0].page = alloc_pages(priority, order);
5256 STbuffer->sg[0].offset = 0;
5257 if (STbuffer->sg[0].page != NULL) {
5258 STbuffer->sg[0].length = b_size;
5259 STbuffer->b_data = page_address(STbuffer->sg[0].page);
5263 if (STbuffer->sg[0].page == NULL) {
5264 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5267 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5268 for (segs=STbuffer->sg_segs=1, got=b_size;
5269 segs < max_segs && got < OS_FRAME_SIZE; ) {
5270 STbuffer->sg[segs].page =
5271 alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5272 STbuffer->sg[segs].offset = 0;
5273 if (STbuffer->sg[segs].page == NULL) {
5274 if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
5275 b_size /= 2; /* Large enough for the rest of the buffers */
5279 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5282 STbuffer->buffer_size = got;
5284 normalize_buffer(STbuffer);
5287 STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
5288 got += STbuffer->sg[segs].length;
5289 STbuffer->buffer_size = got;
5290 STbuffer->sg_segs = ++segs;
5295 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5296 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5298 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5299 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5300 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5308 /* Release the segments */
5309 static void normalize_buffer(struct osst_buffer *STbuffer)
5311 int i, order, b_size;
5313 for (i=0; i < STbuffer->sg_segs; i++) {
5315 for (b_size = PAGE_SIZE, order = 0;
5316 b_size < STbuffer->sg[i].length;
5317 b_size *= 2, order++);
5319 __free_pages(STbuffer->sg[i].page, order);
5320 STbuffer->buffer_size -= STbuffer->sg[i].length;
5323 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5324 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5325 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5327 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5331 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5332 negative error code. */
5333 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
5335 int i, cnt, res, offset;
5337 for (i=0, offset=st_bp->buffer_bytes;
5338 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5339 offset -= st_bp->sg[i].length;
5340 if (i == st_bp->sg_segs) { /* Should never happen */
5341 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5344 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5345 cnt = st_bp->sg[i].length - offset < do_count ?
5346 st_bp->sg[i].length - offset : do_count;
5347 res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
5351 st_bp->buffer_bytes += cnt;
5355 if (do_count) { /* Should never happen */
5356 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5364 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5365 negative error code. */
5366 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
5368 int i, cnt, res, offset;
5370 for (i=0, offset=st_bp->read_pointer;
5371 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5372 offset -= st_bp->sg[i].length;
5373 if (i == st_bp->sg_segs) { /* Should never happen */
5374 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5377 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5378 cnt = st_bp->sg[i].length - offset < do_count ?
5379 st_bp->sg[i].length - offset : do_count;
5380 res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
5384 st_bp->buffer_bytes -= cnt;
5385 st_bp->read_pointer += cnt;
5389 if (do_count) { /* Should never happen */
5390 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5396 /* Sets the tail of the buffer after fill point to zero.
5397 Returns zero (success) or negative error code. */
5398 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
5400 int i, offset, do_count, cnt;
5402 for (i = 0, offset = st_bp->buffer_bytes;
5403 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5404 offset -= st_bp->sg[i].length;
5405 if (i == st_bp->sg_segs) { /* Should never happen */
5406 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5409 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5410 i < st_bp->sg_segs && do_count > 0; i++) {
5411 cnt = st_bp->sg[i].length - offset < do_count ?
5412 st_bp->sg[i].length - offset : do_count ;
5413 memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
5417 if (do_count) { /* Should never happen */
5418 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5424 /* Copy a osst 32K chunk of memory into the buffer.
5425 Returns zero (success) or negative error code. */
5426 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5428 int i, cnt, do_count = OS_DATA_SIZE;
5430 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5431 cnt = st_bp->sg[i].length < do_count ?
5432 st_bp->sg[i].length : do_count ;
5433 memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
5437 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5438 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5445 /* Copy a osst 32K chunk of memory from the buffer.
5446 Returns zero (success) or negative error code. */
5447 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5449 int i, cnt, do_count = OS_DATA_SIZE;
5451 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5452 cnt = st_bp->sg[i].length < do_count ?
5453 st_bp->sg[i].length : do_count ;
5454 memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
5458 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5459 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5467 /* Module housekeeping */
5469 static void validate_options (void)
5472 osst_max_dev = max_dev;
5473 if (write_threshold_kbs > 0)
5474 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5475 if (osst_write_threshold > osst_buffer_size)
5476 osst_write_threshold = osst_buffer_size;
5477 if (max_sg_segs >= OSST_FIRST_SG)
5478 osst_max_sg_segs = max_sg_segs;
5480 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5481 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5486 /* Set the boot options. Syntax: osst=xxx,yyy,...
5487 where xxx is write threshold in 1024 byte blocks,
5488 and yyy is number of s/g segments to use. */
5489 static int __init osst_setup (char *str)
5494 stp = get_options(str, ARRAY_SIZE(ints), ints);
5497 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5498 *parms[i].val = ints[i + 1];
5500 while (stp != NULL) {
5501 for (i = 0; i < ARRAY_SIZE(parms); i++) {
5502 int len = strlen(parms[i].name);
5503 if (!strncmp(stp, parms[i].name, len) &&
5504 (*(stp + len) == ':' || *(stp + len) == '=')) {
5506 simple_strtoul(stp + len + 1, NULL, 0);
5510 if (i >= ARRAY_SIZE(parms))
5511 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5513 stp = strchr(stp, ',');
5522 __setup("osst=", osst_setup);
5526 static struct file_operations osst_fops = {
5527 .owner = THIS_MODULE,
5529 .write = osst_write,
5530 .ioctl = osst_ioctl,
5531 #ifdef CONFIG_COMPAT
5532 .compat_ioctl = osst_compat_ioctl,
5534 .open = os_scsi_tape_open,
5535 .flush = os_scsi_tape_flush,
5536 .release = os_scsi_tape_close,
5539 static int osst_supports(struct scsi_device * SDp)
5541 struct osst_support_data {
5545 char *driver_hint; /* Name of the correct driver, NULL if unknown */
5548 static struct osst_support_data support_list[] = {
5549 /* {"XXX", "Yy-", "", NULL}, example */
5553 struct osst_support_data *rp;
5555 /* We are willing to drive OnStream SC-x0 as well as the
5556 * * IDE, ParPort, FireWire, USB variants, if accessible by
5557 * * emulation layer (ide-scsi, usb-storage, ...) */
5559 for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5560 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5561 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5562 !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5568 * sysfs support for osst driver parameter information
5571 static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
5573 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
5576 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
5578 static void osst_create_driverfs_files(struct device_driver *driverfs)
5580 driver_create_file(driverfs, &driver_attr_version);
5583 static void osst_remove_driverfs_files(struct device_driver *driverfs)
5585 driver_remove_file(driverfs, &driver_attr_version);
5589 * sysfs support for accessing ADR header information
5592 static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf)
5594 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5597 if (STp && STp->header_ok && STp->linux_media)
5598 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
5602 CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
5604 static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf)
5606 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5609 if (STp && STp->header_ok && STp->linux_media)
5610 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
5614 CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
5616 static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf)
5618 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5621 if (STp && STp->header_ok && STp->linux_media)
5622 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
5626 CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
5628 static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf)
5630 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5633 if (STp && STp->header_ok && STp->linux_media)
5634 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
5638 CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
5640 static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf)
5642 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5645 if (STp && STp->header_ok && STp->linux_media)
5646 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
5650 CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
5652 static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf)
5654 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5657 if (STp && STp->header_ok && STp->linux_media)
5658 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
5662 CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5664 static struct class *osst_sysfs_class;
5666 static int osst_sysfs_valid = 0;
5668 static void osst_sysfs_init(void)
5670 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
5671 if ( IS_ERR(osst_sysfs_class) )
5672 printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
5674 osst_sysfs_valid = 1;
5677 static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5679 struct class_device *osst_class_member;
5681 if (!osst_sysfs_valid) return;
5683 osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name);
5684 if (IS_ERR(osst_class_member)) {
5685 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5688 class_set_devdata(osst_class_member, STp);
5689 class_device_create_file(osst_class_member, &class_device_attr_ADR_rev);
5690 class_device_create_file(osst_class_member, &class_device_attr_media_version);
5691 class_device_create_file(osst_class_member, &class_device_attr_capacity);
5692 class_device_create_file(osst_class_member, &class_device_attr_BOT_frame);
5693 class_device_create_file(osst_class_member, &class_device_attr_EOD_frame);
5694 class_device_create_file(osst_class_member, &class_device_attr_file_count);
5697 static void osst_sysfs_destroy(dev_t dev)
5699 if (!osst_sysfs_valid) return;
5701 class_device_destroy(osst_sysfs_class, dev);
5704 static void osst_sysfs_cleanup(void)
5706 if (osst_sysfs_valid) {
5707 class_destroy(osst_sysfs_class);
5708 osst_sysfs_valid = 0;
5713 * osst startup / cleanup code
5716 static int osst_probe(struct device *dev)
5718 struct scsi_device * SDp = to_scsi_device(dev);
5719 struct osst_tape * tpnt;
5720 struct st_modedef * STm;
5721 struct st_partstat * STps;
5722 struct osst_buffer * buffer;
5723 struct gendisk * drive;
5726 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5729 drive = alloc_disk(1);
5731 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5735 /* if this is the first attach, build the infrastructure */
5736 write_lock(&os_scsi_tapes_lock);
5737 if (os_scsi_tapes == NULL) {
5739 (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *),
5741 if (os_scsi_tapes == NULL) {
5742 write_unlock(&os_scsi_tapes_lock);
5743 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5746 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5749 if (osst_nr_dev >= osst_max_dev) {
5750 write_unlock(&os_scsi_tapes_lock);
5751 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5755 /* find a free minor number */
5756 for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++);
5757 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5760 /* allocate a struct osst_tape for this device */
5761 tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
5763 write_unlock(&os_scsi_tapes_lock);
5764 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5767 memset(tpnt, 0, sizeof(struct osst_tape));
5769 /* allocate a buffer for this device */
5770 i = SDp->host->sg_tablesize;
5771 if (osst_max_sg_segs < i)
5772 i = osst_max_sg_segs;
5773 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
5774 if (buffer == NULL) {
5775 write_unlock(&os_scsi_tapes_lock);
5776 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5780 os_scsi_tapes[dev_num] = tpnt;
5781 tpnt->buffer = buffer;
5783 drive->private_data = &tpnt->driver;
5784 sprintf(drive->disk_name, "osst%d", dev_num);
5785 tpnt->driver = &osst_template;
5786 tpnt->drive = drive;
5788 tpnt->capacity = 0xfffff;
5790 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
5791 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5793 tpnt->do_auto_lock = OSST_AUTO_LOCK;
5794 tpnt->can_bsr = OSST_IN_FILE_POS;
5795 tpnt->can_partitions = 0;
5796 tpnt->two_fm = OSST_TWO_FM;
5797 tpnt->fast_mteom = OSST_FAST_MTEOM;
5798 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5799 tpnt->write_threshold = osst_write_threshold;
5800 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5801 tpnt->partition = 0;
5802 tpnt->new_partition = 0;
5803 tpnt->nbr_partitions = 0;
5804 tpnt->min_block = 512;
5805 tpnt->max_block = OS_DATA_SIZE;
5806 tpnt->timeout = OSST_TIMEOUT;
5807 tpnt->long_timeout = OSST_LONG_TIMEOUT;
5809 /* Recognize OnStream tapes */
5810 /* We don't need to test for OnStream, as this has been done in detect () */
5811 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5812 tpnt->omit_blklims = 1;
5814 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5815 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5816 tpnt->frame_in_buffer = 0;
5817 tpnt->header_ok = 0;
5818 tpnt->linux_media = 0;
5819 tpnt->header_cache = NULL;
5821 for (i=0; i < ST_NBR_MODES; i++) {
5822 STm = &(tpnt->modes[i]);
5824 STm->sysv = OSST_SYSV;
5825 STm->defaults_for_writes = 0;
5826 STm->do_async_writes = OSST_ASYNC_WRITES;
5827 STm->do_buffer_writes = OSST_BUFFER_WRITES;
5828 STm->do_read_ahead = OSST_READ_AHEAD;
5829 STm->default_compression = ST_DONT_TOUCH;
5830 STm->default_blksize = 512;
5831 STm->default_density = (-1); /* No forced density */
5834 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5835 STps = &(tpnt->ps[i]);
5837 STps->eof = ST_NOEOF;
5839 STps->last_block_valid = 0;
5840 STps->drv_block = (-1);
5841 STps->drv_file = (-1);
5844 tpnt->current_mode = 0;
5845 tpnt->modes[0].defined = 1;
5846 tpnt->modes[2].defined = 1;
5847 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
5849 init_MUTEX(&tpnt->lock);
5851 write_unlock(&os_scsi_tapes_lock);
5855 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5856 /* No-rewind entry */
5857 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5858 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5861 sdev_printk(KERN_INFO, SDp,
5862 "osst :I: Attached OnStream %.5s tape as %s\n",
5863 SDp->model, tape_name(tpnt));
5872 static int osst_remove(struct device *dev)
5874 struct scsi_device * SDp = to_scsi_device(dev);
5875 struct osst_tape * tpnt;
5878 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
5881 write_lock(&os_scsi_tapes_lock);
5882 for(i=0; i < osst_max_dev; i++) {
5883 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
5884 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
5885 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
5886 tpnt->device = NULL;
5887 put_disk(tpnt->drive);
5888 os_scsi_tapes[i] = NULL;
5890 write_unlock(&os_scsi_tapes_lock);
5891 vfree(tpnt->header_cache);
5893 normalize_buffer(tpnt->buffer);
5894 kfree(tpnt->buffer);
5900 write_unlock(&os_scsi_tapes_lock);
5904 static int __init init_osst(void)
5906 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
5911 if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
5912 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
5913 osst_sysfs_cleanup();
5916 osst_create_driverfs_files(&osst_template.gendrv);
5921 static void __exit exit_osst (void)
5924 struct osst_tape * STp;
5926 osst_remove_driverfs_files(&osst_template.gendrv);
5927 scsi_unregister_driver(&osst_template.gendrv);
5928 unregister_chrdev(OSST_MAJOR, "osst");
5929 osst_sysfs_cleanup();
5931 if (os_scsi_tapes) {
5932 for (i=0; i < osst_max_dev; ++i) {
5933 if (!(STp = os_scsi_tapes[i])) continue;
5934 /* This is defensive, supposed to happen during detach */
5935 vfree(STp->header_cache);
5937 normalize_buffer(STp->buffer);
5940 put_disk(STp->drive);
5943 kfree(os_scsi_tapes);
5945 printk(KERN_INFO "osst :I: Unloaded.\n");
5948 module_init(init_osst);
5949 module_exit(exit_osst);