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 - 2004 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.3";
29 /* The "failure to reconnect" firmware bug */
30 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
31 #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/
32 #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
34 #include <linux/module.h>
37 #include <linux/kernel.h>
38 #include <linux/sched.h>
39 #include <linux/proc_fs.h>
41 #include <linux/init.h>
42 #include <linux/string.h>
43 #include <linux/errno.h>
44 #include <linux/mtio.h>
45 #include <linux/ioctl.h>
46 #include <linux/fcntl.h>
47 #include <linux/spinlock.h>
48 #include <linux/vmalloc.h>
49 #include <linux/blkdev.h>
50 #include <linux/moduleparam.h>
51 #include <linux/delay.h>
52 #include <asm/uaccess.h>
54 #include <asm/system.h>
56 /* The driver prints some debugging information on the console if DEBUG
57 is defined and non-zero. */
60 /* The message level for the debug messages is currently set to KERN_NOTICE
61 so that people can easily see the messages. Later when the debugging messages
62 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
63 #define OSST_DEB_MSG KERN_NOTICE
65 #include <scsi/scsi.h>
66 #include <scsi/scsi_dbg.h>
67 #include <scsi/scsi_device.h>
68 #include <scsi/scsi_driver.h>
69 #include <scsi/scsi_eh.h>
70 #include <scsi/scsi_host.h>
71 #include <scsi/scsi_ioctl.h>
72 #include <scsi/scsi_request.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");
90 module_param(max_dev, int, 0444);
91 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
93 module_param(write_threshold_kbs, int, 0644);
94 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
96 module_param(max_sg_segs, int, 0644);
97 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
99 static struct osst_dev_parm {
102 } parms[] __initdata = {
103 { "max_dev", &max_dev },
104 { "write_threshold_kbs", &write_threshold_kbs },
105 { "max_sg_segs", &max_sg_segs }
109 /* Some default definitions have been moved to osst_options.h */
110 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
111 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
113 /* The buffer size should fit into the 24 bits for length in the
114 6-byte SCSI read and write commands. */
115 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
116 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
120 static int debugging = 1;
121 /* uncomment define below to test error recovery */
122 // #define OSST_INJECT_ERRORS 1
125 /* Do not retry! The drive firmware already retries when appropriate,
126 and when it tries to tell us something, we had better listen... */
127 #define MAX_RETRIES 0
129 #define NO_TAPE NOT_READY
131 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
132 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
133 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
135 #define OSST_TIMEOUT (200 * HZ)
136 #define OSST_LONG_TIMEOUT (1800 * HZ)
138 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
139 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
140 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
141 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
143 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
145 #define SET_DENS_AND_BLK 0x10001
147 static int osst_buffer_size = OSST_BUFFER_SIZE;
148 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
149 static int osst_max_sg_segs = OSST_MAX_SG;
150 static int osst_max_dev = OSST_MAX_TAPES;
151 static int osst_nr_dev;
153 static struct osst_tape **os_scsi_tapes = NULL;
154 static DEFINE_RWLOCK(os_scsi_tapes_lock);
156 static int modes_defined = 0;
158 static struct osst_buffer *new_tape_buffer(int, int, int);
159 static int enlarge_buffer(struct osst_buffer *, int);
160 static void normalize_buffer(struct osst_buffer *);
161 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
162 static int from_buffer(struct osst_buffer *, char __user *, int);
163 static int osst_zero_buffer_tail(struct osst_buffer *);
164 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
165 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
167 static int osst_probe(struct device *);
168 static int osst_remove(struct device *);
170 static struct scsi_driver osst_template = {
171 .owner = THIS_MODULE,
175 .remove = osst_remove,
179 static int osst_int_ioctl(struct osst_tape *STp, struct scsi_request ** aSRpnt,
180 unsigned int cmd_in, unsigned long arg);
182 static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int frame, int skip);
184 static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt);
186 static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt);
188 static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending);
190 static inline char *tape_name(struct osst_tape *tape)
192 return tape->drive->disk_name;
195 /* Routines that handle the interaction with mid-layer SCSI routines */
197 /* Convert the result to success code */
198 static int osst_chk_result(struct osst_tape * STp, struct scsi_request * SRpnt)
200 char *name = tape_name(STp);
201 int result = SRpnt->sr_result;
202 unsigned char * sense = SRpnt->sr_sense_buffer, scode;
208 sense[0] = 0; /* We don't have sense data if this byte is zero */
211 if ((driver_byte(result) & DRIVER_MASK) == DRIVER_SENSE)
212 scode = sense[2] & 0x0f;
214 sense[0] = 0; /* We don't have sense data if this byte is zero */
219 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
221 SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
222 SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
224 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
225 name, scode, sense[12], sense[13]);
226 if (driver_byte(result) & DRIVER_SENSE)
227 scsi_print_req_sense("osst ", SRpnt);
231 if (!(driver_byte(result) & DRIVER_SENSE) ||
232 ((sense[0] & 0x70) == 0x70 &&
234 scode != RECOVERED_ERROR &&
235 /* scode != UNIT_ATTENTION && */
236 scode != BLANK_CHECK &&
237 scode != VOLUME_OVERFLOW &&
238 SRpnt->sr_cmnd[0] != MODE_SENSE &&
239 SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
240 if (driver_byte(result) & DRIVER_SENSE) {
241 printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
242 scsi_print_req_sense("osst:", SRpnt);
245 static int notyetprinted = 1;
248 "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
249 name, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
254 "%s:I: This warning may be caused by your scsi controller,\n", name);
256 "%s:I: it has been reported with some Buslogic cards.\n", name);
260 STp->pos_unknown |= STp->device->was_reset;
262 if ((sense[0] & 0x70) == 0x70 &&
263 scode == RECOVERED_ERROR) {
264 STp->recover_count++;
265 STp->recover_erreg++;
268 if (SRpnt->sr_cmnd[0] == READ_6)
270 else if (SRpnt->sr_cmnd[0] == WRITE_6)
274 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
278 if ((sense[2] & 0xe0) == 0)
285 /* Wakeup from interrupt */
286 static void osst_sleep_done (struct scsi_cmnd * SCpnt)
288 struct osst_tape * STp = container_of(SCpnt->request->rq_disk->private_data, struct osst_tape, driver);
290 if ((STp->buffer)->writing &&
291 (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
292 (SCpnt->sense_buffer[2] & 0x40)) {
293 /* EOM at write-behind, has all been written? */
294 if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
295 STp->buffer->midlevel_result = SCpnt->result; /* Error */
297 STp->buffer->midlevel_result = INT_MAX; /* OK */
300 STp->buffer->midlevel_result = SCpnt->result;
301 SCpnt->request->rq_status = RQ_SCSI_DONE;
302 STp->buffer->last_SRpnt = SCpnt->sc_request;
305 STp->write_pending = 0;
307 complete(SCpnt->request->waiting);
311 /* Do the scsi command. Waits until command performed if do_wait is true.
312 Otherwise osst_write_behind_check() is used to check that the command
314 static struct scsi_request * osst_do_scsi(struct scsi_request *SRpnt, struct osst_tape *STp,
315 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
318 #ifdef OSST_INJECT_ERRORS
319 static int inject = 0;
320 static int repeat = 0;
323 if ((SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC)) == NULL) {
324 printk(KERN_ERR "%s:E: Can't get SCSI request.\n", tape_name(STp));
325 if (signal_pending(current))
326 (STp->buffer)->syscall_result = (-EINTR);
328 (STp->buffer)->syscall_result = (-EBUSY);
333 init_completion(&STp->wait);
334 SRpnt->sr_use_sg = (bytes > (STp->buffer)->sg[0].length) ?
335 (STp->buffer)->use_sg : 0;
336 if (SRpnt->sr_use_sg) {
337 bp = (char *)&(STp->buffer->sg[0]);
338 if (STp->buffer->sg_segs < SRpnt->sr_use_sg)
339 SRpnt->sr_use_sg = STp->buffer->sg_segs;
342 bp = (STp->buffer)->b_data;
343 SRpnt->sr_data_direction = direction;
344 SRpnt->sr_cmd_len = 0;
345 SRpnt->sr_request->waiting = &(STp->wait);
346 SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
347 SRpnt->sr_request->rq_disk = STp->drive;
349 scsi_do_req(SRpnt, (void *)cmd, bp, bytes, osst_sleep_done, timeout, retries);
352 wait_for_completion(SRpnt->sr_request->waiting);
353 SRpnt->sr_request->waiting = NULL;
354 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
355 #ifdef OSST_INJECT_ERRORS
356 if (STp->buffer->syscall_result == 0 &&
359 ( (++ inject % 83) == 29 ||
360 (STp->first_frame_position == 240
361 /* or STp->read_error_frame to fail again on the block calculated above */ &&
363 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
364 STp->buffer->last_result_fatal = 1;
372 /* Handle the write-behind checking (downs the semaphore) */
373 static void osst_write_behind_check(struct osst_tape *STp)
375 struct osst_buffer * STbuffer;
377 STbuffer = STp->buffer;
380 if (STp->write_pending)
385 wait_for_completion(&(STp->wait));
386 (STp->buffer)->last_SRpnt->sr_request->waiting = NULL;
388 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
390 if ((STp->buffer)->syscall_result)
391 (STp->buffer)->syscall_result =
392 osst_write_error_recovery(STp, &((STp->buffer)->last_SRpnt), 1);
394 STp->first_frame_position++;
396 scsi_release_request((STp->buffer)->last_SRpnt);
398 if (STbuffer->writing < STbuffer->buffer_bytes)
399 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
401 STbuffer->buffer_bytes -= STbuffer->writing;
402 STbuffer->writing = 0;
409 /* Onstream specific Routines */
411 * Initialize the OnStream AUX
413 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
414 int logical_blk_num, int blk_sz, int blk_cnt)
416 os_aux_t *aux = STp->buffer->aux;
417 os_partition_t *par = &aux->partition;
418 os_dat_t *dat = &aux->dat;
420 if (STp->raw) return;
422 memset(aux, 0, sizeof(*aux));
423 aux->format_id = htonl(0);
424 memcpy(aux->application_sig, "LIN4", 4);
425 aux->hdwr = htonl(0);
426 aux->frame_type = frame_type;
428 switch (frame_type) {
429 case OS_FRAME_TYPE_HEADER:
430 aux->update_frame_cntr = htonl(STp->update_frame_cntr);
431 par->partition_num = OS_CONFIG_PARTITION;
432 par->par_desc_ver = OS_PARTITION_VERSION;
433 par->wrt_pass_cntr = htons(0xffff);
434 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
435 par->first_frame_ppos = htonl(0);
436 par->last_frame_ppos = htonl(0xbb7);
437 aux->frame_seq_num = htonl(0);
438 aux->logical_blk_num_high = htonl(0);
439 aux->logical_blk_num = htonl(0);
440 aux->next_mark_ppos = htonl(STp->first_mark_ppos);
442 case OS_FRAME_TYPE_DATA:
443 case OS_FRAME_TYPE_MARKER:
448 dat->dat_list[0].blk_sz = htonl(blk_sz);
449 dat->dat_list[0].blk_cnt = htons(blk_cnt);
450 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
451 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
452 dat->dat_list[0].reserved = 0;
453 case OS_FRAME_TYPE_EOD:
454 aux->update_frame_cntr = htonl(0);
455 par->partition_num = OS_DATA_PARTITION;
456 par->par_desc_ver = OS_PARTITION_VERSION;
457 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
458 par->first_frame_ppos = htonl(STp->first_data_ppos);
459 par->last_frame_ppos = htonl(STp->capacity);
460 aux->frame_seq_num = htonl(frame_seq_number);
461 aux->logical_blk_num_high = htonl(0);
462 aux->logical_blk_num = htonl(logical_blk_num);
464 default: ; /* probably FILL */
466 aux->filemark_cnt = ntohl(STp->filemark_cnt);
467 aux->phys_fm = ntohl(0xffffffff);
468 aux->last_mark_ppos = ntohl(STp->last_mark_ppos);
469 aux->last_mark_lbn = ntohl(STp->last_mark_lbn);
473 * Verify that we have the correct tape frame
475 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
477 char * name = tape_name(STp);
478 os_aux_t * aux = STp->buffer->aux;
479 os_partition_t * par = &(aux->partition);
480 struct st_partstat * STps = &(STp->ps[STp->partition]);
481 int blk_cnt, blk_sz, i;
484 if (STp->buffer->syscall_result) {
485 for (i=0; i < STp->buffer->sg_segs; i++)
486 memset(page_address(STp->buffer->sg[i].page),
487 0, STp->buffer->sg[i].length);
488 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
490 STp->buffer->buffer_bytes = OS_FRAME_SIZE;
493 if (STp->buffer->syscall_result) {
495 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
499 if (ntohl(aux->format_id) != 0) {
501 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
505 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
506 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
508 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
512 if (par->partition_num != OS_DATA_PARTITION) {
513 if (!STp->linux_media || STp->linux_media_version != 2) {
515 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
516 name, par->partition_num);
521 if (par->par_desc_ver != OS_PARTITION_VERSION) {
523 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
527 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
529 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
530 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
534 if (aux->frame_type != OS_FRAME_TYPE_DATA &&
535 aux->frame_type != OS_FRAME_TYPE_EOD &&
536 aux->frame_type != OS_FRAME_TYPE_MARKER) {
539 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
543 if (aux->frame_type == OS_FRAME_TYPE_EOD &&
544 STp->first_frame_position < STp->eod_frame_ppos) {
545 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
546 STp->first_frame_position);
549 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
552 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
553 name, ntohl(aux->frame_seq_num), frame_seq_number);
557 if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
558 STps->eof = ST_FM_HIT;
560 i = ntohl(aux->filemark_cnt);
561 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
562 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
564 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
565 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
566 i, STp->first_frame_position - 1);
568 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
569 if (i >= STp->filemark_cnt)
570 STp->filemark_cnt = i+1;
573 if (aux->frame_type == OS_FRAME_TYPE_EOD) {
574 STps->eof = ST_EOD_1;
575 STp->frame_in_buffer = 1;
577 if (aux->frame_type == OS_FRAME_TYPE_DATA) {
578 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
579 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
580 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
581 STp->buffer->read_pointer = 0;
582 STp->frame_in_buffer = 1;
584 /* See what block size was used to write file */
585 if (STp->block_size != blk_sz && blk_sz > 0) {
587 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
588 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
589 STp->block_size<1024?STp->block_size:STp->block_size/1024,
590 STp->block_size<1024?'b':'k');
591 STp->block_size = blk_sz;
592 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
594 STps->eof = ST_NOEOF;
596 STp->frame_seq_number = ntohl(aux->frame_seq_num);
597 STp->logical_blk_num = ntohl(aux->logical_blk_num);
601 if (STp->read_error_frame == 0)
602 STp->read_error_frame = STp->first_frame_position - 1;
607 * Wait for the unit to become Ready
609 static int osst_wait_ready(struct osst_tape * STp, struct scsi_request ** aSRpnt,
610 unsigned timeout, int initial_delay)
612 unsigned char cmd[MAX_COMMAND_SIZE];
613 struct scsi_request * SRpnt;
614 unsigned long startwait = jiffies;
617 char * name = tape_name(STp);
619 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
622 if (initial_delay > 0)
623 msleep(jiffies_to_msecs(initial_delay));
625 memset(cmd, 0, MAX_COMMAND_SIZE);
626 cmd[0] = TEST_UNIT_READY;
628 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
630 if (!SRpnt) return (-EBUSY);
632 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
633 (( SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
634 (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8) ) ||
635 ( SRpnt->sr_sense_buffer[2] == 6 && SRpnt->sr_sense_buffer[12] == 0x28 &&
636 SRpnt->sr_sense_buffer[13] == 0 ) )) {
639 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
640 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
646 memset(cmd, 0, MAX_COMMAND_SIZE);
647 cmd[0] = TEST_UNIT_READY;
649 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
655 if ( STp->buffer->syscall_result &&
656 osst_write_error_recovery(STp, aSRpnt, 0) ) {
658 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
659 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
660 STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
661 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
666 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
672 * Wait for a tape to be inserted in the unit
674 static int osst_wait_for_medium(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned timeout)
676 unsigned char cmd[MAX_COMMAND_SIZE];
677 struct scsi_request * SRpnt;
678 unsigned long startwait = jiffies;
681 char * name = tape_name(STp);
683 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
686 memset(cmd, 0, MAX_COMMAND_SIZE);
687 cmd[0] = TEST_UNIT_READY;
689 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
691 if (!SRpnt) return (-EBUSY);
693 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
694 SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 0x3a &&
695 SRpnt->sr_sense_buffer[13] == 0 ) {
698 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
699 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
705 memset(cmd, 0, MAX_COMMAND_SIZE);
706 cmd[0] = TEST_UNIT_READY;
708 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
714 if ( STp->buffer->syscall_result && SRpnt->sr_sense_buffer[2] != 2 &&
715 SRpnt->sr_sense_buffer[12] != 4 && SRpnt->sr_sense_buffer[13] == 1) {
717 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
718 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
719 STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
720 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
725 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
730 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct scsi_request ** aSRpnt, int frame)
734 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
735 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
736 if (retval) return (retval);
737 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
738 return (osst_get_frame_position(STp, aSRpnt));
742 * Wait for write(s) to complete
744 static int osst_flush_drive_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt)
746 unsigned char cmd[MAX_COMMAND_SIZE];
747 struct scsi_request * SRpnt;
749 int delay = OSST_WAIT_WRITE_COMPLETE;
751 char * name = tape_name(STp);
753 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
756 memset(cmd, 0, MAX_COMMAND_SIZE);
757 cmd[0] = WRITE_FILEMARKS;
760 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
762 if (!SRpnt) return (-EBUSY);
763 if (STp->buffer->syscall_result) {
764 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == 2 && SRpnt->sr_sense_buffer[12] == 4) {
765 if (SRpnt->sr_sense_buffer[13] == 8) {
766 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
769 result = osst_write_error_recovery(STp, aSRpnt, 0);
771 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
772 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
777 #define OSST_POLL_PER_SEC 10
778 static int osst_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int curr, int minlast, int to)
780 unsigned long startwait = jiffies;
781 char * name = tape_name(STp);
783 char notyetprinted = 1;
785 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
786 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
788 while (time_before (jiffies, startwait + to*HZ))
791 result = osst_get_frame_position(STp, aSRpnt);
793 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
794 return 0; /* successful recovery leaves drive ready for frame */
795 if (result < 0) break;
796 if (STp->first_frame_position == curr &&
798 (signed)STp->last_frame_position > (signed)curr + minlast) ||
799 (minlast >= 0 && STp->cur_frames > minlast)
803 if (debugging || jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC)
805 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
806 name, curr, curr+minlast, STp->first_frame_position,
807 STp->last_frame_position, STp->cur_frames,
808 result, (jiffies-startwait)/HZ,
809 (((jiffies-startwait)%HZ)*10)/HZ);
814 if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted)
816 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
817 name, curr, curr+minlast, STp->first_frame_position,
818 STp->last_frame_position, STp->cur_frames, result);
822 msleep(1000 / OSST_POLL_PER_SEC);
825 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
826 name, curr, curr+minlast, STp->first_frame_position,
827 STp->last_frame_position, STp->cur_frames,
828 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
833 static int osst_recover_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int writing)
835 struct scsi_request * SRpnt;
836 unsigned char cmd[MAX_COMMAND_SIZE];
837 unsigned long startwait = jiffies;
839 char * name = tape_name(STp);
843 char * olddata = STp->buffer->b_data;
844 int oldsize = STp->buffer->buffer_size;
846 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
848 memset(cmd, 0, MAX_COMMAND_SIZE);
849 cmd[0] = WRITE_FILEMARKS;
851 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
854 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
856 if (STp->buffer->syscall_result && (SRpnt->sr_sense_buffer[2] & 0x0f) != 2) {
858 /* some failure - not just not-ready */
859 retval = osst_write_error_recovery(STp, aSRpnt, 0);
862 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
864 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
865 memset(cmd, 0, MAX_COMMAND_SIZE);
866 cmd[0] = READ_POSITION;
868 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
871 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
872 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
875 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
877 /* TODO - figure out which error conditions can be handled */
878 if (STp->buffer->syscall_result)
880 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
881 (*aSRpnt)->sr_sense_buffer[ 2] & 0x0f,
882 (*aSRpnt)->sr_sense_buffer[12],
883 (*aSRpnt)->sr_sense_buffer[13]);
889 * Read the next OnStream tape frame at the current location
891 static int osst_read_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int timeout)
893 unsigned char cmd[MAX_COMMAND_SIZE];
894 struct scsi_request * SRpnt;
897 os_aux_t * aux = STp->buffer->aux;
898 char * name = tape_name(STp);
902 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
903 retval = osst_recover_wait_frame(STp, aSRpnt, 0);
905 memset(cmd, 0, MAX_COMMAND_SIZE);
912 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
914 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
915 STp->timeout, MAX_RETRIES, 1);
920 if ((STp->buffer)->syscall_result) {
922 if (STp->read_error_frame == 0) {
923 STp->read_error_frame = STp->first_frame_position;
925 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
930 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
932 SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],
933 SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],
934 SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5],
935 SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7]);
939 STp->first_frame_position++;
944 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
947 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
948 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
949 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
950 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
951 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
952 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
953 if (aux->frame_type==2)
954 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
955 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
956 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
962 static int osst_initiate_read(struct osst_tape * STp, struct scsi_request ** aSRpnt)
964 struct st_partstat * STps = &(STp->ps[STp->partition]);
965 struct scsi_request * SRpnt ;
966 unsigned char cmd[MAX_COMMAND_SIZE];
968 char * name = tape_name(STp);
970 if (STps->rw != ST_READING) { /* Initialize read operation */
971 if (STps->rw == ST_WRITING || STp->dirty) {
972 STp->write_type = OS_WRITE_DATA;
973 osst_flush_write_buffer(STp, aSRpnt);
974 osst_flush_drive_buffer(STp, aSRpnt);
976 STps->rw = ST_READING;
977 STp->frame_in_buffer = 0;
980 * Issue a read 0 command to get the OnStream drive
981 * read frames into its buffer.
983 memset(cmd, 0, MAX_COMMAND_SIZE);
988 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
990 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
992 if ((retval = STp->buffer->syscall_result))
993 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
999 static int osst_get_logical_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1000 int frame_seq_number, int quiet)
1002 struct st_partstat * STps = &(STp->ps[STp->partition]);
1003 char * name = tape_name(STp);
1011 * If we want just any frame (-1) and there is a frame in the buffer, return it
1013 if (frame_seq_number == -1 && STp->frame_in_buffer) {
1015 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1020 * Search and wait for the next logical tape frame
1024 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1025 name, frame_seq_number);
1026 if (STp->read_error_frame) {
1027 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1029 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1030 name, STp->read_error_frame);
1032 STp->read_error_frame = 0;
1039 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1040 name, frame_seq_number, cnt);
1042 if ( osst_initiate_read(STp, aSRpnt)
1043 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1046 position = osst_get_frame_position(STp, aSRpnt);
1047 if (position >= 0xbae && position < 0xbb8)
1049 else if (position > STp->eod_frame_ppos || ++bad == 10) {
1050 position = STp->read_error_frame - 1;
1058 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1061 osst_set_frame_position(STp, aSRpnt, position, 0);
1064 if (osst_verify_frame(STp, frame_seq_number, quiet))
1066 if (osst_verify_frame(STp, -1, quiet)) {
1067 x = ntohl(STp->buffer->aux->frame_seq_num);
1068 if (STp->fast_open) {
1070 "%s:W: Found logical frame %d instead of %d after fast open\n",
1071 name, x, frame_seq_number);
1073 STp->read_error_frame = 0;
1076 if (x > frame_seq_number) {
1078 /* positioning backwards did not bring us to the desired frame */
1079 position = STp->read_error_frame - 1;
1082 position = osst_get_frame_position(STp, aSRpnt)
1083 + frame_seq_number - x - 1;
1085 if (STp->first_frame_position >= 3000 && position < 3000)
1090 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1091 name, x, frame_seq_number,
1092 STp->first_frame_position - position);
1094 osst_set_frame_position(STp, aSRpnt, position, 0);
1100 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1102 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1104 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1107 STp->frame_in_buffer = 0;
1110 STp->recover_count++;
1111 STp->recover_erreg++;
1112 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1113 name, STp->read_error_frame);
1118 if (debugging || STps->eof)
1120 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1121 name, frame_seq_number, STp->frame_seq_number, STps->eof);
1124 STp->read_error_frame = 0;
1128 static int osst_seek_logical_blk(struct osst_tape * STp, struct scsi_request ** aSRpnt, int logical_blk_num)
1130 struct st_partstat * STps = &(STp->ps[STp->partition]);
1131 char * name = tape_name(STp);
1133 int frame_seq_estimate, ppos_estimate, move;
1135 if (logical_blk_num < 0) logical_blk_num = 0;
1137 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1138 name, logical_blk_num, STp->logical_blk_num,
1139 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1140 STp->block_size<1024?'b':'k');
1142 /* Do we know where we are? */
1143 if (STps->drv_block >= 0) {
1144 move = logical_blk_num - STp->logical_blk_num;
1145 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1146 move /= (OS_DATA_SIZE / STp->block_size);
1147 frame_seq_estimate = STp->frame_seq_number + move;
1149 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1151 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1152 else ppos_estimate = frame_seq_estimate + 20;
1153 while (++retries < 10) {
1154 if (ppos_estimate > STp->eod_frame_ppos-2) {
1155 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1156 ppos_estimate = STp->eod_frame_ppos - 2;
1158 if (frame_seq_estimate < 0) {
1159 frame_seq_estimate = 0;
1162 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1163 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1164 /* we've located the estimated frame, now does it have our block? */
1165 if (logical_blk_num < STp->logical_blk_num ||
1166 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1167 if (STps->eof == ST_FM_HIT)
1168 move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1170 move = logical_blk_num - STp->logical_blk_num;
1171 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1172 move /= (OS_DATA_SIZE / STp->block_size);
1174 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1177 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1178 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1179 STp->logical_blk_num, logical_blk_num, move);
1181 frame_seq_estimate += move;
1182 ppos_estimate += move;
1185 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1186 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1187 STp->logical_blk_num = logical_blk_num;
1190 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1191 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1192 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1195 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1196 if (STps->eof == ST_FM_HIT) {
1198 STps->drv_block = 0;
1200 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1201 STp->logical_blk_num -
1202 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1205 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1209 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1211 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1213 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1214 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1215 STp->logical_blk_num, logical_blk_num);
1217 if (frame_seq_estimate != STp->frame_seq_number)
1218 ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1223 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1224 name, logical_blk_num, STp->logical_blk_num, retries);
1228 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1229 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1230 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1231 * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1233 #define OSST_FRAME_SHIFT 6
1234 #define OSST_SECTOR_SHIFT 9
1235 #define OSST_SECTOR_MASK 0x03F
1237 static int osst_get_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt)
1241 char * name = tape_name(STp);
1244 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1245 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1246 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1247 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1248 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1249 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1251 /* do we know where we are inside a file? */
1252 if (STp->ps[STp->partition].drv_block >= 0) {
1253 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1254 STp->first_frame_position) << OSST_FRAME_SHIFT;
1255 if (STp->ps[STp->partition].rw == ST_WRITING)
1256 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1258 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1260 sector = osst_get_frame_position(STp, aSRpnt);
1262 sector <<= OSST_FRAME_SHIFT;
1267 static int osst_seek_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt, int sector)
1269 struct st_partstat * STps = &(STp->ps[STp->partition]);
1270 int frame = sector >> OSST_FRAME_SHIFT,
1271 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1274 char * name = tape_name(STp);
1276 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1277 name, sector, frame, offset);
1279 if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1281 if (frame <= STp->first_data_ppos) {
1282 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1283 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1285 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1286 if (r < 0) return r;
1288 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1289 if (r < 0) return r;
1291 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1294 STp->logical_blk_num += offset / STp->block_size;
1295 STp->buffer->read_pointer = offset;
1296 STp->buffer->buffer_bytes -= offset;
1298 STp->frame_seq_number++;
1299 STp->frame_in_buffer = 0;
1300 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1301 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1303 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1304 if (STps->eof == ST_FM_HIT) {
1306 STps->drv_block = 0;
1308 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1309 STp->logical_blk_num -
1310 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1313 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1316 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1317 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1318 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1324 * Read back the drive's internal buffer contents, as a part
1325 * of the write error recovery mechanism for old OnStream
1326 * firmware revisions.
1327 * Precondition for this function to work: all frames in the
1328 * drive's buffer must be of one type (DATA, MARK or EOD)!
1330 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1331 unsigned int frame, unsigned int skip, int pending)
1333 struct scsi_request * SRpnt = * aSRpnt;
1334 unsigned char * buffer, * p;
1335 unsigned char cmd[MAX_COMMAND_SIZE];
1336 int flag, new_frame, i;
1337 int nframes = STp->cur_frames;
1338 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1339 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1340 - (nframes + pending - 1);
1341 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1342 - (nframes + pending - 1) * blks_per_frame;
1343 char * name = tape_name(STp);
1344 unsigned long startwait = jiffies;
1346 int dbg = debugging;
1349 if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
1352 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1353 name, nframes, pending?" and one that was pending":"");
1355 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1357 if (pending && debugging)
1358 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1359 name, frame_seq_number + nframes,
1360 logical_blk_num + nframes * blks_per_frame,
1361 p[0], p[1], p[2], p[3]);
1363 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1365 memset(cmd, 0, MAX_COMMAND_SIZE);
1366 cmd[0] = 0x3C; /* Buffer Read */
1367 cmd[1] = 6; /* Retrieve Faulty Block */
1368 cmd[7] = 32768 >> 8;
1369 cmd[8] = 32768 & 0xff;
1371 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1372 STp->timeout, MAX_RETRIES, 1);
1374 if ((STp->buffer)->syscall_result || !SRpnt) {
1375 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1380 osst_copy_from_buffer(STp->buffer, p);
1383 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1384 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1388 osst_get_frame_position(STp, aSRpnt);
1391 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1393 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1394 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1396 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1399 if (STp->write_type == OS_WRITE_HEADER) {
1401 p += skip * OS_DATA_SIZE;
1403 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1408 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1409 name, new_frame+i, frame_seq_number+i);
1411 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1412 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1413 osst_get_frame_position(STp, aSRpnt);
1416 if (new_frame > frame + 1000) {
1417 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1421 if ( i >= nframes + pending ) break;
1424 osst_copy_to_buffer(STp->buffer, p);
1426 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1428 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1429 logical_blk_num + i*blks_per_frame,
1430 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1431 memset(cmd, 0, MAX_COMMAND_SIZE);
1439 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1440 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1441 p[0], p[1], p[2], p[3]);
1443 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1444 STp->timeout, MAX_RETRIES, 1);
1446 if (STp->buffer->syscall_result)
1449 p += OS_DATA_SIZE; i++;
1451 /* if we just sent the last frame, wait till all successfully written */
1452 if ( i == nframes + pending ) {
1454 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1456 memset(cmd, 0, MAX_COMMAND_SIZE);
1457 cmd[0] = WRITE_FILEMARKS;
1459 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1460 STp->timeout, MAX_RETRIES, 1);
1463 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1464 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1468 flag = STp->buffer->syscall_result;
1469 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1471 memset(cmd, 0, MAX_COMMAND_SIZE);
1472 cmd[0] = TEST_UNIT_READY;
1474 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1477 if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
1478 (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) {
1479 /* in the process of becoming ready */
1483 if (STp->buffer->syscall_result)
1489 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1495 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
1496 SRpnt->sr_sense_buffer[12] == 0 &&
1497 SRpnt->sr_sense_buffer[13] == 2) {
1498 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1500 return (-EIO); /* hit end of tape = fail */
1502 i = ((SRpnt->sr_sense_buffer[3] << 24) |
1503 (SRpnt->sr_sense_buffer[4] << 16) |
1504 (SRpnt->sr_sense_buffer[5] << 8) |
1505 SRpnt->sr_sense_buffer[6] ) - new_frame;
1506 p = &buffer[i * OS_DATA_SIZE];
1508 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1510 osst_get_frame_position(STp, aSRpnt);
1512 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1513 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1518 /* error recovery did not successfully complete */
1519 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1520 STp->write_type == OS_WRITE_HEADER?"header":"body");
1523 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1528 static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1529 unsigned int frame, unsigned int skip, int pending)
1531 unsigned char cmd[MAX_COMMAND_SIZE];
1532 struct scsi_request * SRpnt;
1533 char * name = tape_name(STp);
1535 int attempts = 1000 / skip;
1537 unsigned long startwait = jiffies;
1539 int dbg = debugging;
1542 while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1547 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1549 expected = frame+skip+STp->cur_frames+pending;
1551 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1552 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1554 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1557 schedule_timeout_interruptible(msecs_to_jiffies(100));
1559 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1561 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1562 name, STp->first_frame_position,
1563 STp->last_frame_position, STp->cur_frames);
1565 frame = STp->last_frame_position;
1569 if (pending && STp->cur_frames < 50) {
1571 memset(cmd, 0, MAX_COMMAND_SIZE);
1576 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1577 name, STp->frame_seq_number-1, STp->first_frame_position);
1579 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1580 STp->timeout, MAX_RETRIES, 1);
1583 if (STp->buffer->syscall_result) { /* additional write error */
1584 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
1585 SRpnt->sr_sense_buffer[12] == 0 &&
1586 SRpnt->sr_sense_buffer[13] == 2) {
1588 "%s:E: Volume overflow in write error recovery\n",
1590 break; /* hit end of tape = fail */
1599 if (STp->cur_frames == 0) {
1602 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1604 if (STp->first_frame_position != expected) {
1605 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1606 name, STp->first_frame_position, expected);
1613 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1614 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1618 schedule_timeout_interruptible(msecs_to_jiffies(100));
1620 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1628 * Error recovery algorithm for the OnStream tape.
1631 static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending)
1633 struct scsi_request * SRpnt = * aSRpnt;
1634 struct st_partstat * STps = & STp->ps[STp->partition];
1635 char * name = tape_name(STp);
1638 unsigned int frame, skip;
1640 rw_state = STps->rw;
1642 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) != 3
1643 || SRpnt->sr_sense_buffer[12] != 12
1644 || SRpnt->sr_sense_buffer[13] != 0) {
1646 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1647 SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
1651 frame = (SRpnt->sr_sense_buffer[3] << 24) |
1652 (SRpnt->sr_sense_buffer[4] << 16) |
1653 (SRpnt->sr_sense_buffer[5] << 8) |
1654 SRpnt->sr_sense_buffer[6];
1655 skip = SRpnt->sr_sense_buffer[9];
1658 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1660 osst_get_frame_position(STp, aSRpnt);
1662 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1663 name, STp->first_frame_position, STp->last_frame_position);
1665 switch (STp->write_type) {
1668 case OS_WRITE_NEW_MARK:
1670 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1671 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1672 if (STp->os_fw_rev >= 10600)
1673 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1675 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1676 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1678 retval?"" :"Don't worry, ",
1679 retval?" not ":" ");
1681 case OS_WRITE_LAST_MARK:
1682 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1683 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1686 case OS_WRITE_HEADER:
1687 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1688 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1691 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1692 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1694 osst_get_frame_position(STp, aSRpnt);
1696 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1697 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1698 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1701 STp->recover_count++;
1702 STp->recover_erreg++;
1706 STps->rw = rw_state;
1710 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1711 int mt_op, int mt_count)
1713 char * name = tape_name(STp);
1715 int last_mark_ppos = -1;
1718 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1720 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1722 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1726 if (STp->linux_media_version >= 4) {
1728 * direct lookup in header filemark list
1730 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1731 if (STp->header_ok &&
1732 STp->header_cache != NULL &&
1733 (cnt - mt_count) >= 0 &&
1734 (cnt - mt_count) < OS_FM_TAB_MAX &&
1735 (cnt - mt_count) < STp->filemark_cnt &&
1736 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1738 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1740 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1741 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1742 STp->header_cache == NULL?"lack of header cache":"count out of range");
1744 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1746 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1747 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1748 STp->buffer->aux->last_mark_ppos))?"match":"error",
1749 mt_count, last_mark_ppos);
1751 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1752 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1753 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1756 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1760 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1761 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1762 name, last_mark_ppos);
1768 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1772 while (cnt != mt_count) {
1773 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1774 if (last_mark_ppos == -1)
1777 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1779 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1781 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1783 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1787 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1788 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1789 name, last_mark_ppos);
1794 if (mt_op == MTBSFM) {
1795 STp->frame_seq_number++;
1796 STp->frame_in_buffer = 0;
1797 STp->buffer->buffer_bytes = 0;
1798 STp->buffer->read_pointer = 0;
1799 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1805 * ADRL 1.1 compatible "slow" space filemarks fwd version
1807 * Just scans for the filemark sequentially.
1809 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1810 int mt_op, int mt_count)
1814 char * name = tape_name(STp);
1816 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1818 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1820 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1825 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1827 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1831 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1833 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1835 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1837 if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1839 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1840 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1842 STp->eod_frame_ppos = STp->first_frame_position-1;
1846 if (cnt == mt_count)
1848 STp->frame_in_buffer = 0;
1850 if (mt_op == MTFSF) {
1851 STp->frame_seq_number++;
1852 STp->frame_in_buffer = 0;
1853 STp->buffer->buffer_bytes = 0;
1854 STp->buffer->read_pointer = 0;
1855 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1861 * Fast linux specific version of OnStream FSF
1863 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1864 int mt_op, int mt_count)
1866 char * name = tape_name(STp);
1868 next_mark_ppos = -1;
1871 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
1873 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1875 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1880 if (STp->linux_media_version >= 4) {
1882 * direct lookup in header filemark list
1884 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
1885 if (STp->header_ok &&
1886 STp->header_cache != NULL &&
1887 (cnt + mt_count) < OS_FM_TAB_MAX &&
1888 (cnt + mt_count) < STp->filemark_cnt &&
1889 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1890 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
1892 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
1894 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
1895 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1896 STp->header_cache == NULL?"lack of header cache":"count out of range");
1898 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1900 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1901 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
1902 STp->buffer->aux->last_mark_ppos))?"match":"error",
1903 mt_count, next_mark_ppos);
1905 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
1907 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1909 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1911 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
1912 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1914 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
1919 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1920 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1921 name, next_mark_ppos);
1924 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
1925 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
1926 name, cnt+mt_count, next_mark_ppos,
1927 ntohl(STp->buffer->aux->filemark_cnt));
1933 * Find nearest (usually previous) marker, then jump from marker to marker
1936 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1938 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1940 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1944 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
1945 if (STp->first_mark_ppos == -1) {
1947 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1949 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1951 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
1952 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1955 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
1960 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1961 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
1962 name, STp->first_mark_ppos);
1966 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
1972 while (cnt != mt_count) {
1973 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
1974 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
1976 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1978 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
1981 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
1983 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
1985 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1987 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
1992 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1993 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1994 name, next_mark_ppos);
1999 if (mt_op == MTFSF) {
2000 STp->frame_seq_number++;
2001 STp->frame_in_buffer = 0;
2002 STp->buffer->buffer_bytes = 0;
2003 STp->buffer->read_pointer = 0;
2004 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2010 * In debug mode, we want to see as many errors as possible
2011 * to test the error recovery mechanism.
2014 static void osst_set_retries(struct osst_tape * STp, struct scsi_request ** aSRpnt, int retries)
2016 unsigned char cmd[MAX_COMMAND_SIZE];
2017 struct scsi_request * SRpnt = * aSRpnt;
2018 char * name = tape_name(STp);
2020 memset(cmd, 0, MAX_COMMAND_SIZE);
2021 cmd[0] = MODE_SELECT;
2023 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2025 (STp->buffer)->b_data[0] = cmd[4] - 1;
2026 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
2027 (STp->buffer)->b_data[2] = 0; /* Reserved */
2028 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
2029 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2030 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2031 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2032 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2035 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2037 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2040 if ((STp->buffer)->syscall_result)
2041 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2046 static int osst_write_filemark(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2049 int this_mark_ppos = STp->first_frame_position;
2050 int this_mark_lbn = STp->logical_blk_num;
2052 char * name = tape_name(STp);
2055 if (STp->raw) return 0;
2057 STp->write_type = OS_WRITE_NEW_MARK;
2059 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2060 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2063 result = osst_flush_write_buffer(STp, aSRpnt);
2064 result |= osst_flush_drive_buffer(STp, aSRpnt);
2065 STp->last_mark_ppos = this_mark_ppos;
2066 STp->last_mark_lbn = this_mark_lbn;
2067 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2068 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2069 if (STp->filemark_cnt++ == 0)
2070 STp->first_mark_ppos = this_mark_ppos;
2074 static int osst_write_eod(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2078 char * name = tape_name(STp);
2081 if (STp->raw) return 0;
2083 STp->write_type = OS_WRITE_EOD;
2084 STp->eod_frame_ppos = STp->first_frame_position;
2086 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2087 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2091 result = osst_flush_write_buffer(STp, aSRpnt);
2092 result |= osst_flush_drive_buffer(STp, aSRpnt);
2093 STp->eod_frame_lfa = --(STp->frame_seq_number);
2097 static int osst_write_filler(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count)
2099 char * name = tape_name(STp);
2102 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2104 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2105 osst_set_frame_position(STp, aSRpnt, where, 0);
2106 STp->write_type = OS_WRITE_FILLER;
2108 memcpy(STp->buffer->b_data, "Filler", 6);
2109 STp->buffer->buffer_bytes = 6;
2111 if (osst_flush_write_buffer(STp, aSRpnt)) {
2112 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2117 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2119 return osst_flush_drive_buffer(STp, aSRpnt);
2122 static int __osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count)
2124 char * name = tape_name(STp);
2128 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2130 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2131 osst_set_frame_position(STp, aSRpnt, where, 0);
2132 STp->write_type = OS_WRITE_HEADER;
2134 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2135 STp->buffer->buffer_bytes = sizeof(os_header_t);
2137 if (osst_flush_write_buffer(STp, aSRpnt)) {
2138 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2142 result = osst_flush_drive_buffer(STp, aSRpnt);
2144 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2149 static int osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int locate_eod)
2151 os_header_t * header;
2153 char * name = tape_name(STp);
2156 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2158 if (STp->raw) return 0;
2160 if (STp->header_cache == NULL) {
2161 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2162 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2165 memset(STp->header_cache, 0, sizeof(os_header_t));
2167 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2170 if (STp->header_ok) STp->update_frame_cntr++;
2171 else STp->update_frame_cntr = 0;
2173 header = STp->header_cache;
2174 strcpy(header->ident_str, "ADR_SEQ");
2175 header->major_rev = 1;
2176 header->minor_rev = 4;
2177 header->ext_trk_tb_off = htons(17192);
2178 header->pt_par_num = 1;
2179 header->partition[0].partition_num = OS_DATA_PARTITION;
2180 header->partition[0].par_desc_ver = OS_PARTITION_VERSION;
2181 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2182 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2183 header->partition[0].last_frame_ppos = htonl(STp->capacity);
2184 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2185 header->cfg_col_width = htonl(20);
2186 header->dat_col_width = htonl(1500);
2187 header->qfa_col_width = htonl(0);
2188 header->ext_track_tb.nr_stream_part = 1;
2189 header->ext_track_tb.et_ent_sz = 32;
2190 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2191 header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2192 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2193 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2194 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa);
2195 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
2196 header->dat_fm_tab.fm_part_num = 0;
2197 header->dat_fm_tab.fm_tab_ent_sz = 4;
2198 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2199 STp->filemark_cnt:OS_FM_TAB_MAX);
2201 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2202 if (STp->update_frame_cntr == 0)
2203 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2204 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2208 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2210 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2213 printk(KERN_ERR "%s:E: Write header failed\n", name);
2215 memcpy(STp->application_sig, "LIN4", 4);
2216 STp->linux_media = 1;
2217 STp->linux_media_version = 4;
2223 static int osst_reset_header(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2225 if (STp->header_cache != NULL)
2226 memset(STp->header_cache, 0, sizeof(os_header_t));
2228 STp->logical_blk_num = STp->frame_seq_number = 0;
2229 STp->frame_in_buffer = 0;
2230 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2231 STp->filemark_cnt = 0;
2232 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2233 return osst_write_header(STp, aSRpnt, 1);
2236 static int __osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt, int ppos)
2238 char * name = tape_name(STp);
2239 os_header_t * header;
2242 int linux_media_version,
2248 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2249 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2250 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2251 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2252 if (osst_initiate_read (STp, aSRpnt)) {
2253 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2257 if (osst_read_frame(STp, aSRpnt, 180)) {
2259 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2263 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2264 aux = STp->buffer->aux;
2265 if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2267 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2271 if (ntohl(aux->frame_seq_num) != 0 ||
2272 ntohl(aux->logical_blk_num) != 0 ||
2273 aux->partition.partition_num != OS_CONFIG_PARTITION ||
2274 ntohl(aux->partition.first_frame_ppos) != 0 ||
2275 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2277 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2278 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2279 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2280 ntohl(aux->partition.last_frame_ppos));
2284 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2285 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2286 strlcpy(id_string, header->ident_str, 8);
2288 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2292 update_frame_cntr = ntohl(aux->update_frame_cntr);
2293 if (update_frame_cntr < STp->update_frame_cntr) {
2295 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2296 name, ppos, update_frame_cntr, STp->update_frame_cntr);
2300 if (header->major_rev != 1 || header->minor_rev != 4 ) {
2302 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2303 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2304 header->minor_rev > 4 )? "Invalid" : "Warning:",
2305 header->major_rev, header->minor_rev);
2307 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2311 if (header->pt_par_num != 1)
2312 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2313 name, header->pt_par_num);
2315 memcpy(id_string, aux->application_sig, 4);
2317 if (memcmp(id_string, "LIN", 3) == 0) {
2318 STp->linux_media = 1;
2319 linux_media_version = id_string[3] - '0';
2320 if (linux_media_version != 4)
2321 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2322 name, linux_media_version);
2324 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2327 if (linux_media_version < STp->linux_media_version) {
2329 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2330 name, ppos, linux_media_version);
2334 if (linux_media_version > STp->linux_media_version) {
2336 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2337 name, ppos, linux_media_version);
2339 memcpy(STp->application_sig, id_string, 5);
2340 STp->linux_media_version = linux_media_version;
2341 STp->update_frame_cntr = -1;
2343 if (update_frame_cntr > STp->update_frame_cntr) {
2345 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2346 name, ppos, update_frame_cntr);
2348 if (STp->header_cache == NULL) {
2349 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2350 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2354 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2357 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2358 header = STp->header_cache; /* further accesses from cached (full) copy */
2360 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2361 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2362 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2363 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2364 STp->filemark_cnt = ntohl(aux->filemark_cnt);
2365 STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2366 STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2367 STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2368 STp->update_frame_cntr = update_frame_cntr;
2370 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2371 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2372 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2373 STp->first_data_ppos,
2374 ntohl(header->partition[0].last_frame_ppos),
2375 ntohl(header->partition[0].eod_frame_ppos));
2376 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2377 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2379 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2381 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2383 memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2384 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2385 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2387 if (header->minor_rev == 4 &&
2388 (header->ext_trk_tb_off != htons(17192) ||
2389 header->partition[0].partition_num != OS_DATA_PARTITION ||
2390 header->partition[0].par_desc_ver != OS_PARTITION_VERSION ||
2391 header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2392 header->cfg_col_width != htonl(20) ||
2393 header->dat_col_width != htonl(1500) ||
2394 header->qfa_col_width != htonl(0) ||
2395 header->ext_track_tb.nr_stream_part != 1 ||
2396 header->ext_track_tb.et_ent_sz != 32 ||
2397 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION ||
2398 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2399 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2400 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2401 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) ||
2402 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION ||
2403 header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2404 header->dat_fm_tab.fm_tab_ent_cnt !=
2405 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2406 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2413 static int osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2418 char * name = tape_name(STp);
2420 position = osst_get_frame_position(STp, aSRpnt);
2423 STp->header_ok = STp->linux_media = 1;
2424 STp->linux_media_version = 0;
2427 STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2428 STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2429 STp->eod_frame_ppos = STp->first_data_ppos = -1;
2430 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2432 printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2435 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2436 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2438 first = position==10?0xbae: 5;
2439 last = position==10?0xbb3:10;
2441 for (ppos = first; ppos < last; ppos++)
2442 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2445 first = position==10? 5:0xbae;
2446 last = position==10?10:0xbb3;
2448 for (ppos = first; ppos < last; ppos++)
2449 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2453 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2454 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2455 osst_set_frame_position(STp, aSRpnt, 10, 0);
2458 if (position <= STp->first_data_ppos) {
2459 position = STp->first_data_ppos;
2460 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2462 osst_set_frame_position(STp, aSRpnt, position, 0);
2468 static int osst_verify_position(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2470 int frame_position = STp->first_frame_position;
2471 int frame_seq_numbr = STp->frame_seq_number;
2472 int logical_blk_num = STp->logical_blk_num;
2473 int halfway_frame = STp->frame_in_buffer;
2474 int read_pointer = STp->buffer->read_pointer;
2475 int prev_mark_ppos = -1;
2476 int actual_mark_ppos, i, n;
2478 char * name = tape_name(STp);
2480 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2482 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2483 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2485 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2489 if (STp->linux_media_version >= 4) {
2490 for (i=0; i<STp->filemark_cnt; i++)
2491 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2494 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2495 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2496 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2497 if (frame_position != STp->first_frame_position ||
2498 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2499 prev_mark_ppos != actual_mark_ppos ) {
2501 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2502 STp->first_frame_position, frame_position,
2503 STp->frame_seq_number + (halfway_frame?0:1),
2504 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2508 if (halfway_frame) {
2509 /* prepare buffer for append and rewrite on top of original */
2510 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2511 STp->buffer->buffer_bytes = read_pointer;
2512 STp->ps[STp->partition].rw = ST_WRITING;
2515 STp->frame_in_buffer = halfway_frame;
2516 STp->frame_seq_number = frame_seq_numbr;
2517 STp->logical_blk_num = logical_blk_num;
2521 /* Acc. to OnStream, the vers. numbering is the following:
2522 * X.XX for released versions (X=digit),
2523 * XXXY for unreleased versions (Y=letter)
2524 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2525 * This fn makes monoton numbers out of this scheme ...
2527 static unsigned int osst_parse_firmware_rev (const char * str)
2529 if (str[1] == '.') {
2530 return (str[0]-'0')*10000
2534 return (str[0]-'0')*10000
2536 +(str[2]-'0')*100 - 100
2542 * Configure the OnStream SCII tape drive for default operation
2544 static int osst_configure_onstream(struct osst_tape *STp, struct scsi_request ** aSRpnt)
2546 unsigned char cmd[MAX_COMMAND_SIZE];
2547 char * name = tape_name(STp);
2548 struct scsi_request * SRpnt = * aSRpnt;
2549 osst_mode_parameter_header_t * header;
2550 osst_block_size_page_t * bs;
2551 osst_capabilities_page_t * cp;
2552 osst_tape_paramtr_page_t * prm;
2553 int drive_buffer_size;
2555 if (STp->ready != ST_READY) {
2557 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2562 if (STp->os_fw_rev < 10600) {
2563 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2564 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2568 * Configure 32.5KB (data+aux) frame size.
2569 * Get the current frame size from the block size mode page
2571 memset(cmd, 0, MAX_COMMAND_SIZE);
2572 cmd[0] = MODE_SENSE;
2574 cmd[2] = BLOCK_SIZE_PAGE;
2575 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2577 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2578 if (SRpnt == NULL) {
2580 printk(OSST_DEB_MSG "osst :D: Busy\n");
2585 if ((STp->buffer)->syscall_result != 0) {
2586 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2590 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2591 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2594 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2595 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No");
2596 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2597 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2601 * Configure default auto columns mode, 32.5KB transfer mode
2609 memset(cmd, 0, MAX_COMMAND_SIZE);
2610 cmd[0] = MODE_SELECT;
2612 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2614 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2616 if ((STp->buffer)->syscall_result != 0) {
2617 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2622 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2624 * In debug mode, we want to see as many errors as possible
2625 * to test the error recovery mechanism.
2627 osst_set_retries(STp, aSRpnt, 0);
2632 * Set vendor name to 'LIN4' for "Linux support version 4".
2635 memset(cmd, 0, MAX_COMMAND_SIZE);
2636 cmd[0] = MODE_SELECT;
2638 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2640 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2641 header->medium_type = 0; /* Medium Type - ignoring */
2642 header->dsp = 0; /* Reserved */
2643 header->bdl = 0; /* Block Descriptor Length */
2645 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2646 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2647 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2648 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2649 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2650 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2651 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2652 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2654 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2657 if ((STp->buffer)->syscall_result != 0) {
2658 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2659 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2663 memset(cmd, 0, MAX_COMMAND_SIZE);
2664 cmd[0] = MODE_SENSE;
2666 cmd[2] = CAPABILITIES_PAGE;
2667 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2669 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2672 if ((STp->buffer)->syscall_result != 0) {
2673 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2677 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2678 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2679 sizeof(osst_mode_parameter_header_t) + header->bdl);
2681 drive_buffer_size = ntohs(cp->buffer_size) / 2;
2683 memset(cmd, 0, MAX_COMMAND_SIZE);
2684 cmd[0] = MODE_SENSE;
2686 cmd[2] = TAPE_PARAMTR_PAGE;
2687 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2689 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2692 if ((STp->buffer)->syscall_result != 0) {
2693 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2697 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2698 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2699 sizeof(osst_mode_parameter_header_t) + header->bdl);
2701 STp->density = prm->density;
2702 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2704 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2705 name, STp->density, STp->capacity / 32, drive_buffer_size);
2713 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2714 it messes up the block number). */
2715 static int cross_eof(struct osst_tape *STp, struct scsi_request ** aSRpnt, int forward)
2718 char * name = tape_name(STp);
2722 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2723 name, forward ? "forward" : "backward");
2727 /* assumes that the filemark is already read by the drive, so this is low cost */
2728 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2731 /* assumes this is only called if we just read the filemark! */
2732 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2735 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2736 name, forward ? "forward" : "backward");
2742 /* Get the tape position. */
2744 static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt)
2746 unsigned char scmd[MAX_COMMAND_SIZE];
2747 struct scsi_request * SRpnt;
2749 char * name = tape_name(STp);
2751 /* KG: We want to be able to use it for checking Write Buffer availability
2752 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2754 char * olddata = STp->buffer->b_data;
2755 int oldsize = STp->buffer->buffer_size;
2757 if (STp->ready != ST_READY) return (-EIO);
2759 memset (scmd, 0, MAX_COMMAND_SIZE);
2760 scmd[0] = READ_POSITION;
2762 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2763 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2764 STp->timeout, MAX_RETRIES, 1);
2766 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2771 if (STp->buffer->syscall_result)
2772 result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */
2774 if (result == -EINVAL)
2775 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2777 if (result == -EIO) { /* re-read position - this needs to preserve media errors */
2778 unsigned char mysense[16];
2779 memcpy (mysense, SRpnt->sr_sense_buffer, 16);
2780 memset (scmd, 0, MAX_COMMAND_SIZE);
2781 scmd[0] = READ_POSITION;
2782 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2783 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2784 STp->timeout, MAX_RETRIES, 1);
2786 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2787 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2788 SRpnt->sr_sense_buffer[2],SRpnt->sr_sense_buffer[12],SRpnt->sr_sense_buffer[13]);
2790 if (!STp->buffer->syscall_result)
2791 memcpy (SRpnt->sr_sense_buffer, mysense, 16);
2793 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2795 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2796 + ((STp->buffer)->b_data[5] << 16)
2797 + ((STp->buffer)->b_data[6] << 8)
2798 + (STp->buffer)->b_data[7];
2799 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2800 + ((STp->buffer)->b_data[ 9] << 16)
2801 + ((STp->buffer)->b_data[10] << 8)
2802 + (STp->buffer)->b_data[11];
2803 STp->cur_frames = (STp->buffer)->b_data[15];
2806 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2807 STp->first_frame_position, STp->last_frame_position,
2808 ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2809 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2813 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2815 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2816 STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2818 STp->first_frame_position = STp->last_frame_position;
2821 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2823 return (result == 0 ? STp->first_frame_position : result);
2827 /* Set the tape block */
2828 static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int ppos, int skip)
2830 unsigned char scmd[MAX_COMMAND_SIZE];
2831 struct scsi_request * SRpnt;
2832 struct st_partstat * STps;
2834 int pp = (ppos == 3000 && !skip)? 0 : ppos;
2835 char * name = tape_name(STp);
2837 if (STp->ready != ST_READY) return (-EIO);
2839 STps = &(STp->ps[STp->partition]);
2841 if (ppos < 0 || ppos > STp->capacity) {
2842 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2843 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2850 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2852 memset (scmd, 0, MAX_COMMAND_SIZE);
2855 scmd[3] = (pp >> 24);
2856 scmd[4] = (pp >> 16);
2857 scmd[5] = (pp >> 8);
2862 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
2868 if ((STp->buffer)->syscall_result != 0) {
2870 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
2871 name, STp->first_frame_position, pp);
2876 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
2877 } while ((pp != ppos) && (pp = ppos));
2878 STp->first_frame_position = STp->last_frame_position = ppos;
2879 STps->eof = ST_NOEOF;
2882 STp->frame_in_buffer = 0;
2886 static int osst_write_trailer(struct osst_tape *STp, struct scsi_request ** aSRpnt, int leave_at_EOT)
2888 struct st_partstat * STps = &(STp->ps[STp->partition]);
2891 if (STp->write_type != OS_WRITE_NEW_MARK) {
2892 /* true unless the user wrote the filemark for us */
2893 result = osst_flush_drive_buffer(STp, aSRpnt);
2894 if (result < 0) goto out;
2895 result = osst_write_filemark(STp, aSRpnt);
2896 if (result < 0) goto out;
2898 if (STps->drv_file >= 0)
2900 STps->drv_block = 0;
2902 result = osst_write_eod(STp, aSRpnt);
2903 osst_write_header(STp, aSRpnt, leave_at_EOT);
2910 /* osst versions of st functions - augmented and stripped to suit OnStream only */
2912 /* Flush the write buffer (never need to write if variable blocksize). */
2913 static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt)
2915 int offset, transfer, blks = 0;
2917 unsigned char cmd[MAX_COMMAND_SIZE];
2918 struct scsi_request * SRpnt = *aSRpnt;
2919 struct st_partstat * STps;
2920 char * name = tape_name(STp);
2922 if ((STp->buffer)->writing) {
2923 if (SRpnt == (STp->buffer)->last_SRpnt)
2925 { printk(OSST_DEB_MSG
2926 "%s:D: aSRpnt points to scsi_request that write_behind_check will release -- cleared\n", name);
2928 *aSRpnt = SRpnt = NULL;
2932 "%s:D: aSRpnt does not point to scsi_request that write_behind_check will release -- strange\n", name);
2934 osst_write_behind_check(STp);
2935 if ((STp->buffer)->syscall_result) {
2938 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
2939 name, (STp->buffer)->midlevel_result);
2941 if ((STp->buffer)->midlevel_result == INT_MAX)
2948 if (STp->dirty == 1) {
2951 STps = &(STp->ps[STp->partition]);
2952 STps->rw = ST_WRITING;
2953 offset = STp->buffer->buffer_bytes;
2954 blks = (offset + STp->block_size - 1) / STp->block_size;
2955 transfer = OS_FRAME_SIZE;
2957 if (offset < OS_DATA_SIZE)
2958 osst_zero_buffer_tail(STp->buffer);
2961 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
2962 result = osst_recover_wait_frame(STp, aSRpnt, 1);
2964 memset(cmd, 0, MAX_COMMAND_SIZE);
2969 switch (STp->write_type) {
2973 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
2974 name, blks, STp->frame_seq_number,
2975 STp->logical_blk_num - blks, STp->logical_blk_num - 1);
2977 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
2978 STp->logical_blk_num - blks, STp->block_size, blks);
2981 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
2982 STp->logical_blk_num, 0, 0);
2984 case OS_WRITE_NEW_MARK:
2985 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
2986 STp->logical_blk_num++, 0, blks=1);
2988 case OS_WRITE_HEADER:
2989 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
2991 default: /* probably FILLER */
2992 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
2996 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
2997 name, offset, transfer, blks);
3000 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3001 STp->timeout, MAX_RETRIES, 1);
3006 if ((STp->buffer)->syscall_result != 0) {
3009 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3010 name, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
3011 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
3013 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
3014 (SRpnt->sr_sense_buffer[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3015 (SRpnt->sr_sense_buffer[2] & 0x0f) == NO_SENSE) {
3017 (STp->buffer)->buffer_bytes = 0;
3021 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3022 printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3026 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
3029 STp->first_frame_position++;
3031 (STp->buffer)->buffer_bytes = 0;
3035 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3041 /* Flush the tape buffer. The tape will be positioned correctly unless
3042 seek_next is true. */
3043 static int osst_flush_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt, int seek_next)
3045 struct st_partstat * STps;
3046 int backspace = 0, result = 0;
3048 char * name = tape_name(STp);
3052 * If there was a bus reset, block further access
3055 if( STp->pos_unknown)
3058 if (STp->ready != ST_READY)
3061 STps = &(STp->ps[STp->partition]);
3062 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
3063 STp->write_type = OS_WRITE_DATA;
3064 return osst_flush_write_buffer(STp, aSRpnt);
3066 if (STp->block_size == 0)
3070 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3073 if (!STp->can_bsr) {
3074 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3075 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3076 (STp->buffer)->buffer_bytes = 0;
3077 (STp->buffer)->read_pointer = 0;
3078 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3082 if (STps->eof == ST_FM_HIT) {
3083 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3085 STps->eof = ST_NOEOF;
3087 if (STps->drv_file >= 0)
3089 STps->drv_block = 0;
3092 if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3093 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3095 else if (STps->eof == ST_FM_HIT) {
3096 if (STps->drv_file >= 0)
3098 STps->drv_block = 0;
3099 STps->eof = ST_NOEOF;
3105 static int osst_write_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int synchronous)
3107 unsigned char cmd[MAX_COMMAND_SIZE];
3108 struct scsi_request * SRpnt;
3111 char * name = tape_name(STp);
3114 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3116 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3118 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3121 /* error recovery may have bumped us past the header partition */
3122 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3124 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3126 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3131 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3132 if (osst_recover_wait_frame(STp, aSRpnt, 1))
3135 // osst_build_stats(STp, &SRpnt);
3137 STp->ps[STp->partition].rw = ST_WRITING;
3138 STp->write_type = OS_WRITE_DATA;
3140 memset(cmd, 0, MAX_COMMAND_SIZE);
3143 cmd[4] = 1; /* one frame at a time... */
3144 blks = STp->buffer->buffer_bytes / STp->block_size;
3147 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3148 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3150 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3151 STp->logical_blk_num - blks, STp->block_size, blks);
3155 STp->write_pending = 1;
3157 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3158 MAX_RETRIES, synchronous);
3164 if (STp->buffer->syscall_result != 0) {
3167 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3169 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
3170 (SRpnt->sr_sense_buffer[2] & 0x40)) {
3171 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
3175 if (osst_write_error_recovery(STp, aSRpnt, 1))
3180 STp->first_frame_position++;
3188 /* Lock or unlock the drive door. Don't use when struct scsi_request allocated. */
3189 static int do_door_lock(struct osst_tape * STp, int do_lock)
3193 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
3195 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3197 retval = scsi_ioctl(STp->device, cmd, NULL);
3199 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3202 STp->door_locked = ST_LOCK_FAILS;
3207 /* Set the internal state after reset */
3208 static void reset_state(struct osst_tape *STp)
3211 struct st_partstat *STps;
3213 STp->pos_unknown = 0;
3214 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3215 STps = &(STp->ps[i]);
3217 STps->eof = ST_NOEOF;
3219 STps->last_block_valid = 0;
3220 STps->drv_block = -1;
3221 STps->drv_file = -1;
3226 /* Entry points to osst */
3229 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3231 ssize_t total, retval = 0;
3232 ssize_t i, do_count, blks, transfer;
3233 int write_threshold;
3234 int doing_write = 0;
3235 const char __user * b_point;
3236 struct scsi_request * SRpnt = NULL;
3237 struct st_modedef * STm;
3238 struct st_partstat * STps;
3239 struct osst_tape * STp = filp->private_data;
3240 char * name = tape_name(STp);
3243 if (down_interruptible(&STp->lock))
3244 return (-ERESTARTSYS);
3247 * If we are in the middle of error recovery, don't let anyone
3248 * else try and use this device. Also, if error recovery fails, it
3249 * may try and take the device offline, in which case all further
3250 * access to the device is prohibited.
3252 if( !scsi_block_when_processing_errors(STp->device) ) {
3257 if (STp->ready != ST_READY) {
3258 if (STp->ready == ST_NO_TAPE)
3259 retval = (-ENOMEDIUM);
3264 STm = &(STp->modes[STp->current_mode]);
3265 if (!STm->defined) {
3273 * If there was a bus reset, block further access
3276 if (STp->pos_unknown) {
3283 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3289 if (STp->write_prot) {
3294 /* Write must be integral number of blocks */
3295 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3296 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3297 name, count, STp->block_size<1024?
3298 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3303 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3304 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3305 name, STp->first_frame_position);
3310 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3311 STp->door_locked = ST_LOCKED_AUTO;
3313 STps = &(STp->ps[STp->partition]);
3315 if (STps->rw == ST_READING) {
3317 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3318 STps->drv_file, STps->drv_block);
3320 retval = osst_flush_buffer(STp, &SRpnt, 0);
3325 if (STps->rw != ST_WRITING) {
3326 /* Are we totally rewriting this tape? */
3327 if (!STp->header_ok ||
3328 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3329 (STps->drv_file == 0 && STps->drv_block == 0)) {
3330 STp->wrt_pass_cntr++;
3332 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3333 name, STp->wrt_pass_cntr);
3335 osst_reset_header(STp, &SRpnt);
3336 STps->drv_file = STps->drv_block = 0;
3338 /* Do we know where we'll be writing on the tape? */
3340 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3341 STps->drv_file < 0 || STps->drv_block < 0) {
3342 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3343 STps->drv_file = STp->filemark_cnt;
3344 STps->drv_block = 0;
3347 /* We have no idea where the tape is positioned - give up */
3350 "%s:D: Cannot write at indeterminate position.\n", name);
3356 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3357 STp->filemark_cnt = STps->drv_file;
3358 STp->last_mark_ppos =
3359 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3361 "%s:W: Overwriting file %d with old write pass counter %d\n",
3362 name, STps->drv_file, STp->wrt_pass_cntr);
3364 "%s:W: may lead to stale data being accepted on reading back!\n",
3368 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3369 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3375 if (!STp->header_ok) {
3377 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3383 if ((STp->buffer)->writing) {
3384 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3385 osst_write_behind_check(STp);
3386 if ((STp->buffer)->syscall_result) {
3389 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3390 (STp->buffer)->midlevel_result);
3392 if ((STp->buffer)->midlevel_result == INT_MAX)
3393 STps->eof = ST_EOM_OK;
3395 STps->eof = ST_EOM_ERROR;
3398 if (STps->eof == ST_EOM_OK) {
3402 else if (STps->eof == ST_EOM_ERROR) {
3407 /* Check the buffer readability in cases where copy_user might catch
3408 the problems after some tape movement. */
3409 if ((copy_from_user(&i, buf, 1) != 0 ||
3410 copy_from_user(&i, buf + count - 1, 1) != 0)) {
3415 if (!STm->do_buffer_writes) {
3416 write_threshold = 1;
3419 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3420 if (!STm->do_async_writes)
3426 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3427 name, count, STps->drv_file, STps->drv_block,
3428 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3431 while ((STp->buffer)->buffer_bytes + count > write_threshold)
3434 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3435 (STp->buffer)->buffer_bytes;
3436 if (do_count > count)
3439 i = append_to_buffer(b_point, STp->buffer, do_count);
3445 blks = do_count / STp->block_size;
3446 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3448 i = osst_write_frame(STp, &SRpnt, 1);
3450 if (i == (-ENOSPC)) {
3451 transfer = STp->buffer->writing; /* FIXME -- check this logic */
3452 if (transfer <= do_count) {
3453 filp->f_pos += do_count - transfer;
3454 count -= do_count - transfer;
3455 if (STps->drv_block >= 0) {
3456 STps->drv_block += (do_count - transfer) / STp->block_size;
3458 STps->eof = ST_EOM_OK;
3459 retval = (-ENOSPC); /* EOM within current request */
3462 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3467 STps->eof = ST_EOM_ERROR;
3468 STps->drv_block = (-1); /* Too cautious? */
3469 retval = (-EIO); /* EOM for old data */
3472 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3480 if (SRpnt != NULL) {
3481 scsi_release_request(SRpnt);
3484 STp->buffer->buffer_bytes = 0;
3487 retval = total - count;
3491 filp->f_pos += do_count;
3492 b_point += do_count;
3494 if (STps->drv_block >= 0) {
3495 STps->drv_block += blks;
3497 STp->buffer->buffer_bytes = 0;
3499 } /* end while write threshold exceeded */
3503 i = append_to_buffer(b_point, STp->buffer, count);
3508 blks = count / STp->block_size;
3509 STp->logical_blk_num += blks;
3510 if (STps->drv_block >= 0) {
3511 STps->drv_block += blks;
3513 filp->f_pos += count;
3517 if (doing_write && (STp->buffer)->syscall_result != 0) {
3518 retval = (STp->buffer)->syscall_result;
3522 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3523 /* Schedule an asynchronous write */
3524 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3525 STp->block_size) * STp->block_size;
3526 STp->dirty = !((STp->buffer)->writing ==
3527 (STp->buffer)->buffer_bytes);
3529 i = osst_write_frame(STp, &SRpnt, 0);
3534 SRpnt = NULL; /* Prevent releasing this request! */
3536 STps->at_sm &= (total == 0);
3538 STps->eof = ST_NOEOF;
3543 if (SRpnt != NULL) scsi_release_request(SRpnt);
3552 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3554 ssize_t total, retval = 0;
3555 ssize_t i, transfer;
3557 struct st_modedef * STm;
3558 struct st_partstat * STps;
3559 struct scsi_request * SRpnt = NULL;
3560 struct osst_tape * STp = filp->private_data;
3561 char * name = tape_name(STp);
3564 if (down_interruptible(&STp->lock))
3565 return (-ERESTARTSYS);
3568 * If we are in the middle of error recovery, don't let anyone
3569 * else try and use this device. Also, if error recovery fails, it
3570 * may try and take the device offline, in which case all further
3571 * access to the device is prohibited.
3573 if( !scsi_block_when_processing_errors(STp->device) ) {
3578 if (STp->ready != ST_READY) {
3579 if (STp->ready == ST_NO_TAPE)
3580 retval = (-ENOMEDIUM);
3585 STm = &(STp->modes[STp->current_mode]);
3586 if (!STm->defined) {
3592 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3597 /* Must have initialized medium */
3598 if (!STp->header_ok) {
3603 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3604 STp->door_locked = ST_LOCKED_AUTO;
3606 STps = &(STp->ps[STp->partition]);
3607 if (STps->rw == ST_WRITING) {
3608 retval = osst_flush_buffer(STp, &SRpnt, 0);
3612 /* FIXME -- this may leave the tape without EOD and up2date headers */
3615 if ((count % STp->block_size) != 0) {
3617 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3618 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3622 if (debugging && STps->eof != ST_NOEOF)
3623 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3624 STps->eof, (STp->buffer)->buffer_bytes);
3626 if ((STp->buffer)->buffer_bytes == 0 &&
3627 STps->eof >= ST_EOD_1) {
3628 if (STps->eof < ST_EOD) {
3633 retval = (-EIO); /* EOM or Blank Check */
3637 /* Check the buffer writability before any tape movement. Don't alter
3639 if (copy_from_user(&i, buf, 1) != 0 ||
3640 copy_to_user (buf, &i, 1) != 0 ||
3641 copy_from_user(&i, buf + count - 1, 1) != 0 ||
3642 copy_to_user (buf + count - 1, &i, 1) != 0) {
3647 /* Loop until enough data in buffer or a special condition found */
3648 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3650 /* Get new data if the buffer is empty */
3651 if ((STp->buffer)->buffer_bytes == 0) {
3652 if (STps->eof == ST_FM_HIT)
3654 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3655 if (special < 0) { /* No need to continue read */
3656 STp->frame_in_buffer = 0;
3662 /* Move the data from driver buffer to user buffer */
3663 if ((STp->buffer)->buffer_bytes > 0) {
3665 if (debugging && STps->eof != ST_NOEOF)
3666 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3667 STps->eof, (STp->buffer)->buffer_bytes, count - total);
3669 /* force multiple of block size, note block_size may have been adjusted */
3670 transfer = (((STp->buffer)->buffer_bytes < count - total ?
3671 (STp->buffer)->buffer_bytes : count - total)/
3672 STp->block_size) * STp->block_size;
3674 if (transfer == 0) {
3676 "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
3677 name, count, STp->block_size < 1024?
3678 STp->block_size:STp->block_size/1024,
3679 STp->block_size<1024?'b':'k');
3682 i = from_buffer(STp->buffer, buf, transfer);
3687 STp->logical_blk_num += transfer / STp->block_size;
3688 STps->drv_block += transfer / STp->block_size;
3689 filp->f_pos += transfer;
3694 if ((STp->buffer)->buffer_bytes == 0) {
3697 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3698 name, STp->frame_seq_number);
3700 STp->frame_in_buffer = 0;
3701 STp->frame_seq_number++; /* frame to look for next time */
3703 } /* for (total = 0, special = 0; total < count && !special; ) */
3705 /* Change the eof state if no data from tape or buffer */
3707 if (STps->eof == ST_FM_HIT) {
3708 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3709 STps->drv_block = 0;
3710 if (STps->drv_file >= 0)
3713 else if (STps->eof == ST_EOD_1) {
3714 STps->eof = ST_EOD_2;
3715 if (STps->drv_block > 0 && STps->drv_file >= 0)
3717 STps->drv_block = 0;
3719 else if (STps->eof == ST_EOD_2)
3722 else if (STps->eof == ST_FM)
3723 STps->eof = ST_NOEOF;
3728 if (SRpnt != NULL) scsi_release_request(SRpnt);
3736 /* Set the driver options */
3737 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3740 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3741 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3742 STm->do_read_ahead);
3744 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3745 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3747 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3748 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3749 STp->scsi2_logical);
3751 "%s:I: sysv: %d\n", name, STm->sysv);
3754 "%s:D: debugging: %d\n",
3760 static int osst_set_options(struct osst_tape *STp, long options)
3764 struct st_modedef * STm;
3765 char * name = tape_name(STp);
3767 STm = &(STp->modes[STp->current_mode]);
3768 if (!STm->defined) {
3769 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3773 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3774 name, STp->current_mode);
3778 code = options & MT_ST_OPTIONS;
3779 if (code == MT_ST_BOOLEANS) {
3780 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3781 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3782 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3783 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3784 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3785 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3786 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3787 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3788 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3789 if ((STp->device)->scsi_level >= SCSI_2)
3790 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3791 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3792 STm->sysv = (options & MT_ST_SYSV) != 0;
3794 debugging = (options & MT_ST_DEBUGGING) != 0;
3796 osst_log_options(STp, STm, name);
3798 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3799 value = (code == MT_ST_SETBOOLEANS);
3800 if ((options & MT_ST_BUFFER_WRITES) != 0)
3801 STm->do_buffer_writes = value;
3802 if ((options & MT_ST_ASYNC_WRITES) != 0)
3803 STm->do_async_writes = value;
3804 if ((options & MT_ST_DEF_WRITES) != 0)
3805 STm->defaults_for_writes = value;
3806 if ((options & MT_ST_READ_AHEAD) != 0)
3807 STm->do_read_ahead = value;
3808 if ((options & MT_ST_TWO_FM) != 0)
3809 STp->two_fm = value;
3810 if ((options & MT_ST_FAST_MTEOM) != 0)
3811 STp->fast_mteom = value;
3812 if ((options & MT_ST_AUTO_LOCK) != 0)
3813 STp->do_auto_lock = value;
3814 if ((options & MT_ST_CAN_BSR) != 0)
3815 STp->can_bsr = value;
3816 if ((options & MT_ST_NO_BLKLIMS) != 0)
3817 STp->omit_blklims = value;
3818 if ((STp->device)->scsi_level >= SCSI_2 &&
3819 (options & MT_ST_CAN_PARTITIONS) != 0)
3820 STp->can_partitions = value;
3821 if ((options & MT_ST_SCSI2LOGICAL) != 0)
3822 STp->scsi2_logical = value;
3823 if ((options & MT_ST_SYSV) != 0)
3826 if ((options & MT_ST_DEBUGGING) != 0)
3829 osst_log_options(STp, STm, name);
3831 else if (code == MT_ST_WRITE_THRESHOLD) {
3832 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3833 if (value < 1 || value > osst_buffer_size) {
3834 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3838 STp->write_threshold = value;
3839 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3842 else if (code == MT_ST_DEF_BLKSIZE) {
3843 value = (options & ~MT_ST_OPTIONS);
3844 if (value == ~MT_ST_OPTIONS) {
3845 STm->default_blksize = (-1);
3846 printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3849 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3850 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3854 STm->default_blksize = value;
3855 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
3856 name, STm->default_blksize);
3859 else if (code == MT_ST_TIMEOUTS) {
3860 value = (options & ~MT_ST_OPTIONS);
3861 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
3862 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
3863 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
3864 (value & ~MT_ST_SET_LONG_TIMEOUT));
3867 STp->timeout = value * HZ;
3868 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
3871 else if (code == MT_ST_DEF_OPTIONS) {
3872 code = (options & ~MT_ST_CLEAR_DEFAULT);
3873 value = (options & MT_ST_CLEAR_DEFAULT);
3874 if (code == MT_ST_DEF_DENSITY) {
3875 if (value == MT_ST_CLEAR_DEFAULT) {
3876 STm->default_density = (-1);
3877 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
3880 STm->default_density = value & 0xff;
3881 printk(KERN_INFO "%s:I: Density default set to %x\n",
3882 name, STm->default_density);
3885 else if (code == MT_ST_DEF_DRVBUFFER) {
3886 if (value == MT_ST_CLEAR_DEFAULT) {
3887 STp->default_drvbuffer = 0xff;
3888 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
3891 STp->default_drvbuffer = value & 7;
3892 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
3893 name, STp->default_drvbuffer);
3896 else if (code == MT_ST_DEF_COMPRESSION) {
3897 if (value == MT_ST_CLEAR_DEFAULT) {
3898 STm->default_compression = ST_DONT_TOUCH;
3899 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
3902 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
3903 printk(KERN_INFO "%s:I: Compression default set to %x\n",
3915 /* Internal ioctl function */
3916 static int osst_int_ioctl(struct osst_tape * STp, struct scsi_request ** aSRpnt,
3917 unsigned int cmd_in, unsigned long arg)
3921 int i, ioctl_result;
3923 unsigned char cmd[MAX_COMMAND_SIZE];
3924 struct scsi_request * SRpnt = * aSRpnt;
3925 struct st_partstat * STps;
3926 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
3927 int datalen = 0, direction = DMA_NONE;
3928 char * name = tape_name(STp);
3930 if (STp->ready != ST_READY && cmd_in != MTLOAD) {
3931 if (STp->ready == ST_NO_TAPE)
3932 return (-ENOMEDIUM);
3936 timeout = STp->long_timeout;
3937 STps = &(STp->ps[STp->partition]);
3938 fileno = STps->drv_file;
3939 blkno = STps->drv_block;
3940 at_sm = STps->at_sm;
3941 frame_seq_numbr = STp->frame_seq_number;
3942 logical_blk_num = STp->logical_blk_num;
3944 memset(cmd, 0, MAX_COMMAND_SIZE);
3947 chg_eof = 0; /* Changed from the FSF after this */
3951 if (STp->linux_media)
3952 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
3954 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
3958 at_sm &= (arg == 0);
3962 chg_eof = 0; /* Changed from the FSF after this */
3966 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
3969 blkno = (-1); /* We can't know the block number */
3970 at_sm &= (arg == 0);
3977 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
3978 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
3980 if (cmd_in == MTFSR) {
3981 logical_blk_num += arg;
3982 if (blkno >= 0) blkno += arg;
3985 logical_blk_num -= arg;
3986 if (blkno >= 0) blkno -= arg;
3988 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
3989 fileno = STps->drv_file;
3990 blkno = STps->drv_block;
3991 at_sm &= (arg == 0);
3996 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
3997 cmd[2] = (arg >> 16);
3998 cmd[3] = (arg >> 8);
4002 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4003 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4006 blkno = fileno = (-1);
4012 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4014 cmd[2] = (ltmp >> 16);
4015 cmd[3] = (ltmp >> 8);
4021 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4022 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4027 blkno = fileno = (-1);
4032 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4033 STp->write_type = OS_WRITE_DATA;
4034 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4039 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4041 for (i=0; i<arg; i++)
4042 ioctl_result |= osst_write_filemark(STp, &SRpnt);
4043 if (fileno >= 0) fileno += arg;
4044 if (blkno >= 0) blkno = 0;
4048 if (STp->write_prot)
4052 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
4053 if (cmd_in == MTWSM)
4055 cmd[2] = (arg >> 16);
4056 cmd[3] = (arg >> 8);
4058 timeout = STp->timeout;
4061 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4062 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4067 at_sm = (cmd_in == MTWSM);
4073 cmd[0] = START_STOP;
4074 cmd[1] = 1; /* Don't wait for completion */
4075 if (cmd_in == MTLOAD) {
4076 if (STp->ready == ST_NO_TAPE)
4077 cmd[4] = 4; /* open tray */
4079 cmd[4] = 1; /* load */
4081 if (cmd_in == MTRETEN)
4082 cmd[4] = 3; /* retension then mount */
4083 if (cmd_in == MTOFFL)
4084 cmd[4] = 4; /* rewind then eject */
4085 timeout = STp->timeout;
4090 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4093 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4096 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4099 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4104 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4109 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4111 return 0; /* Should do something ? */
4116 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4118 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4119 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4120 ioctl_result = -EIO;
4123 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4125 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4127 ioctl_result = -EIO;
4130 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4131 fileno = STp->filemark_cnt;
4136 if (STp->write_prot)
4138 ioctl_result = osst_reset_header(STp, &SRpnt);
4139 i = osst_write_eod(STp, &SRpnt);
4140 if (i < ioctl_result) ioctl_result = i;
4141 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4142 if (i < ioctl_result) ioctl_result = i;
4143 fileno = blkno = at_sm = 0 ;
4147 cmd[0] = REZERO_UNIT; /* rewind */
4151 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4153 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4156 case MTSETBLK: /* Set block length */
4157 if ((STps->drv_block == 0 ) &&
4159 ((STp->buffer)->buffer_bytes == 0) &&
4160 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4161 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4162 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4164 * Only allowed to change the block size if you opened the
4165 * device at the beginning of a file before writing anything.
4166 * Note, that when reading, changing block_size is futile,
4167 * as the size used when writing overrides it.
4169 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4170 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4171 name, STp->block_size);
4174 case MTSETDENSITY: /* Set tape density */
4175 case MTSETDRVBUFFER: /* Set drive buffering */
4176 case SET_DENS_AND_BLK: /* Set density and block size */
4178 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4179 return (-EIO); /* Not allowed if data in buffer */
4180 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4181 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4182 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4183 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4184 name, (int)(arg & MT_ST_BLKSIZE_MASK),
4185 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4188 return 0; /* FIXME silently ignore if block size didn't change */
4194 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4196 ioctl_result = (STp->buffer)->syscall_result;
4200 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4202 return ioctl_result;
4205 if (!ioctl_result) { /* SCSI command successful */
4206 STp->frame_seq_number = frame_seq_numbr;
4207 STp->logical_blk_num = logical_blk_num;
4213 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4216 if (!ioctl_result) { /* success */
4218 if (cmd_in == MTFSFM) {
4222 if (cmd_in == MTBSFM) {
4226 STps->drv_block = blkno;
4227 STps->drv_file = fileno;
4228 STps->at_sm = at_sm;
4230 if (cmd_in == MTEOM)
4232 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4233 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4235 STp->logical_blk_num++;
4236 STp->frame_seq_number++;
4237 STp->frame_in_buffer = 0;
4238 STp->buffer->read_pointer = 0;
4240 else if (cmd_in == MTFSF)
4241 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4243 STps->eof = ST_NOEOF;
4245 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4246 STp->rew_at_close = 0;
4247 else if (cmd_in == MTLOAD) {
4248 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4249 STp->ps[i].rw = ST_IDLE;
4250 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4255 if (cmd_in == MTREW) {
4256 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4257 if (ioctl_result > 0)
4261 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4262 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4263 STps->drv_file = STps->drv_block = -1;
4265 STps->drv_file = STps->drv_block = 0;
4266 STps->eof = ST_NOEOF;
4267 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4268 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4269 STps->drv_file = STps->drv_block = -1;
4271 STps->drv_file = STp->filemark_cnt;
4272 STps->drv_block = 0;
4275 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4276 STps->drv_file = STps->drv_block = (-1);
4277 STps->eof = ST_NOEOF;
4279 } else if (cmd_in == MTERASE) {
4281 } else if (SRpnt) { /* SCSI command was not completely successful. */
4282 if (SRpnt->sr_sense_buffer[2] & 0x40) {
4283 STps->eof = ST_EOM_OK;
4284 STps->drv_block = 0;
4287 STps->eof = ST_NOEOF;
4289 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == BLANK_CHECK)
4292 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4293 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4297 return ioctl_result;
4301 /* Open the device */
4302 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4304 unsigned short flags;
4305 int i, b_size, new_session = 0, retval = 0;
4306 unsigned char cmd[MAX_COMMAND_SIZE];
4307 struct scsi_request * SRpnt = NULL;
4308 struct osst_tape * STp;
4309 struct st_modedef * STm;
4310 struct st_partstat * STps;
4312 int dev = TAPE_NR(inode);
4313 int mode = TAPE_MODE(inode);
4316 * We really want to do nonseekable_open(inode, filp); here, but some
4317 * versions of tar incorrectly call lseek on tapes and bail out if that
4318 * fails. So we disallow pread() and pwrite(), but permit lseeks.
4320 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
4322 write_lock(&os_scsi_tapes_lock);
4323 if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4324 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4325 write_unlock(&os_scsi_tapes_lock);
4329 name = tape_name(STp);
4332 write_unlock(&os_scsi_tapes_lock);
4334 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4338 if (scsi_device_get(STp->device)) {
4339 write_unlock(&os_scsi_tapes_lock);
4341 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4345 filp->private_data = STp;
4347 write_unlock(&os_scsi_tapes_lock);
4348 STp->rew_at_close = TAPE_REWIND(inode);
4350 if( !scsi_block_when_processing_errors(STp->device) ) {
4354 if (mode != STp->current_mode) {
4357 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4358 name, STp->current_mode, mode);
4361 STp->current_mode = mode;
4363 STm = &(STp->modes[STp->current_mode]);
4365 flags = filp->f_flags;
4366 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4368 STp->raw = TAPE_IS_RAW(inode);
4372 /* Allocate data segments for this device's tape buffer */
4373 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4374 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4375 retval = (-EOVERFLOW);
4378 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4379 for (i = 0, b_size = 0;
4380 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4381 b_size += STp->buffer->sg[i++].length);
4382 STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
4384 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4385 STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4386 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4387 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4390 STp->buffer->aux = NULL; /* this had better never happen! */
4391 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4395 STp->buffer->writing = 0;
4396 STp->buffer->syscall_result = 0;
4398 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4399 STps = &(STp->ps[i]);
4402 STp->ready = ST_READY;
4404 STp->nbr_waits = STp->nbr_finished = 0;
4407 memset (cmd, 0, MAX_COMMAND_SIZE);
4408 cmd[0] = TEST_UNIT_READY;
4410 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4412 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
4415 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4416 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
4417 SRpnt->sr_sense_buffer[12] == 4 ) {
4419 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sr_sense_buffer[13]);
4421 if (filp->f_flags & O_NONBLOCK) {
4425 if (SRpnt->sr_sense_buffer[13] == 2) { /* initialize command required (LOAD) */
4426 memset (cmd, 0, MAX_COMMAND_SIZE);
4427 cmd[0] = START_STOP;
4430 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4431 STp->timeout, MAX_RETRIES, 1);
4433 osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0);
4435 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4436 (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4438 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4442 for (i=0; i < 10; i++) {
4444 memset (cmd, 0, MAX_COMMAND_SIZE);
4445 cmd[0] = TEST_UNIT_READY;
4447 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4448 STp->timeout, MAX_RETRIES, 1);
4449 if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
4450 (SRpnt->sr_sense_buffer[2] & 0x0f) != UNIT_ATTENTION)
4454 STp->pos_unknown = 0;
4455 STp->partition = STp->new_partition = 0;
4456 if (STp->can_partitions)
4457 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4458 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4459 STps = &(STp->ps[i]);
4460 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4461 STps->eof = ST_NOEOF;
4463 STps->last_block_valid = 0;
4464 STps->drv_block = 0;
4465 STps->drv_file = 0 ;
4468 STp->recover_count = 0;
4469 STp->abort_count = 0;
4472 * if we have valid headers from before, and the drive/tape seem untouched,
4473 * open without reconfiguring and re-reading the headers
4475 if (!STp->buffer->syscall_result && STp->header_ok &&
4476 !SRpnt->sr_result && SRpnt->sr_sense_buffer[0] == 0) {
4478 memset(cmd, 0, MAX_COMMAND_SIZE);
4479 cmd[0] = MODE_SENSE;
4481 cmd[2] = VENDOR_IDENT_PAGE;
4482 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4484 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4486 if (STp->buffer->syscall_result ||
4487 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4488 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4489 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4490 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4492 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4493 STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4494 STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4495 STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4496 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4500 i = STp->first_frame_position;
4501 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4502 if (STp->door_locked == ST_UNLOCKED) {
4503 if (do_door_lock(STp, 1))
4504 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4506 STp->door_locked = ST_LOCKED_AUTO;
4508 if (!STp->frame_in_buffer) {
4509 STp->block_size = (STm->default_blksize > 0) ?
4510 STm->default_blksize : OS_DATA_SIZE;
4511 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4513 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4515 scsi_release_request(SRpnt);
4519 if (i != STp->first_frame_position)
4520 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4521 name, i, STp->first_frame_position);
4527 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4528 (SRpnt->sr_sense_buffer[2] != 2 || SRpnt->sr_sense_buffer[12] != 0x3A) ) {
4530 memset(cmd, 0, MAX_COMMAND_SIZE);
4531 cmd[0] = MODE_SELECT;
4533 cmd[4] = 4 + MODE_HEADER_LENGTH;
4535 (STp->buffer)->b_data[0] = cmd[4] - 1;
4536 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4537 (STp->buffer)->b_data[2] = 0; /* Reserved */
4538 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4539 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4540 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4541 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4542 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4545 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4547 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4551 for (i=0; i < 10; i++) {
4553 memset (cmd, 0, MAX_COMMAND_SIZE);
4554 cmd[0] = TEST_UNIT_READY;
4556 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4557 STp->timeout, MAX_RETRIES, 1);
4558 if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
4559 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY)
4562 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) {
4563 STp->pos_unknown = 0;
4564 STp->partition = STp->new_partition = 0;
4565 if (STp->can_partitions)
4566 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4567 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4568 STps = &(STp->ps[i]);
4570 STps->eof = ST_NOEOF;
4572 STps->last_block_valid = 0;
4573 STps->drv_block = 0;
4574 STps->drv_file = 0 ;
4581 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4582 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4584 if ((STp->buffer)->syscall_result != 0) {
4585 if ((STp->device)->scsi_level >= SCSI_2 &&
4586 (SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4587 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
4588 SRpnt->sr_sense_buffer[12] == 0x3a) { /* Check ASC */
4589 STp->ready = ST_NO_TAPE;
4591 STp->ready = ST_NOT_READY;
4592 scsi_release_request(SRpnt);
4594 STp->density = 0; /* Clear the erroneous "residue" */
4595 STp->write_prot = 0;
4596 STp->block_size = 0;
4597 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4598 STp->partition = STp->new_partition = 0;
4599 STp->door_locked = ST_UNLOCKED;
4603 osst_configure_onstream(STp, &SRpnt);
4605 STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4606 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4607 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4608 STp->buffer->buffer_bytes =
4609 STp->buffer->read_pointer =
4610 STp->frame_in_buffer = 0;
4614 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4615 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4616 (STp->buffer)->buffer_blocks);
4619 if (STp->drv_write_prot) {
4620 STp->write_prot = 1;
4623 printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4625 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4631 if (new_session) { /* Change the drive parameters for the new mode */
4634 printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4636 STp->density_changed = STp->blksize_changed = 0;
4637 STp->compression_changed = 0;
4641 * properly position the tape and check the ADR headers
4643 if (STp->door_locked == ST_UNLOCKED) {
4644 if (do_door_lock(STp, 1))
4645 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4647 STp->door_locked = ST_LOCKED_AUTO;
4650 osst_analyze_headers(STp, &SRpnt);
4652 scsi_release_request(SRpnt);
4659 scsi_release_request(SRpnt);
4660 normalize_buffer(STp->buffer);
4663 scsi_device_put(STp->device);
4669 /* Flush the tape buffer before close */
4670 static int os_scsi_tape_flush(struct file * filp)
4672 int result = 0, result2;
4673 struct osst_tape * STp = filp->private_data;
4674 struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4675 struct st_partstat * STps = &(STp->ps[STp->partition]);
4676 struct scsi_request * SRpnt = NULL;
4677 char * name = tape_name(STp);
4679 if (file_count(filp) > 1)
4682 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4683 STp->write_type = OS_WRITE_DATA;
4684 result = osst_flush_write_buffer(STp, &SRpnt);
4685 if (result != 0 && result != (-ENOSPC))
4688 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4692 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4693 name, (long)(filp->f_pos));
4694 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4695 name, STp->nbr_waits, STp->nbr_finished);
4698 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4701 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4702 name, 1+STp->two_fm);
4705 else if (!STp->rew_at_close) {
4706 STps = &(STp->ps[STp->partition]);
4707 if (!STm->sysv || STps->rw != ST_READING) {
4709 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4710 else if (STps->eof == ST_FM_HIT) {
4711 result = cross_eof(STp, &SRpnt, 0);
4713 if (STps->drv_file >= 0)
4715 STps->drv_block = 0;
4719 STps->eof = ST_NOEOF;
4722 else if ((STps->eof == ST_NOEOF &&
4723 !(result = cross_eof(STp, &SRpnt, 1))) ||
4724 STps->eof == ST_FM_HIT) {
4725 if (STps->drv_file >= 0)
4727 STps->drv_block = 0;
4733 if (STp->rew_at_close) {
4734 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4735 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4736 if (result == 0 && result2 < 0)
4739 if (SRpnt) scsi_release_request(SRpnt);
4741 if (STp->abort_count || STp->recover_count) {
4742 printk(KERN_INFO "%s:I:", name);
4743 if (STp->abort_count)
4744 printk(" %d unrecovered errors", STp->abort_count);
4745 if (STp->recover_count)
4746 printk(" %d recovered errors", STp->recover_count);
4747 if (STp->write_count)
4748 printk(" in %d frames written", STp->write_count);
4749 if (STp->read_count)
4750 printk(" in %d frames read", STp->read_count);
4752 STp->recover_count = 0;
4753 STp->abort_count = 0;
4755 STp->write_count = 0;
4756 STp->read_count = 0;
4762 /* Close the device and release it */
4763 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4766 struct osst_tape * STp = filp->private_data;
4768 if (STp->door_locked == ST_LOCKED_AUTO)
4769 do_door_lock(STp, 0);
4774 normalize_buffer(STp->buffer);
4775 write_lock(&os_scsi_tapes_lock);
4777 write_unlock(&os_scsi_tapes_lock);
4779 scsi_device_put(STp->device);
4785 /* The ioctl command */
4786 static int osst_ioctl(struct inode * inode,struct file * file,
4787 unsigned int cmd_in, unsigned long arg)
4789 int i, cmd_nr, cmd_type, retval = 0;
4791 struct st_modedef * STm;
4792 struct st_partstat * STps;
4793 struct scsi_request * SRpnt = NULL;
4794 struct osst_tape * STp = file->private_data;
4795 char * name = tape_name(STp);
4796 void __user * p = (void __user *)arg;
4798 if (down_interruptible(&STp->lock))
4799 return -ERESTARTSYS;
4802 if (debugging && !STp->in_use) {
4803 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4808 STm = &(STp->modes[STp->current_mode]);
4809 STps = &(STp->ps[STp->partition]);
4812 * If we are in the middle of error recovery, don't let anyone
4813 * else try and use this device. Also, if error recovery fails, it
4814 * may try and take the device offline, in which case all further
4815 * access to the device is prohibited.
4817 if( !scsi_block_when_processing_errors(STp->device) ) {
4822 cmd_type = _IOC_TYPE(cmd_in);
4823 cmd_nr = _IOC_NR(cmd_in);
4825 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4826 cmd_type, cmd_nr, STp->raw?"raw":"normal");
4828 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4832 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
4837 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
4843 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
4844 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
4849 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
4854 if (!STp->pos_unknown) {
4856 if (STps->eof == ST_FM_HIT) {
4857 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
4859 if (STps->drv_file >= 0)
4860 STps->drv_file += 1;
4862 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
4864 if (STps->drv_file >= 0)
4865 STps->drv_file += 1;
4869 if (mtc.mt_op == MTSEEK) {
4870 /* Old position must be restored if partition will be changed */
4871 i = !STp->can_partitions || (STp->new_partition != STp->partition);
4874 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
4875 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
4876 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
4877 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
4878 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
4879 mtc.mt_op == MTCOMPRESSION;
4881 i = osst_flush_buffer(STp, &SRpnt, i);
4889 * If there was a bus reset, block further access
4890 * to this device. If the user wants to rewind the tape,
4891 * then reset the flag and allow access again.
4893 if(mtc.mt_op != MTREW &&
4894 mtc.mt_op != MTOFFL &&
4895 mtc.mt_op != MTRETEN &&
4896 mtc.mt_op != MTERASE &&
4897 mtc.mt_op != MTSEEK &&
4898 mtc.mt_op != MTEOM) {
4903 /* remove this when the midlevel properly clears was_reset */
4904 STp->device->was_reset = 0;
4907 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK &&
4908 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
4909 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER &&
4910 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART &&
4911 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) {
4914 * The user tells us to move to another position on the tape.
4915 * If we were appending to the tape content, that would leave
4916 * the tape without proper end, in that case write EOD and
4917 * update the header to reflect its position.
4920 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
4921 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
4922 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
4923 STp->logical_blk_num, STps->drv_file, STps->drv_block );
4925 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
4926 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
4927 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4928 i = osst_write_trailer(STp, &SRpnt,
4929 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4931 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
4932 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
4933 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
4943 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
4944 do_door_lock(STp, 0); /* Ignore result! */
4946 if (mtc.mt_op == MTSETDRVBUFFER &&
4947 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
4948 retval = osst_set_options(STp, mtc.mt_count);
4952 if (mtc.mt_op == MTSETPART) {
4953 if (mtc.mt_count >= STp->nbr_partitions)
4956 STp->new_partition = mtc.mt_count;
4962 if (mtc.mt_op == MTMKPART) {
4963 if (!STp->can_partitions) {
4967 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
4968 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
4972 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4973 STp->ps[i].rw = ST_IDLE;
4974 STp->ps[i].at_sm = 0;
4975 STp->ps[i].last_block_valid = 0;
4977 STp->partition = STp->new_partition = 0;
4978 STp->nbr_partitions = 1; /* Bad guess ?-) */
4979 STps->drv_block = STps->drv_file = 0;
4984 if (mtc.mt_op == MTSEEK) {
4986 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
4988 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
4989 if (!STp->can_partitions)
4990 STp->ps[0].rw = ST_IDLE;
4995 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
4996 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
5001 cross_eof(STp, &SRpnt, 0);
5003 if (mtc.mt_op == MTCOMPRESSION)
5004 retval = -EINVAL; /* OnStream drives don't have compression hardware */
5006 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5007 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5008 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5012 if (!STm->defined) {
5017 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5022 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
5023 struct mtget mt_status;
5025 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
5030 mt_status.mt_type = MT_ISONSTREAM_SC;
5031 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
5032 mt_status.mt_dsreg =
5033 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
5034 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
5035 mt_status.mt_blkno = STps->drv_block;
5036 mt_status.mt_fileno = STps->drv_file;
5037 if (STp->block_size != 0) {
5038 if (STps->rw == ST_WRITING)
5039 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
5040 else if (STps->rw == ST_READING)
5041 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
5042 STp->block_size - 1) / STp->block_size;
5045 mt_status.mt_gstat = 0;
5046 if (STp->drv_write_prot)
5047 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
5048 if (mt_status.mt_blkno == 0) {
5049 if (mt_status.mt_fileno == 0)
5050 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
5052 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
5054 mt_status.mt_resid = STp->partition;
5055 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
5056 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
5057 else if (STps->eof >= ST_EOM_OK)
5058 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
5059 if (STp->density == 1)
5060 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
5061 else if (STp->density == 2)
5062 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
5063 else if (STp->density == 3)
5064 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
5065 if (STp->ready == ST_READY)
5066 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
5067 if (STp->ready == ST_NO_TAPE)
5068 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
5070 mt_status.mt_gstat |= GMT_SM(0xffffffff);
5071 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
5072 STp->drv_buffer != 0)
5073 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
5075 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
5081 STp->recover_erreg = 0; /* Clear after read */
5084 } /* End of MTIOCGET */
5086 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5087 struct mtpos mt_pos;
5089 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5094 blk = osst_get_frame_position(STp, &SRpnt);
5096 blk = osst_get_sector(STp, &SRpnt);
5101 mt_pos.mt_blkno = blk;
5102 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5107 if (SRpnt) scsi_release_request(SRpnt);
5111 return scsi_ioctl(STp->device, cmd_in, p);
5114 if (SRpnt) scsi_release_request(SRpnt);
5121 #ifdef CONFIG_COMPAT
5122 static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg)
5124 struct osst_tape *STp = file->private_data;
5125 struct scsi_device *sdev = STp->device;
5126 int ret = -ENOIOCTLCMD;
5127 if (sdev->host->hostt->compat_ioctl) {
5129 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
5138 /* Memory handling routines */
5140 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5141 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5145 struct osst_buffer *tb;
5147 if (from_initialization)
5148 priority = GFP_ATOMIC;
5150 priority = GFP_KERNEL;
5152 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5153 tb = (struct osst_buffer *)kmalloc(i, priority);
5155 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5159 tb->sg_segs = tb->orig_sg_segs = 0;
5160 tb->use_sg = max_sg;
5163 tb->buffer_size = 0;
5167 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5168 i, max_sg, need_dma);
5173 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5174 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5176 int segs, nbr, max_segs, b_size, order, got;
5179 if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5182 if (STbuffer->sg_segs) {
5183 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5184 normalize_buffer(STbuffer);
5186 /* See how many segments we can use -- need at least two */
5187 nbr = max_segs = STbuffer->use_sg;
5191 priority = GFP_KERNEL /* | __GFP_NOWARN */;
5193 priority |= GFP_DMA;
5195 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5196 big enough to reach the goal (code assumes no segments in place) */
5197 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5198 STbuffer->sg[0].page = alloc_pages(priority, order);
5199 STbuffer->sg[0].offset = 0;
5200 if (STbuffer->sg[0].page != NULL) {
5201 STbuffer->sg[0].length = b_size;
5202 STbuffer->b_data = page_address(STbuffer->sg[0].page);
5206 if (STbuffer->sg[0].page == NULL) {
5207 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5210 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5211 for (segs=STbuffer->sg_segs=1, got=b_size;
5212 segs < max_segs && got < OS_FRAME_SIZE; ) {
5213 STbuffer->sg[segs].page =
5214 alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5215 STbuffer->sg[segs].offset = 0;
5216 if (STbuffer->sg[segs].page == NULL) {
5217 if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
5218 b_size /= 2; /* Large enough for the rest of the buffers */
5222 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5225 STbuffer->buffer_size = got;
5227 normalize_buffer(STbuffer);
5230 STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
5231 got += STbuffer->sg[segs].length;
5232 STbuffer->buffer_size = got;
5233 STbuffer->sg_segs = ++segs;
5238 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5239 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5241 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5242 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5243 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5251 /* Release the segments */
5252 static void normalize_buffer(struct osst_buffer *STbuffer)
5254 int i, order, b_size;
5256 for (i=0; i < STbuffer->sg_segs; i++) {
5258 for (b_size = PAGE_SIZE, order = 0;
5259 b_size < STbuffer->sg[i].length;
5260 b_size *= 2, order++);
5262 __free_pages(STbuffer->sg[i].page, order);
5263 STbuffer->buffer_size -= STbuffer->sg[i].length;
5266 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5267 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5268 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5270 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5274 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5275 negative error code. */
5276 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
5278 int i, cnt, res, offset;
5280 for (i=0, offset=st_bp->buffer_bytes;
5281 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5282 offset -= st_bp->sg[i].length;
5283 if (i == st_bp->sg_segs) { /* Should never happen */
5284 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5287 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5288 cnt = st_bp->sg[i].length - offset < do_count ?
5289 st_bp->sg[i].length - offset : do_count;
5290 res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
5294 st_bp->buffer_bytes += cnt;
5298 if (do_count) { /* Should never happen */
5299 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5307 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5308 negative error code. */
5309 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
5311 int i, cnt, res, offset;
5313 for (i=0, offset=st_bp->read_pointer;
5314 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5315 offset -= st_bp->sg[i].length;
5316 if (i == st_bp->sg_segs) { /* Should never happen */
5317 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5320 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5321 cnt = st_bp->sg[i].length - offset < do_count ?
5322 st_bp->sg[i].length - offset : do_count;
5323 res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
5327 st_bp->buffer_bytes -= cnt;
5328 st_bp->read_pointer += cnt;
5332 if (do_count) { /* Should never happen */
5333 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5339 /* Sets the tail of the buffer after fill point to zero.
5340 Returns zero (success) or negative error code. */
5341 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
5343 int i, offset, do_count, cnt;
5345 for (i = 0, offset = st_bp->buffer_bytes;
5346 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5347 offset -= st_bp->sg[i].length;
5348 if (i == st_bp->sg_segs) { /* Should never happen */
5349 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5352 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5353 i < st_bp->sg_segs && do_count > 0; i++) {
5354 cnt = st_bp->sg[i].length - offset < do_count ?
5355 st_bp->sg[i].length - offset : do_count ;
5356 memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
5360 if (do_count) { /* Should never happen */
5361 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5367 /* Copy a osst 32K chunk of memory into the buffer.
5368 Returns zero (success) or negative error code. */
5369 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5371 int i, cnt, do_count = OS_DATA_SIZE;
5373 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5374 cnt = st_bp->sg[i].length < do_count ?
5375 st_bp->sg[i].length : do_count ;
5376 memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
5380 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5381 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5388 /* Copy a osst 32K chunk of memory from the buffer.
5389 Returns zero (success) or negative error code. */
5390 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5392 int i, cnt, do_count = OS_DATA_SIZE;
5394 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5395 cnt = st_bp->sg[i].length < do_count ?
5396 st_bp->sg[i].length : do_count ;
5397 memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
5401 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5402 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5410 /* Module housekeeping */
5412 static void validate_options (void)
5415 osst_max_dev = max_dev;
5416 if (write_threshold_kbs > 0)
5417 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5418 if (osst_write_threshold > osst_buffer_size)
5419 osst_write_threshold = osst_buffer_size;
5420 if (max_sg_segs >= OSST_FIRST_SG)
5421 osst_max_sg_segs = max_sg_segs;
5423 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5424 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5429 /* Set the boot options. Syntax: osst=xxx,yyy,...
5430 where xxx is write threshold in 1024 byte blocks,
5431 and yyy is number of s/g segments to use. */
5432 static int __init osst_setup (char *str)
5437 stp = get_options(str, ARRAY_SIZE(ints), ints);
5440 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5441 *parms[i].val = ints[i + 1];
5443 while (stp != NULL) {
5444 for (i = 0; i < ARRAY_SIZE(parms); i++) {
5445 int len = strlen(parms[i].name);
5446 if (!strncmp(stp, parms[i].name, len) &&
5447 (*(stp + len) == ':' || *(stp + len) == '=')) {
5449 simple_strtoul(stp + len + 1, NULL, 0);
5453 if (i >= sizeof(parms) / sizeof(struct osst_dev_parm))
5454 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5456 stp = strchr(stp, ',');
5465 __setup("osst=", osst_setup);
5469 static struct file_operations osst_fops = {
5470 .owner = THIS_MODULE,
5472 .write = osst_write,
5473 .ioctl = osst_ioctl,
5474 #ifdef CONFIG_COMPAT
5475 .compat_ioctl = osst_compat_ioctl,
5477 .open = os_scsi_tape_open,
5478 .flush = os_scsi_tape_flush,
5479 .release = os_scsi_tape_close,
5482 static int osst_supports(struct scsi_device * SDp)
5484 struct osst_support_data {
5488 char *driver_hint; /* Name of the correct driver, NULL if unknown */
5491 static struct osst_support_data support_list[] = {
5492 /* {"XXX", "Yy-", "", NULL}, example */
5496 struct osst_support_data *rp;
5498 /* We are willing to drive OnStream SC-x0 as well as the
5499 * * IDE, ParPort, FireWire, USB variants, if accessible by
5500 * * emulation layer (ide-scsi, usb-storage, ...) */
5502 for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5503 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5504 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5505 !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5511 * sysfs support for osst driver parameter information
5514 static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
5516 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
5519 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
5521 static void osst_create_driverfs_files(struct device_driver *driverfs)
5523 driver_create_file(driverfs, &driver_attr_version);
5526 static void osst_remove_driverfs_files(struct device_driver *driverfs)
5528 driver_remove_file(driverfs, &driver_attr_version);
5532 * sysfs support for accessing ADR header information
5535 static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf)
5537 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5540 if (STp && STp->header_ok && STp->linux_media)
5541 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
5545 CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
5547 static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf)
5549 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5552 if (STp && STp->header_ok && STp->linux_media)
5553 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
5557 CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
5559 static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf)
5561 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5564 if (STp && STp->header_ok && STp->linux_media)
5565 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
5569 CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
5571 static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf)
5573 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5576 if (STp && STp->header_ok && STp->linux_media)
5577 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
5581 CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
5583 static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf)
5585 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5588 if (STp && STp->header_ok && STp->linux_media)
5589 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
5593 CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
5595 static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf)
5597 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5600 if (STp && STp->header_ok && STp->linux_media)
5601 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
5605 CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5607 static struct class *osst_sysfs_class;
5609 static int osst_sysfs_valid = 0;
5611 static void osst_sysfs_init(void)
5613 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
5614 if ( IS_ERR(osst_sysfs_class) )
5615 printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
5617 osst_sysfs_valid = 1;
5620 static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5622 struct class_device *osst_class_member;
5624 if (!osst_sysfs_valid) return;
5626 osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name);
5627 if (IS_ERR(osst_class_member)) {
5628 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5631 class_set_devdata(osst_class_member, STp);
5632 class_device_create_file(osst_class_member, &class_device_attr_ADR_rev);
5633 class_device_create_file(osst_class_member, &class_device_attr_media_version);
5634 class_device_create_file(osst_class_member, &class_device_attr_capacity);
5635 class_device_create_file(osst_class_member, &class_device_attr_BOT_frame);
5636 class_device_create_file(osst_class_member, &class_device_attr_EOD_frame);
5637 class_device_create_file(osst_class_member, &class_device_attr_file_count);
5640 static void osst_sysfs_destroy(dev_t dev)
5642 if (!osst_sysfs_valid) return;
5644 class_device_destroy(osst_sysfs_class, dev);
5647 static void osst_sysfs_cleanup(void)
5649 if (osst_sysfs_valid) {
5650 class_destroy(osst_sysfs_class);
5651 osst_sysfs_valid = 0;
5656 * osst startup / cleanup code
5659 static int osst_probe(struct device *dev)
5661 struct scsi_device * SDp = to_scsi_device(dev);
5662 struct osst_tape * tpnt;
5663 struct st_modedef * STm;
5664 struct st_partstat * STps;
5665 struct osst_buffer * buffer;
5666 struct gendisk * drive;
5669 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5672 drive = alloc_disk(1);
5674 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5678 /* if this is the first attach, build the infrastructure */
5679 write_lock(&os_scsi_tapes_lock);
5680 if (os_scsi_tapes == NULL) {
5682 (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *),
5684 if (os_scsi_tapes == NULL) {
5685 write_unlock(&os_scsi_tapes_lock);
5686 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5689 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5692 if (osst_nr_dev >= osst_max_dev) {
5693 write_unlock(&os_scsi_tapes_lock);
5694 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5698 /* find a free minor number */
5699 for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++);
5700 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5703 /* allocate a struct osst_tape for this device */
5704 tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
5706 write_unlock(&os_scsi_tapes_lock);
5707 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5710 memset(tpnt, 0, sizeof(struct osst_tape));
5712 /* allocate a buffer for this device */
5713 i = SDp->host->sg_tablesize;
5714 if (osst_max_sg_segs < i)
5715 i = osst_max_sg_segs;
5716 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
5717 if (buffer == NULL) {
5718 write_unlock(&os_scsi_tapes_lock);
5719 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5723 os_scsi_tapes[dev_num] = tpnt;
5724 tpnt->buffer = buffer;
5726 drive->private_data = &tpnt->driver;
5727 sprintf(drive->disk_name, "osst%d", dev_num);
5728 tpnt->driver = &osst_template;
5729 tpnt->drive = drive;
5731 tpnt->capacity = 0xfffff;
5733 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
5734 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5736 tpnt->do_auto_lock = OSST_AUTO_LOCK;
5737 tpnt->can_bsr = OSST_IN_FILE_POS;
5738 tpnt->can_partitions = 0;
5739 tpnt->two_fm = OSST_TWO_FM;
5740 tpnt->fast_mteom = OSST_FAST_MTEOM;
5741 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5742 tpnt->write_threshold = osst_write_threshold;
5743 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5744 tpnt->partition = 0;
5745 tpnt->new_partition = 0;
5746 tpnt->nbr_partitions = 0;
5747 tpnt->min_block = 512;
5748 tpnt->max_block = OS_DATA_SIZE;
5749 tpnt->timeout = OSST_TIMEOUT;
5750 tpnt->long_timeout = OSST_LONG_TIMEOUT;
5752 /* Recognize OnStream tapes */
5753 /* We don't need to test for OnStream, as this has been done in detect () */
5754 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5755 tpnt->omit_blklims = 1;
5757 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5758 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5759 tpnt->frame_in_buffer = 0;
5760 tpnt->header_ok = 0;
5761 tpnt->linux_media = 0;
5762 tpnt->header_cache = NULL;
5764 for (i=0; i < ST_NBR_MODES; i++) {
5765 STm = &(tpnt->modes[i]);
5767 STm->sysv = OSST_SYSV;
5768 STm->defaults_for_writes = 0;
5769 STm->do_async_writes = OSST_ASYNC_WRITES;
5770 STm->do_buffer_writes = OSST_BUFFER_WRITES;
5771 STm->do_read_ahead = OSST_READ_AHEAD;
5772 STm->default_compression = ST_DONT_TOUCH;
5773 STm->default_blksize = 512;
5774 STm->default_density = (-1); /* No forced density */
5777 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5778 STps = &(tpnt->ps[i]);
5780 STps->eof = ST_NOEOF;
5782 STps->last_block_valid = 0;
5783 STps->drv_block = (-1);
5784 STps->drv_file = (-1);
5787 tpnt->current_mode = 0;
5788 tpnt->modes[0].defined = 1;
5789 tpnt->modes[2].defined = 1;
5790 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
5792 init_MUTEX(&tpnt->lock);
5794 write_unlock(&os_scsi_tapes_lock);
5798 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5799 /* No-rewind entry */
5800 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5801 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5804 sdev_printk(KERN_INFO, SDp,
5805 "osst :I: Attached OnStream %.5s tape as %s\n",
5806 SDp->model, tape_name(tpnt));
5815 static int osst_remove(struct device *dev)
5817 struct scsi_device * SDp = to_scsi_device(dev);
5818 struct osst_tape * tpnt;
5821 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
5824 write_lock(&os_scsi_tapes_lock);
5825 for(i=0; i < osst_max_dev; i++) {
5826 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
5827 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
5828 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
5829 tpnt->device = NULL;
5830 put_disk(tpnt->drive);
5831 os_scsi_tapes[i] = NULL;
5833 write_unlock(&os_scsi_tapes_lock);
5834 vfree(tpnt->header_cache);
5836 normalize_buffer(tpnt->buffer);
5837 kfree(tpnt->buffer);
5843 write_unlock(&os_scsi_tapes_lock);
5847 static int __init init_osst(void)
5849 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
5854 if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
5855 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
5856 osst_sysfs_cleanup();
5859 osst_create_driverfs_files(&osst_template.gendrv);
5864 static void __exit exit_osst (void)
5867 struct osst_tape * STp;
5869 osst_remove_driverfs_files(&osst_template.gendrv);
5870 scsi_unregister_driver(&osst_template.gendrv);
5871 unregister_chrdev(OSST_MAJOR, "osst");
5872 osst_sysfs_cleanup();
5874 if (os_scsi_tapes) {
5875 for (i=0; i < osst_max_dev; ++i) {
5876 if (!(STp = os_scsi_tapes[i])) continue;
5877 /* This is defensive, supposed to happen during detach */
5878 vfree(STp->header_cache);
5880 normalize_buffer(STp->buffer);
5883 put_disk(STp->drive);
5886 kfree(os_scsi_tapes);
5888 printk(KERN_INFO "osst :I: Unloaded.\n");
5891 module_init(init_osst);
5892 module_exit(exit_osst);