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 / Willem Riede
17 email Kai.Makisara@metla.fi / osst@riede.org
19 $Header: /cvsroot/osst/Driver/osst.c,v 1.70 2003/12/23 14:22:12 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.70 2003/12/23 14:22:12 wriede Exp $";
27 const char * osst_version = "0.99.1";
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>
40 #include <linux/init.h>
41 #include <linux/string.h>
42 #include <linux/errno.h>
43 #include <linux/mtio.h>
44 #include <linux/ioctl.h>
45 #include <linux/fcntl.h>
46 #include <linux/spinlock.h>
47 #include <linux/vmalloc.h>
48 #include <linux/blkdev.h>
49 #include <linux/devfs_fs_kernel.h>
50 #include <linux/delay.h>
51 #include <asm/uaccess.h>
53 #include <asm/system.h>
55 /* The driver prints some debugging information on the console if DEBUG
56 is defined and non-zero. */
59 /* The message level for the debug messages is currently set to KERN_NOTICE
60 so that people can easily see the messages. Later when the debugging messages
61 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
62 #define OSST_DEB_MSG KERN_NOTICE
65 #include <scsi/scsi_host.h>
66 #include <scsi/scsi_driver.h>
67 #include <scsi/scsi_ioctl.h>
69 #define ST_KILOBYTE 1024
73 #include "osst_options.h"
74 #include "osst_detect.h"
76 static int max_dev = 0;
77 static int write_threshold_kbs = 0;
78 static int max_sg_segs = 0;
81 MODULE_AUTHOR("Willem Riede");
82 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
83 MODULE_LICENSE("GPL");
85 module_param(max_dev, int, 0);
86 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
88 module_param(write_threshold_kbs, int, 0);
89 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
91 module_param(max_sg_segs, int, 0);
92 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
94 static struct osst_dev_parm {
97 } parms[] __initdata = {
98 { "max_dev", &max_dev },
99 { "write_threshold_kbs", &write_threshold_kbs },
100 { "max_sg_segs", &max_sg_segs }
104 static char *osst_formats[ST_NBR_MODES] ={"", "l", "m", "a"};
106 /* Some default definitions have been moved to osst_options.h */
107 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
108 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
110 /* The buffer size should fit into the 24 bits for length in the
111 6-byte SCSI read and write commands. */
112 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
113 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
117 static int debugging = 1;
118 /* uncomment define below to test error recovery */
119 // #define OSST_INJECT_ERRORS 1
122 #define MAX_RETRIES 2
123 #define MAX_READ_RETRIES 0
124 #define MAX_WRITE_RETRIES 0
125 #define MAX_READY_RETRIES 0
126 #define NO_TAPE NOT_READY
128 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
129 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
130 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
132 #define OSST_TIMEOUT (200 * HZ)
133 #define OSST_LONG_TIMEOUT (1800 * HZ)
135 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
136 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
137 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
138 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
140 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
142 #define SET_DENS_AND_BLK 0x10001
144 static int osst_buffer_size = OSST_BUFFER_SIZE;
145 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
146 static int osst_max_sg_segs = OSST_MAX_SG;
147 static int osst_max_dev = OSST_MAX_TAPES;
148 static int osst_nr_dev;
150 static OS_Scsi_Tape **os_scsi_tapes = NULL;
151 static rwlock_t os_scsi_tapes_lock = RW_LOCK_UNLOCKED;
153 static int modes_defined = FALSE;
155 static OSST_buffer *new_tape_buffer(int, int, int);
156 static int enlarge_buffer(OSST_buffer *, int);
157 static void normalize_buffer(OSST_buffer *);
158 static int append_to_buffer(const char __user *, OSST_buffer *, int);
159 static int from_buffer(OSST_buffer *, char __user *, int);
160 static int osst_zero_buffer_tail(OSST_buffer *);
161 static int osst_copy_to_buffer(OSST_buffer *, unsigned char *);
162 static int osst_copy_from_buffer(OSST_buffer *, unsigned char *);
164 static int osst_probe(struct device *);
165 static int osst_remove(struct device *);
167 struct scsi_driver osst_template = {
168 .owner = THIS_MODULE,
172 .remove = osst_remove,
176 static int osst_int_ioctl(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, unsigned int cmd_in,unsigned long arg);
178 static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int frame, int skip);
180 static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt);
182 static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt);
184 static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending);
186 static inline char *tape_name(OS_Scsi_Tape *tape)
188 return tape->drive->disk_name;
191 /* Routines that handle the interaction with mid-layer SCSI routines */
193 /* Convert the result to success code */
194 static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt)
196 char *name = tape_name(STp);
197 int result = SRpnt->sr_result;
198 unsigned char * sense = SRpnt->sr_sense_buffer, scode;
204 sense[0] = 0; /* We don't have sense data if this byte is zero */
207 if ((driver_byte(result) & DRIVER_MASK) == DRIVER_SENSE)
208 scode = sense[2] & 0x0f;
210 sense[0] = 0; /* We don't have sense data if this byte is zero */
215 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
217 SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
218 SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
220 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
221 name, scode, sense[12], sense[13]);
222 if (driver_byte(result) & DRIVER_SENSE)
223 print_req_sense("osst ", SRpnt);
227 if (!(driver_byte(result) & DRIVER_SENSE) ||
228 ((sense[0] & 0x70) == 0x70 &&
230 scode != RECOVERED_ERROR &&
231 /* scode != UNIT_ATTENTION && */
232 scode != BLANK_CHECK &&
233 scode != VOLUME_OVERFLOW &&
234 SRpnt->sr_cmnd[0] != MODE_SENSE &&
235 SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
236 if (driver_byte(result) & DRIVER_SENSE) {
237 printk(KERN_WARNING "%s:W: Command with sense data: ", name);
238 print_req_sense("osst:", SRpnt);
241 static int notyetprinted = 1;
244 "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
245 name, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
250 "%s:I: This warning may be caused by your scsi controller,\n", name);
252 "%s:I: it has been reported with some Buslogic cards.\n", name);
256 STp->pos_unknown |= STp->device->was_reset;
258 if ((sense[0] & 0x70) == 0x70 &&
259 scode == RECOVERED_ERROR) {
260 STp->recover_count++;
261 STp->recover_erreg++;
264 if (SRpnt->sr_cmnd[0] == READ_6)
266 else if (SRpnt->sr_cmnd[0] == WRITE_6)
270 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
274 if ((sense[2] & 0xe0) == 0)
281 /* Wakeup from interrupt */
282 static void osst_sleep_done (Scsi_Cmnd * SCpnt)
284 OS_Scsi_Tape * STp = container_of(SCpnt->request->rq_disk->private_data, OS_Scsi_Tape, driver);
286 if ((STp->buffer)->writing &&
287 (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
288 (SCpnt->sense_buffer[2] & 0x40)) {
289 /* EOM at write-behind, has all been written? */
290 if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
291 STp->buffer->midlevel_result = SCpnt->result; /* Error */
293 STp->buffer->midlevel_result = INT_MAX; /* OK */
296 STp->buffer->midlevel_result = SCpnt->result;
297 SCpnt->request->rq_status = RQ_SCSI_DONE;
298 STp->buffer->last_SRpnt = SCpnt->sc_request;
301 STp->write_pending = 0;
303 complete(SCpnt->request->waiting);
307 /* Do the scsi command. Waits until command performed if do_wait is true.
308 Otherwise osst_write_behind_check() is used to check that the command
310 static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp,
311 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
314 #ifdef OSST_INJECT_ERRORS
315 static int inject = 0;
316 static int repeat = 0;
319 if ((SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC)) == NULL) {
320 printk(KERN_ERR "%s:E: Can't get SCSI request.\n", tape_name(STp));
321 if (signal_pending(current))
322 (STp->buffer)->syscall_result = (-EINTR);
324 (STp->buffer)->syscall_result = (-EBUSY);
329 init_completion(&STp->wait);
330 SRpnt->sr_use_sg = (bytes > (STp->buffer)->sg[0].length) ?
331 (STp->buffer)->use_sg : 0;
332 if (SRpnt->sr_use_sg) {
333 bp = (char *)&(STp->buffer->sg[0]);
334 if (STp->buffer->sg_segs < SRpnt->sr_use_sg)
335 SRpnt->sr_use_sg = STp->buffer->sg_segs;
338 bp = (STp->buffer)->b_data;
339 SRpnt->sr_data_direction = direction;
340 SRpnt->sr_cmd_len = 0;
341 SRpnt->sr_request->waiting = &(STp->wait);
342 SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
343 SRpnt->sr_request->rq_disk = STp->drive;
345 scsi_do_req(SRpnt, (void *)cmd, bp, bytes, osst_sleep_done, timeout, retries);
348 wait_for_completion(SRpnt->sr_request->waiting);
349 SRpnt->sr_request->waiting = NULL;
350 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
351 #ifdef OSST_INJECT_ERRORS
352 if (STp->buffer->syscall_result == 0 &&
355 ( (++ inject % 83) == 29 ||
356 (STp->first_frame_position == 240
357 /* or STp->read_error_frame to fail again on the block calculated above */ &&
359 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
360 STp->buffer->last_result_fatal = 1;
368 /* Handle the write-behind checking (downs the semaphore) */
369 static void osst_write_behind_check(OS_Scsi_Tape *STp)
371 OSST_buffer * STbuffer;
373 STbuffer = STp->buffer;
376 if (STp->write_pending)
381 wait_for_completion(&(STp->wait));
382 (STp->buffer)->last_SRpnt->sr_request->waiting = NULL;
384 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
386 if ((STp->buffer)->syscall_result)
387 (STp->buffer)->syscall_result =
388 osst_write_error_recovery(STp, &((STp->buffer)->last_SRpnt), 1);
390 STp->first_frame_position++;
392 scsi_release_request((STp->buffer)->last_SRpnt);
394 if (STbuffer->writing < STbuffer->buffer_bytes)
395 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
397 STbuffer->buffer_bytes -= STbuffer->writing;
398 STbuffer->writing = 0;
405 /* Onstream specific Routines */
407 * Initialize the OnStream AUX
409 static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int frame_seq_number,
410 int logical_blk_num, int blk_sz, int blk_cnt)
412 os_aux_t *aux = STp->buffer->aux;
413 os_partition_t *par = &aux->partition;
414 os_dat_t *dat = &aux->dat;
416 if (STp->raw) return;
418 memset(aux, 0, sizeof(*aux));
419 aux->format_id = htonl(0);
420 memcpy(aux->application_sig, "LIN4", 4);
421 aux->hdwr = htonl(0);
422 aux->frame_type = frame_type;
424 switch (frame_type) {
425 case OS_FRAME_TYPE_HEADER:
426 aux->update_frame_cntr = htonl(STp->update_frame_cntr);
427 par->partition_num = OS_CONFIG_PARTITION;
428 par->par_desc_ver = OS_PARTITION_VERSION;
429 par->wrt_pass_cntr = htons(0xffff);
430 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
431 par->first_frame_ppos = htonl(0);
432 par->last_frame_ppos = htonl(0xbb7);
433 aux->frame_seq_num = htonl(0);
434 aux->logical_blk_num_high = htonl(0);
435 aux->logical_blk_num = htonl(0);
436 aux->next_mark_ppos = htonl(STp->first_mark_ppos);
438 case OS_FRAME_TYPE_DATA:
439 case OS_FRAME_TYPE_MARKER:
444 dat->dat_list[0].blk_sz = htonl(blk_sz);
445 dat->dat_list[0].blk_cnt = htons(blk_cnt);
446 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
447 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
448 dat->dat_list[0].reserved = 0;
449 case OS_FRAME_TYPE_EOD:
450 aux->update_frame_cntr = htonl(0);
451 par->partition_num = OS_DATA_PARTITION;
452 par->par_desc_ver = OS_PARTITION_VERSION;
453 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
454 par->first_frame_ppos = htonl(STp->first_data_ppos);
455 par->last_frame_ppos = htonl(STp->capacity);
456 aux->frame_seq_num = htonl(frame_seq_number);
457 aux->logical_blk_num_high = htonl(0);
458 aux->logical_blk_num = htonl(logical_blk_num);
460 default: ; /* probably FILL */
462 aux->filemark_cnt = ntohl(STp->filemark_cnt);
463 aux->phys_fm = ntohl(0xffffffff);
464 aux->last_mark_ppos = ntohl(STp->last_mark_ppos);
465 aux->last_mark_lbn = ntohl(STp->last_mark_lbn);
469 * Verify that we have the correct tape frame
471 static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet)
473 char * name = tape_name(STp);
474 os_aux_t * aux = STp->buffer->aux;
475 os_partition_t * par = &(aux->partition);
476 struct st_partstat * STps = &(STp->ps[STp->partition]);
477 int blk_cnt, blk_sz, i;
480 if (STp->buffer->syscall_result) {
481 for (i=0; i < STp->buffer->sg_segs; i++)
482 memset(page_address(STp->buffer->sg[i].page),
483 0, STp->buffer->sg[i].length);
484 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
486 STp->buffer->buffer_bytes = OS_FRAME_SIZE;
489 if (STp->buffer->syscall_result) {
491 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
495 if (ntohl(aux->format_id) != 0) {
497 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
501 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
502 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
504 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
508 if (par->partition_num != OS_DATA_PARTITION) {
509 if (!STp->linux_media || STp->linux_media_version != 2) {
511 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
512 name, par->partition_num);
517 if (par->par_desc_ver != OS_PARTITION_VERSION) {
519 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
523 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
525 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
526 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
530 if (aux->frame_type != OS_FRAME_TYPE_DATA &&
531 aux->frame_type != OS_FRAME_TYPE_EOD &&
532 aux->frame_type != OS_FRAME_TYPE_MARKER) {
535 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
539 if (aux->frame_type == OS_FRAME_TYPE_EOD &&
540 STp->first_frame_position < STp->eod_frame_ppos) {
541 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
542 STp->first_frame_position);
545 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
548 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
549 name, ntohl(aux->frame_seq_num), frame_seq_number);
553 if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
554 STps->eof = ST_FM_HIT;
556 i = ntohl(aux->filemark_cnt);
557 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
558 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
560 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
561 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
562 i, STp->first_frame_position - 1);
564 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
565 if (i >= STp->filemark_cnt)
566 STp->filemark_cnt = i+1;
569 if (aux->frame_type == OS_FRAME_TYPE_EOD) {
570 STps->eof = ST_EOD_1;
571 STp->frame_in_buffer = 1;
573 if (aux->frame_type == OS_FRAME_TYPE_DATA) {
574 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
575 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
576 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
577 STp->buffer->read_pointer = 0;
578 STp->frame_in_buffer = 1;
580 /* See what block size was used to write file */
581 if (STp->block_size != blk_sz && blk_sz > 0) {
583 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
584 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
585 STp->block_size<1024?STp->block_size:STp->block_size/1024,
586 STp->block_size<1024?'b':'k');
587 STp->block_size = blk_sz;
588 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
590 STps->eof = ST_NOEOF;
592 STp->frame_seq_number = ntohl(aux->frame_seq_num);
593 STp->logical_blk_num = ntohl(aux->logical_blk_num);
597 if (STp->read_error_frame == 0)
598 STp->read_error_frame = STp->first_frame_position - 1;
603 * Wait for the unit to become Ready
605 static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout, int initial_delay)
607 unsigned char cmd[MAX_COMMAND_SIZE];
608 Scsi_Request * SRpnt;
609 unsigned long startwait = jiffies;
612 char * name = tape_name(STp);
614 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
617 if (initial_delay > 0)
618 msleep(jiffies_to_msecs(initial_delay));
620 memset(cmd, 0, MAX_COMMAND_SIZE);
621 cmd[0] = TEST_UNIT_READY;
623 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
625 if (!SRpnt) return (-EBUSY);
627 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
628 (( SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
629 (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8) ) ||
630 ( SRpnt->sr_sense_buffer[2] == 6 && SRpnt->sr_sense_buffer[12] == 0x28 &&
631 SRpnt->sr_sense_buffer[13] == 0 ) )) {
634 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
635 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
641 memset(cmd, 0, MAX_COMMAND_SIZE);
642 cmd[0] = TEST_UNIT_READY;
644 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
650 if ( STp->buffer->syscall_result &&
651 osst_write_error_recovery(STp, aSRpnt, 0) ) {
653 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
654 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
655 STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
656 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
661 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
667 * Wait for a tape to be inserted in the unit
669 static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout)
671 unsigned char cmd[MAX_COMMAND_SIZE];
672 Scsi_Request * SRpnt;
673 unsigned long startwait = jiffies;
676 char * name = tape_name(STp);
678 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
681 memset(cmd, 0, MAX_COMMAND_SIZE);
682 cmd[0] = TEST_UNIT_READY;
684 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
686 if (!SRpnt) return (-EBUSY);
688 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
689 SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 0x3a &&
690 SRpnt->sr_sense_buffer[13] == 0 ) {
693 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
694 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
700 memset(cmd, 0, MAX_COMMAND_SIZE);
701 cmd[0] = TEST_UNIT_READY;
703 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
709 if ( STp->buffer->syscall_result && SRpnt->sr_sense_buffer[2] != 2 &&
710 SRpnt->sr_sense_buffer[12] != 4 && SRpnt->sr_sense_buffer[13] == 1) {
712 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
713 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
714 STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
715 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
720 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
725 static int osst_position_tape_and_confirm(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame)
729 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
730 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
731 if (retval) return (retval);
732 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
733 return (osst_get_frame_position(STp, aSRpnt));
737 * Wait for write(s) to complete
739 static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
741 unsigned char cmd[MAX_COMMAND_SIZE];
742 Scsi_Request * SRpnt;
745 int delay = OSST_WAIT_WRITE_COMPLETE;
747 char * name = tape_name(STp);
749 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
752 memset(cmd, 0, MAX_COMMAND_SIZE);
753 cmd[0] = WRITE_FILEMARKS;
756 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_WRITE_RETRIES, TRUE);
758 if (!SRpnt) return (-EBUSY);
759 if (STp->buffer->syscall_result) {
760 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == 2 && SRpnt->sr_sense_buffer[12] == 4) {
761 if (SRpnt->sr_sense_buffer[13] == 8) {
762 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
765 result = osst_write_error_recovery(STp, aSRpnt, 0);
767 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
768 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
773 #define OSST_POLL_PER_SEC 10
774 static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, int minlast, int to)
776 unsigned long startwait = jiffies;
777 char * name = tape_name(STp);
779 char notyetprinted = 1;
781 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
782 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
784 while (time_before (jiffies, startwait + to*HZ))
787 result = osst_get_frame_position (STp, aSRpnt);
789 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
790 return 0; /* successful recovery leaves drive ready for frame */
791 if (result < 0) break;
792 if (STp->first_frame_position == curr &&
794 (signed)STp->last_frame_position > (signed)curr + minlast) ||
795 (minlast >= 0 && STp->cur_frames > minlast)
799 if (debugging || jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC)
801 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
802 name, curr, curr+minlast, STp->first_frame_position,
803 STp->last_frame_position, STp->cur_frames,
804 result, (jiffies-startwait)/HZ,
805 (((jiffies-startwait)%HZ)*10)/HZ);
810 if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted)
812 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
813 name, curr, curr+minlast, STp->first_frame_position,
814 STp->last_frame_position, STp->cur_frames, result);
818 msleep(1000 / OSST_POLL_PER_SEC);
821 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
822 name, curr, curr+minlast, STp->first_frame_position,
823 STp->last_frame_position, STp->cur_frames,
824 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
830 * Read the next OnStream tape frame at the current location
832 static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeout)
834 unsigned char cmd[MAX_COMMAND_SIZE];
835 Scsi_Request * SRpnt;
838 os_aux_t * aux = STp->buffer->aux;
839 char * name = tape_name(STp);
842 /* TODO: Error handling */
844 retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout);
846 memset(cmd, 0, MAX_COMMAND_SIZE);
853 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
855 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
856 STp->timeout, MAX_READ_RETRIES, TRUE);
861 if ((STp->buffer)->syscall_result) {
863 if (STp->read_error_frame == 0) {
864 STp->read_error_frame = STp->first_frame_position;
866 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
871 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
873 SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],
874 SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],
875 SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5],
876 SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7]);
880 STp->first_frame_position++;
885 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
888 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
889 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
890 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
891 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
892 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
893 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
894 if (aux->frame_type==2)
895 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
896 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
897 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
903 static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
905 struct st_partstat * STps = &(STp->ps[STp->partition]);
906 Scsi_Request * SRpnt ;
907 unsigned char cmd[MAX_COMMAND_SIZE];
910 char * name = tape_name(STp);
913 if (STps->rw != ST_READING) { /* Initialize read operation */
914 if (STps->rw == ST_WRITING || STp->dirty) {
915 STp->write_type = OS_WRITE_DATA;
916 osst_flush_write_buffer(STp, aSRpnt);
917 osst_flush_drive_buffer(STp, aSRpnt);
919 STps->rw = ST_READING;
920 STp->frame_in_buffer = 0;
923 * Issue a read 0 command to get the OnStream drive
924 * read frames into its buffer.
926 memset(cmd, 0, MAX_COMMAND_SIZE);
931 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
933 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READ_RETRIES, TRUE);
935 retval = STp->buffer->syscall_result;
941 static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame_seq_number, int quiet)
943 struct st_partstat * STps = &(STp->ps[STp->partition]);
944 char * name = tape_name(STp);
952 * If we want just any frame (-1) and there is a frame in the buffer, return it
954 if (frame_seq_number == -1 && STp->frame_in_buffer) {
956 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
961 * Search and wait for the next logical tape frame
965 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
966 name, frame_seq_number);
967 if (STp->read_error_frame) {
968 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
970 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
971 name, STp->read_error_frame);
973 STp->read_error_frame = 0;
979 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
980 name, frame_seq_number, cnt);
982 if ( osst_initiate_read(STp, aSRpnt)
983 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
986 position = osst_get_frame_position(STp, aSRpnt);
987 if (position >= 0xbae && position < 0xbb8)
989 else if (position > STp->eod_frame_ppos || ++bad == 10) {
990 position = STp->read_error_frame - 1;
997 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1000 osst_set_frame_position(STp, aSRpnt, position, 0);
1003 if (osst_verify_frame(STp, frame_seq_number, quiet))
1005 if (osst_verify_frame(STp, -1, quiet)) {
1006 x = ntohl(STp->buffer->aux->frame_seq_num);
1007 if (STp->fast_open) {
1009 "%s:W: Found logical frame %d instead of %d after fast open\n",
1010 name, x, frame_seq_number);
1012 STp->read_error_frame = 0;
1015 if (x > frame_seq_number) {
1017 /* positioning backwards did not bring us to the desired frame */
1018 position = STp->read_error_frame - 1;
1021 position = osst_get_frame_position(STp, aSRpnt)
1022 + frame_seq_number - x - 1;
1024 if (STp->first_frame_position >= 3000 && position < 3000)
1029 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1030 name, x, frame_seq_number,
1031 STp->first_frame_position - position);
1033 osst_set_frame_position(STp, aSRpnt, position, 0);
1039 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1041 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1043 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1046 STp->frame_in_buffer = 0;
1049 STp->recover_count++;
1050 STp->recover_erreg++;
1051 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1052 name, STp->read_error_frame);
1057 if (debugging || STps->eof)
1059 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1060 name, frame_seq_number, STp->frame_seq_number, STps->eof);
1062 STp->fast_open = FALSE;
1063 STp->read_error_frame = 0;
1067 static int osst_seek_logical_blk(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int logical_blk_num)
1069 struct st_partstat * STps = &(STp->ps[STp->partition]);
1070 char * name = tape_name(STp);
1072 int frame_seq_estimate, ppos_estimate, move;
1074 if (logical_blk_num < 0) logical_blk_num = 0;
1076 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1077 name, logical_blk_num, STp->logical_blk_num,
1078 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1079 STp->block_size<1024?'b':'k');
1081 /* Do we know where we are? */
1082 if (STps->drv_block >= 0) {
1083 move = logical_blk_num - STp->logical_blk_num;
1084 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1085 move /= (OS_DATA_SIZE / STp->block_size);
1086 frame_seq_estimate = STp->frame_seq_number + move;
1088 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1090 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1091 else ppos_estimate = frame_seq_estimate + 20;
1092 while (++retries < 10) {
1093 if (ppos_estimate > STp->eod_frame_ppos-2) {
1094 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1095 ppos_estimate = STp->eod_frame_ppos - 2;
1097 if (frame_seq_estimate < 0) {
1098 frame_seq_estimate = 0;
1101 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1102 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1103 /* we've located the estimated frame, now does it have our block? */
1104 if (logical_blk_num < STp->logical_blk_num ||
1105 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1106 if (STps->eof == ST_FM_HIT)
1107 move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1109 move = logical_blk_num - STp->logical_blk_num;
1110 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1111 move /= (OS_DATA_SIZE / STp->block_size);
1113 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1116 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1117 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1118 STp->logical_blk_num, logical_blk_num, move);
1120 frame_seq_estimate += move;
1121 ppos_estimate += move;
1124 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1125 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1126 STp->logical_blk_num = logical_blk_num;
1129 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1130 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1131 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1134 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1135 if (STps->eof == ST_FM_HIT) {
1137 STps->drv_block = 0;
1139 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1140 STp->logical_blk_num -
1141 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1144 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1148 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1150 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1152 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1153 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1154 STp->logical_blk_num, logical_blk_num);
1156 if (frame_seq_estimate != STp->frame_seq_number)
1157 ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1162 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1163 name, logical_blk_num, STp->logical_blk_num, retries);
1167 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1168 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1169 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1170 * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1172 #define OSST_FRAME_SHIFT 6
1173 #define OSST_SECTOR_SHIFT 9
1174 #define OSST_SECTOR_MASK 0x03F
1176 static int osst_get_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
1180 char * name = tape_name(STp);
1183 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1184 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1185 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1186 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1187 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1188 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1190 /* do we know where we are inside a file? */
1191 if (STp->ps[STp->partition].drv_block >= 0) {
1192 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1193 STp->first_frame_position) << OSST_FRAME_SHIFT;
1194 if (STp->ps[STp->partition].rw == ST_WRITING)
1195 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1197 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1199 sector = osst_get_frame_position(STp, aSRpnt);
1201 sector <<= OSST_FRAME_SHIFT;
1206 static int osst_seek_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sector)
1208 struct st_partstat * STps = &(STp->ps[STp->partition]);
1209 int frame = sector >> OSST_FRAME_SHIFT,
1210 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1213 char * name = tape_name(STp);
1215 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1216 name, sector, frame, offset);
1218 if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1220 if (frame <= STp->first_data_ppos) {
1221 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1222 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1224 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1225 if (r < 0) return r;
1227 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1228 if (r < 0) return r;
1230 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1233 STp->logical_blk_num += offset / STp->block_size;
1234 STp->buffer->read_pointer = offset;
1235 STp->buffer->buffer_bytes -= offset;
1237 STp->frame_seq_number++;
1238 STp->frame_in_buffer = 0;
1239 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1240 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1242 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1243 if (STps->eof == ST_FM_HIT) {
1245 STps->drv_block = 0;
1247 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1248 STp->logical_blk_num -
1249 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1252 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1255 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1256 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1257 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1263 * Read back the drive's internal buffer contents, as a part
1264 * of the write error recovery mechanism for old OnStream
1265 * firmware revisions.
1266 * Precondition for this function to work: all frames in the
1267 * drive's buffer must be of one type (DATA, MARK or EOD)!
1269 static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
1270 unsigned int frame, unsigned int skip, int pending)
1272 Scsi_Request * SRpnt = * aSRpnt;
1273 unsigned char * buffer, * p;
1274 unsigned char cmd[MAX_COMMAND_SIZE];
1275 int flag, new_frame, i;
1276 int nframes = STp->cur_frames;
1277 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1278 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1279 - (nframes + pending - 1);
1280 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1281 - (nframes + pending - 1) * blks_per_frame;
1282 char * name = tape_name(STp);
1283 unsigned long startwait = jiffies;
1285 int dbg = debugging;
1288 if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
1291 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1292 name, nframes, pending?" and one that was pending":"");
1294 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1296 if (pending && debugging)
1297 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1298 name, frame_seq_number + nframes,
1299 logical_blk_num + nframes * blks_per_frame,
1300 p[0], p[1], p[2], p[3]);
1302 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1304 memset(cmd, 0, MAX_COMMAND_SIZE);
1305 cmd[0] = 0x3C; /* Buffer Read */
1306 cmd[1] = 6; /* Retrieve Faulty Block */
1307 cmd[7] = 32768 >> 8;
1308 cmd[8] = 32768 & 0xff;
1310 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
1311 STp->timeout, MAX_READ_RETRIES, TRUE);
1313 if ((STp->buffer)->syscall_result || !SRpnt) {
1314 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1315 vfree((void *)buffer);
1319 osst_copy_from_buffer(STp->buffer, p);
1322 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1323 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1327 osst_get_frame_position(STp, aSRpnt);
1330 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1332 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1333 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1335 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1338 if (STp->write_type == OS_WRITE_HEADER) {
1340 p += skip * OS_DATA_SIZE;
1342 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1347 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1348 name, new_frame+i, frame_seq_number+i);
1350 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1351 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1352 osst_get_frame_position(STp, aSRpnt);
1355 if (new_frame > frame + 1000) {
1356 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1357 vfree((void *)buffer);
1361 if ( i >= nframes + pending ) break;
1363 osst_copy_to_buffer(STp->buffer, p);
1365 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1367 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1368 logical_blk_num + i*blks_per_frame,
1369 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1370 memset(cmd, 0, MAX_COMMAND_SIZE);
1378 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1379 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1380 p[0], p[1], p[2], p[3]);
1382 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
1383 STp->timeout, MAX_WRITE_RETRIES, TRUE);
1385 if (STp->buffer->syscall_result)
1388 p += OS_DATA_SIZE; i++;
1390 /* if we just sent the last frame, wait till all successfully written */
1391 if ( i == nframes + pending ) {
1393 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1395 memset(cmd, 0, MAX_COMMAND_SIZE);
1396 cmd[0] = WRITE_FILEMARKS;
1398 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
1399 STp->timeout, MAX_WRITE_RETRIES, TRUE);
1402 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1403 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1407 flag = STp->buffer->syscall_result;
1408 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1410 memset(cmd, 0, MAX_COMMAND_SIZE);
1411 cmd[0] = TEST_UNIT_READY;
1413 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout,
1414 MAX_READY_RETRIES, TRUE);
1416 if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
1417 (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) {
1418 /* in the process of becoming ready */
1422 if (STp->buffer->syscall_result)
1428 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1434 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
1435 SRpnt->sr_sense_buffer[12] == 0 &&
1436 SRpnt->sr_sense_buffer[13] == 2) {
1437 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1438 vfree((void *)buffer);
1439 return (-EIO); /* hit end of tape = fail */
1441 i = ((SRpnt->sr_sense_buffer[3] << 24) |
1442 (SRpnt->sr_sense_buffer[4] << 16) |
1443 (SRpnt->sr_sense_buffer[5] << 8) |
1444 SRpnt->sr_sense_buffer[6] ) - new_frame;
1445 p = &buffer[i * OS_DATA_SIZE];
1447 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1449 osst_get_frame_position(STp, aSRpnt);
1451 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1452 name, STp->first_frame_position, STp->last_frame_position);
1457 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1458 vfree((void *)buffer);
1462 static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
1463 unsigned int frame, unsigned int skip, int pending)
1465 unsigned char cmd[MAX_COMMAND_SIZE];
1466 Scsi_Request * SRpnt;
1467 char * name = tape_name(STp);
1469 int attempts = 1000 / skip;
1471 unsigned long startwait = jiffies;
1473 int dbg = debugging;
1476 while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1481 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1483 expected = frame+skip+STp->cur_frames+pending;
1485 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1486 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1488 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1491 set_current_state(TASK_INTERRUPTIBLE);
1492 schedule_timeout(HZ / 10);
1494 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1496 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1497 name, STp->first_frame_position,
1498 STp->last_frame_position, STp->cur_frames);
1500 frame = STp->last_frame_position;
1504 if (pending && STp->cur_frames < 50) {
1506 memset(cmd, 0, MAX_COMMAND_SIZE);
1511 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1512 name, STp->frame_seq_number-1, STp->first_frame_position);
1514 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
1515 STp->timeout, MAX_WRITE_RETRIES, TRUE);
1518 if (STp->buffer->syscall_result) { /* additional write error */
1519 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
1520 SRpnt->sr_sense_buffer[12] == 0 &&
1521 SRpnt->sr_sense_buffer[13] == 2) {
1523 "%s:E: Volume overflow in write error recovery\n",
1525 break; /* hit end of tape = fail */
1534 if (STp->cur_frames == 0) {
1537 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1539 if (STp->first_frame_position != expected) {
1540 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1541 name, STp->first_frame_position, expected);
1548 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1549 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1553 schedule_timeout(HZ / 10);
1555 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1563 * Error recovery algorithm for the OnStream tape.
1566 static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending)
1568 Scsi_Request * SRpnt = * aSRpnt;
1569 struct st_partstat * STps = & STp->ps[STp->partition];
1570 char * name = tape_name(STp);
1573 unsigned int frame, skip;
1575 rw_state = STps->rw;
1577 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) != 3
1578 || SRpnt->sr_sense_buffer[12] != 12
1579 || SRpnt->sr_sense_buffer[13] != 0) {
1581 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1582 SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
1586 frame = (SRpnt->sr_sense_buffer[3] << 24) |
1587 (SRpnt->sr_sense_buffer[4] << 16) |
1588 (SRpnt->sr_sense_buffer[5] << 8) |
1589 SRpnt->sr_sense_buffer[6];
1590 skip = SRpnt->sr_sense_buffer[9];
1593 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1595 osst_get_frame_position(STp, aSRpnt);
1597 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1598 name, STp->first_frame_position, STp->last_frame_position);
1600 switch (STp->write_type) {
1603 case OS_WRITE_NEW_MARK:
1605 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1606 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1607 if (STp->os_fw_rev >= 10600)
1608 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1610 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1611 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1613 retval?"" :"Don't worry, ",
1614 retval?" not ":" ");
1616 case OS_WRITE_LAST_MARK:
1617 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1618 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1621 case OS_WRITE_HEADER:
1622 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1623 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1626 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1627 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1629 osst_get_frame_position(STp, aSRpnt);
1631 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1632 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1633 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1636 STp->recover_count++;
1637 STp->recover_erreg++;
1639 STps->rw = rw_state;
1643 static int osst_space_over_filemarks_backward(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
1644 int mt_op, int mt_count)
1646 char * name = tape_name(STp);
1648 int last_mark_ppos = -1;
1651 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1653 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1655 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1659 if (STp->linux_media_version >= 4) {
1661 * direct lookup in header filemark list
1663 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1664 if (STp->header_ok &&
1665 STp->header_cache != NULL &&
1666 (cnt - mt_count) >= 0 &&
1667 (cnt - mt_count) < OS_FM_TAB_MAX &&
1668 (cnt - mt_count) < STp->filemark_cnt &&
1669 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1671 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1673 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1674 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1675 STp->header_cache == NULL?"lack of header cache":"count out of range");
1677 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1679 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1680 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1681 STp->buffer->aux->last_mark_ppos))?"match":"error",
1682 mt_count, last_mark_ppos);
1684 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1685 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1686 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1689 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1693 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1694 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1695 name, last_mark_ppos);
1701 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1705 while (cnt != mt_count) {
1706 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1707 if (last_mark_ppos == -1)
1710 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1712 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1714 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1716 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1720 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1721 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1722 name, last_mark_ppos);
1727 if (mt_op == MTBSFM) {
1728 STp->frame_seq_number++;
1729 STp->frame_in_buffer = 0;
1730 STp->buffer->buffer_bytes = 0;
1731 STp->buffer->read_pointer = 0;
1732 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1738 * ADRL 1.1 compatible "slow" space filemarks fwd version
1740 * Just scans for the filemark sequentially.
1742 static int osst_space_over_filemarks_forward_slow(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
1743 int mt_op, int mt_count)
1747 char * name = tape_name(STp);
1749 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1751 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1753 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1758 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1760 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1764 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1766 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1768 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1770 if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1772 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1773 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1775 STp->eod_frame_ppos = STp->first_frame_position-1;
1779 if (cnt == mt_count)
1781 STp->frame_in_buffer = 0;
1783 if (mt_op == MTFSF) {
1784 STp->frame_seq_number++;
1785 STp->frame_in_buffer = 0;
1786 STp->buffer->buffer_bytes = 0;
1787 STp->buffer->read_pointer = 0;
1788 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1794 * Fast linux specific version of OnStream FSF
1796 static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
1797 int mt_op, int mt_count)
1799 char * name = tape_name(STp);
1801 next_mark_ppos = -1;
1804 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
1806 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1808 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1813 if (STp->linux_media_version >= 4) {
1815 * direct lookup in header filemark list
1817 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
1818 if (STp->header_ok &&
1819 STp->header_cache != NULL &&
1820 (cnt + mt_count) < OS_FM_TAB_MAX &&
1821 (cnt + mt_count) < STp->filemark_cnt &&
1822 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1823 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
1825 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
1827 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
1828 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1829 STp->header_cache == NULL?"lack of header cache":"count out of range");
1831 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1833 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1834 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
1835 STp->buffer->aux->last_mark_ppos))?"match":"error",
1836 mt_count, next_mark_ppos);
1838 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
1840 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1842 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1844 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
1845 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1847 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
1852 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1853 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1854 name, next_mark_ppos);
1857 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
1858 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
1859 name, cnt+mt_count, next_mark_ppos,
1860 ntohl(STp->buffer->aux->filemark_cnt));
1866 * Find nearest (usually previous) marker, then jump from marker to marker
1869 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1871 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1873 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1877 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
1878 if (STp->first_mark_ppos == -1) {
1880 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1882 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1884 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
1885 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1888 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
1893 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1894 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
1895 name, STp->first_mark_ppos);
1899 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
1905 while (cnt != mt_count) {
1906 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
1907 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
1909 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1911 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
1914 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
1916 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
1918 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1920 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
1925 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1926 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1927 name, next_mark_ppos);
1932 if (mt_op == MTFSF) {
1933 STp->frame_seq_number++;
1934 STp->frame_in_buffer = 0;
1935 STp->buffer->buffer_bytes = 0;
1936 STp->buffer->read_pointer = 0;
1937 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1943 * In debug mode, we want to see as many errors as possible
1944 * to test the error recovery mechanism.
1947 static void osst_set_retries(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int retries)
1949 unsigned char cmd[MAX_COMMAND_SIZE];
1950 Scsi_Request * SRpnt = * aSRpnt;
1951 char * name = tape_name(STp);
1953 memset(cmd, 0, MAX_COMMAND_SIZE);
1954 cmd[0] = MODE_SELECT;
1956 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
1958 (STp->buffer)->b_data[0] = cmd[4] - 1;
1959 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
1960 (STp->buffer)->b_data[2] = 0; /* Reserved */
1961 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
1962 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
1963 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
1964 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
1965 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
1968 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
1970 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
1973 if ((STp->buffer)->syscall_result)
1974 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
1979 static int osst_write_filemark(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
1982 int this_mark_ppos = STp->first_frame_position;
1983 int this_mark_lbn = STp->logical_blk_num;
1985 char * name = tape_name(STp);
1988 if (STp->raw) return 0;
1990 STp->write_type = OS_WRITE_NEW_MARK;
1992 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
1993 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
1996 result = osst_flush_write_buffer(STp, aSRpnt);
1997 result |= osst_flush_drive_buffer(STp, aSRpnt);
1998 STp->last_mark_ppos = this_mark_ppos;
1999 STp->last_mark_lbn = this_mark_lbn;
2000 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2001 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2002 if (STp->filemark_cnt++ == 0)
2003 STp->first_mark_ppos = this_mark_ppos;
2007 static int osst_write_eod(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
2011 char * name = tape_name(STp);
2014 if (STp->raw) return 0;
2016 STp->write_type = OS_WRITE_EOD;
2017 STp->eod_frame_ppos = STp->first_frame_position;
2019 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2020 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2024 result = osst_flush_write_buffer(STp, aSRpnt);
2025 result |= osst_flush_drive_buffer(STp, aSRpnt);
2026 STp->eod_frame_lfa = --(STp->frame_seq_number);
2030 static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
2032 char * name = tape_name(STp);
2035 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2037 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2038 osst_set_frame_position(STp, aSRpnt, where, 0);
2039 STp->write_type = OS_WRITE_FILLER;
2041 memcpy(STp->buffer->b_data, "Filler", 6);
2042 STp->buffer->buffer_bytes = 6;
2044 if (osst_flush_write_buffer(STp, aSRpnt)) {
2045 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2050 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2052 return osst_flush_drive_buffer(STp, aSRpnt);
2055 static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
2057 char * name = tape_name(STp);
2061 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2063 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2064 osst_set_frame_position(STp, aSRpnt, where, 0);
2065 STp->write_type = OS_WRITE_HEADER;
2067 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2068 STp->buffer->buffer_bytes = sizeof(os_header_t);
2070 if (osst_flush_write_buffer(STp, aSRpnt)) {
2071 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2075 result = osst_flush_drive_buffer(STp, aSRpnt);
2077 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2082 static int osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int locate_eod)
2084 os_header_t * header;
2086 char * name = tape_name(STp);
2089 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2091 if (STp->raw) return 0;
2093 if (STp->header_cache == NULL) {
2094 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2095 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2098 memset(STp->header_cache, 0, sizeof(os_header_t));
2100 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2103 if (STp->header_ok) STp->update_frame_cntr++;
2104 else STp->update_frame_cntr = 0;
2106 header = STp->header_cache;
2107 strcpy(header->ident_str, "ADR_SEQ");
2108 header->major_rev = 1;
2109 header->minor_rev = 4;
2110 header->ext_trk_tb_off = htons(17192);
2111 header->pt_par_num = 1;
2112 header->partition[0].partition_num = OS_DATA_PARTITION;
2113 header->partition[0].par_desc_ver = OS_PARTITION_VERSION;
2114 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2115 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2116 header->partition[0].last_frame_ppos = htonl(STp->capacity);
2117 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2118 header->cfg_col_width = htonl(20);
2119 header->dat_col_width = htonl(1500);
2120 header->qfa_col_width = htonl(0);
2121 header->ext_track_tb.nr_stream_part = 1;
2122 header->ext_track_tb.et_ent_sz = 32;
2123 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2124 header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2125 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2126 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2127 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa);
2128 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
2129 header->dat_fm_tab.fm_part_num = 0;
2130 header->dat_fm_tab.fm_tab_ent_sz = 4;
2131 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2132 STp->filemark_cnt:OS_FM_TAB_MAX);
2134 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2135 if (STp->update_frame_cntr == 0)
2136 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2137 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2141 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2143 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2146 printk(KERN_ERR "%s:E: Write header failed\n", name);
2148 memcpy(STp->application_sig, "LIN4", 4);
2149 STp->linux_media = 1;
2150 STp->linux_media_version = 4;
2156 static int osst_reset_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
2158 if (STp->header_cache != NULL)
2159 memset(STp->header_cache, 0, sizeof(os_header_t));
2161 STp->logical_blk_num = STp->frame_seq_number = 0;
2162 STp->frame_in_buffer = 0;
2163 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2164 STp->filemark_cnt = 0;
2165 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2166 return osst_write_header(STp, aSRpnt, 1);
2169 static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int ppos)
2171 char * name = tape_name(STp);
2172 os_header_t * header;
2175 int linux_media_version,
2181 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2182 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2183 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2184 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2185 if (osst_initiate_read (STp, aSRpnt)) {
2186 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2190 if (osst_read_frame(STp, aSRpnt, 180)) {
2192 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2196 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2197 aux = STp->buffer->aux;
2198 if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2200 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2204 if (ntohl(aux->frame_seq_num) != 0 ||
2205 ntohl(aux->logical_blk_num) != 0 ||
2206 aux->partition.partition_num != OS_CONFIG_PARTITION ||
2207 ntohl(aux->partition.first_frame_ppos) != 0 ||
2208 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2210 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2211 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2212 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2213 ntohl(aux->partition.last_frame_ppos));
2217 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2218 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2219 strlcpy(id_string, header->ident_str, 8);
2221 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2225 update_frame_cntr = ntohl(aux->update_frame_cntr);
2226 if (update_frame_cntr < STp->update_frame_cntr) {
2228 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2229 name, ppos, update_frame_cntr, STp->update_frame_cntr);
2233 if (header->major_rev != 1 || header->minor_rev != 4 ) {
2235 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2236 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2237 header->minor_rev > 4 )? "Invalid" : "Warning:",
2238 header->major_rev, header->minor_rev);
2240 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2244 if (header->pt_par_num != 1)
2245 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2246 name, header->pt_par_num);
2248 memcpy(id_string, aux->application_sig, 4);
2250 if (memcmp(id_string, "LIN", 3) == 0) {
2251 STp->linux_media = 1;
2252 linux_media_version = id_string[3] - '0';
2253 if (linux_media_version != 4)
2254 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2255 name, linux_media_version);
2257 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2260 if (linux_media_version < STp->linux_media_version) {
2262 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2263 name, ppos, linux_media_version);
2267 if (linux_media_version > STp->linux_media_version) {
2269 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2270 name, ppos, linux_media_version);
2272 memcpy(STp->application_sig, id_string, 5);
2273 STp->linux_media_version = linux_media_version;
2274 STp->update_frame_cntr = -1;
2276 if (update_frame_cntr > STp->update_frame_cntr) {
2278 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2279 name, ppos, update_frame_cntr);
2281 if (STp->header_cache == NULL) {
2282 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2283 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2287 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2290 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2291 header = STp->header_cache; /* further accesses from cached (full) copy */
2293 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2294 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2295 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2296 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2297 STp->filemark_cnt = ntohl(aux->filemark_cnt);
2298 STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2299 STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2300 STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2301 STp->update_frame_cntr = update_frame_cntr;
2303 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2304 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2305 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2306 STp->first_data_ppos,
2307 ntohl(header->partition[0].last_frame_ppos),
2308 ntohl(header->partition[0].eod_frame_ppos));
2309 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2310 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2312 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2314 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2316 memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2317 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2318 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2320 if (header->minor_rev == 4 &&
2321 (header->ext_trk_tb_off != htons(17192) ||
2322 header->partition[0].partition_num != OS_DATA_PARTITION ||
2323 header->partition[0].par_desc_ver != OS_PARTITION_VERSION ||
2324 header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2325 header->cfg_col_width != htonl(20) ||
2326 header->dat_col_width != htonl(1500) ||
2327 header->qfa_col_width != htonl(0) ||
2328 header->ext_track_tb.nr_stream_part != 1 ||
2329 header->ext_track_tb.et_ent_sz != 32 ||
2330 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION ||
2331 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2332 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2333 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2334 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) ||
2335 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION ||
2336 header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2337 header->dat_fm_tab.fm_tab_ent_cnt !=
2338 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2339 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2346 static int osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
2351 char * name = tape_name(STp);
2353 position = osst_get_frame_position(STp, aSRpnt);
2356 STp->header_ok = STp->linux_media = 1;
2357 STp->linux_media_version = 0;
2360 STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2361 STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2362 STp->eod_frame_ppos = STp->first_data_ppos = -1;
2363 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2365 printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2368 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2369 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2371 first = position==10?0xbae: 5;
2372 last = position==10?0xbb3:10;
2374 for (ppos = first; ppos < last; ppos++)
2375 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2378 first = position==10? 5:0xbae;
2379 last = position==10?10:0xbb3;
2381 for (ppos = first; ppos < last; ppos++)
2382 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2386 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2387 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2388 osst_set_frame_position(STp, aSRpnt, 10, 0);
2391 if (position <= STp->first_data_ppos) {
2392 position = STp->first_data_ppos;
2393 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2395 osst_set_frame_position(STp, aSRpnt, position, 0);
2401 static int osst_verify_position(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
2403 int frame_position = STp->first_frame_position;
2404 int frame_seq_numbr = STp->frame_seq_number;
2405 int logical_blk_num = STp->logical_blk_num;
2406 int halfway_frame = STp->frame_in_buffer;
2407 int read_pointer = STp->buffer->read_pointer;
2408 int prev_mark_ppos = -1;
2409 int actual_mark_ppos, i, n;
2411 char * name = tape_name(STp);
2413 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2415 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2416 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2418 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2422 if (STp->linux_media_version >= 4) {
2423 for (i=0; i<STp->filemark_cnt; i++)
2424 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2427 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2428 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2429 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2430 if (frame_position != STp->first_frame_position ||
2431 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2432 prev_mark_ppos != actual_mark_ppos ) {
2434 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2435 STp->first_frame_position, frame_position,
2436 STp->frame_seq_number + (halfway_frame?0:1),
2437 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2441 if (halfway_frame) {
2442 /* prepare buffer for append and rewrite on top of original */
2443 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2444 STp->buffer->buffer_bytes = read_pointer;
2445 STp->ps[STp->partition].rw = ST_WRITING;
2448 STp->frame_in_buffer = halfway_frame;
2449 STp->frame_seq_number = frame_seq_numbr;
2450 STp->logical_blk_num = logical_blk_num;
2454 /* Acc. to OnStream, the vers. numbering is the following:
2455 * X.XX for released versions (X=digit),
2456 * XXXY for unreleased versions (Y=letter)
2457 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2458 * This fn makes monoton numbers out of this scheme ...
2460 static unsigned int osst_parse_firmware_rev (const char * str)
2462 if (str[1] == '.') {
2463 return (str[0]-'0')*10000
2467 return (str[0]-'0')*10000
2469 +(str[2]-'0')*100 - 100
2475 * Configure the OnStream SCII tape drive for default operation
2477 static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
2479 unsigned char cmd[MAX_COMMAND_SIZE];
2480 char * name = tape_name(STp);
2481 Scsi_Request * SRpnt = * aSRpnt;
2482 osst_mode_parameter_header_t * header;
2483 osst_block_size_page_t * bs;
2484 osst_capabilities_page_t * cp;
2485 osst_tape_paramtr_page_t * prm;
2486 int drive_buffer_size;
2488 if (STp->ready != ST_READY) {
2490 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2495 if (STp->os_fw_rev < 10600) {
2496 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2497 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2501 * Configure 32.5KB (data+aux) frame size.
2502 * Get the current frame size from the block size mode page
2504 memset(cmd, 0, MAX_COMMAND_SIZE);
2505 cmd[0] = MODE_SENSE;
2507 cmd[2] = BLOCK_SIZE_PAGE;
2508 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2510 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
2511 if (SRpnt == NULL) {
2513 printk(OSST_DEB_MSG "osst :D: Busy\n");
2518 if ((STp->buffer)->syscall_result != 0) {
2519 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2523 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2524 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2527 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2528 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No");
2529 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2530 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2534 * Configure default auto columns mode, 32.5KB transfer mode
2542 memset(cmd, 0, MAX_COMMAND_SIZE);
2543 cmd[0] = MODE_SELECT;
2545 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2547 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
2549 if ((STp->buffer)->syscall_result != 0) {
2550 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2555 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2557 * In debug mode, we want to see as many errors as possible
2558 * to test the error recovery mechanism.
2560 osst_set_retries(STp, aSRpnt, 0);
2565 * Set vendor name to 'LIN4' for "Linux support version 4".
2568 memset(cmd, 0, MAX_COMMAND_SIZE);
2569 cmd[0] = MODE_SELECT;
2571 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2573 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2574 header->medium_type = 0; /* Medium Type - ignoring */
2575 header->dsp = 0; /* Reserved */
2576 header->bdl = 0; /* Block Descriptor Length */
2578 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2579 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2580 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2581 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2582 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2583 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2584 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2585 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2587 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
2590 if ((STp->buffer)->syscall_result != 0) {
2591 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2592 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2596 memset(cmd, 0, MAX_COMMAND_SIZE);
2597 cmd[0] = MODE_SENSE;
2599 cmd[2] = CAPABILITIES_PAGE;
2600 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2602 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
2605 if ((STp->buffer)->syscall_result != 0) {
2606 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2610 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2611 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2612 sizeof(osst_mode_parameter_header_t) + header->bdl);
2614 drive_buffer_size = ntohs(cp->buffer_size) / 2;
2616 memset(cmd, 0, MAX_COMMAND_SIZE);
2617 cmd[0] = MODE_SENSE;
2619 cmd[2] = TAPE_PARAMTR_PAGE;
2620 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2622 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
2625 if ((STp->buffer)->syscall_result != 0) {
2626 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2630 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2631 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2632 sizeof(osst_mode_parameter_header_t) + header->bdl);
2634 STp->density = prm->density;
2635 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2637 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2638 name, STp->density, STp->capacity / 32, drive_buffer_size);
2646 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2647 it messes up the block number). */
2648 static int cross_eof(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int forward)
2651 char * name = tape_name(STp);
2655 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2656 name, forward ? "forward" : "backward");
2660 /* assumes that the filemark is already read by the drive, so this is low cost */
2661 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2664 /* assumes this is only called if we just read the filemark! */
2665 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2668 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2669 name, forward ? "forward" : "backward");
2675 /* Get the tape position. */
2677 static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
2679 unsigned char scmd[MAX_COMMAND_SIZE];
2680 Scsi_Request * SRpnt;
2683 /* KG: We want to be able to use it for checking Write Buffer availability
2684 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2686 char * olddata = STp->buffer->b_data;
2687 int oldsize = STp->buffer->buffer_size;
2688 char * name = tape_name(STp);
2690 if (STp->ready != ST_READY) return (-EIO);
2692 memset (scmd, 0, MAX_COMMAND_SIZE);
2693 scmd[0] = READ_POSITION;
2695 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2696 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, SCSI_DATA_READ,
2697 STp->timeout, MAX_RETRIES, TRUE);
2699 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2704 if (STp->buffer->syscall_result)
2705 result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL;
2707 if (result == -EINVAL)
2708 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2711 if (result == -EIO) { /* re-read position */
2712 unsigned char mysense[16];
2713 memcpy (mysense, SRpnt->sr_sense_buffer, 16);
2714 memset (scmd, 0, MAX_COMMAND_SIZE);
2715 scmd[0] = READ_POSITION;
2716 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2717 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, SCSI_DATA_READ,
2718 STp->timeout, MAX_RETRIES, TRUE);
2719 if (!STp->buffer->syscall_result)
2720 memcpy (SRpnt->sr_sense_buffer, mysense, 16);
2722 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2723 + ((STp->buffer)->b_data[5] << 16)
2724 + ((STp->buffer)->b_data[6] << 8)
2725 + (STp->buffer)->b_data[7];
2726 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2727 + ((STp->buffer)->b_data[ 9] << 16)
2728 + ((STp->buffer)->b_data[10] << 8)
2729 + (STp->buffer)->b_data[11];
2730 STp->cur_frames = (STp->buffer)->b_data[15];
2733 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2734 STp->first_frame_position, STp->last_frame_position,
2735 ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2736 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2740 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2742 printk(KERN_WARNING "%s:D: Correcting read position %d, %d, %d\n", name,
2743 STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2745 STp->first_frame_position = STp->last_frame_position;
2748 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2750 return (result == 0 ? STp->first_frame_position : result);
2754 /* Set the tape block */
2755 static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int ppos, int skip)
2757 unsigned char scmd[MAX_COMMAND_SIZE];
2758 Scsi_Request * SRpnt;
2759 struct st_partstat * STps;
2761 int pp = (ppos == 3000 && !skip)? 0 : ppos;
2762 char * name = tape_name(STp);
2764 if (STp->ready != ST_READY) return (-EIO);
2766 STps = &(STp->ps[STp->partition]);
2768 if (ppos < 0 || ppos > STp->capacity) {
2769 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2770 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2777 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2779 memset (scmd, 0, MAX_COMMAND_SIZE);
2782 scmd[3] = (pp >> 24);
2783 scmd[4] = (pp >> 16);
2784 scmd[5] = (pp >> 8);
2789 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, SCSI_DATA_NONE, STp->long_timeout,
2795 if ((STp->buffer)->syscall_result != 0) {
2797 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
2798 name, STp->first_frame_position, pp);
2803 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
2804 } while ((pp != ppos) && (pp = ppos));
2805 STp->first_frame_position = STp->last_frame_position = ppos;
2806 STps->eof = ST_NOEOF;
2809 STp->frame_in_buffer = 0;
2813 static int osst_write_trailer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int leave_at_EOT)
2815 struct st_partstat * STps = &(STp->ps[STp->partition]);
2818 if (STp->write_type != OS_WRITE_NEW_MARK) {
2819 /* true unless the user wrote the filemark for us */
2820 result = osst_flush_drive_buffer(STp, aSRpnt);
2821 if (result < 0) goto out;
2822 result = osst_write_filemark(STp, aSRpnt);
2823 if (result < 0) goto out;
2825 if (STps->drv_file >= 0)
2827 STps->drv_block = 0;
2829 result = osst_write_eod(STp, aSRpnt);
2830 osst_write_header(STp, aSRpnt, leave_at_EOT);
2837 /* osst versions of st functions - augmented and stripped to suit OnStream only */
2839 /* Flush the write buffer (never need to write if variable blocksize). */
2840 static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
2842 int offset, transfer, blks = 0;
2844 unsigned char cmd[MAX_COMMAND_SIZE];
2845 Scsi_Request * SRpnt = *aSRpnt;
2846 struct st_partstat * STps;
2847 char * name = tape_name(STp);
2849 if ((STp->buffer)->writing) {
2850 if (SRpnt == (STp->buffer)->last_SRpnt)
2852 { printk(OSST_DEB_MSG
2853 "%s:D: aSRpnt points to Scsi_Request that write_behind_check will release -- cleared\n", name);
2855 *aSRpnt = SRpnt = NULL;
2859 "%s:D: aSRpnt does not point to Scsi_Request that write_behind_check will release -- strange\n", name);
2861 osst_write_behind_check(STp);
2862 if ((STp->buffer)->syscall_result) {
2865 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
2866 name, (STp->buffer)->midlevel_result);
2868 if ((STp->buffer)->midlevel_result == INT_MAX)
2875 if (STp->dirty == 1) {
2878 STps = &(STp->ps[STp->partition]);
2879 STps->rw = ST_WRITING;
2880 offset = STp->buffer->buffer_bytes;
2881 blks = (offset + STp->block_size - 1) / STp->block_size;
2882 transfer = OS_FRAME_SIZE;
2884 if (offset < OS_DATA_SIZE)
2885 osst_zero_buffer_tail(STp->buffer);
2887 /* TODO: Error handling! */
2889 result = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120);
2891 memset(cmd, 0, MAX_COMMAND_SIZE);
2896 switch (STp->write_type) {
2900 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
2901 name, blks, STp->frame_seq_number,
2902 STp->logical_blk_num - blks, STp->logical_blk_num - 1);
2904 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
2905 STp->logical_blk_num - blks, STp->block_size, blks);
2908 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
2909 STp->logical_blk_num, 0, 0);
2911 case OS_WRITE_NEW_MARK:
2912 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
2913 STp->logical_blk_num++, 0, blks=1);
2915 case OS_WRITE_HEADER:
2916 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
2918 default: /* probably FILLER */
2919 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
2923 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
2924 name, offset, transfer, blks);
2927 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, SCSI_DATA_WRITE,
2928 STp->timeout, MAX_WRITE_RETRIES, TRUE);
2933 if ((STp->buffer)->syscall_result != 0) {
2936 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
2937 name, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
2938 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
2940 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
2941 (SRpnt->sr_sense_buffer[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
2942 (SRpnt->sr_sense_buffer[2] & 0x0f) == NO_SENSE) {
2944 (STp->buffer)->buffer_bytes = 0;
2948 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
2949 printk(KERN_ERR "%s:E: Error on flush write.\n", name);
2953 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
2956 STp->first_frame_position++;
2958 (STp->buffer)->buffer_bytes = 0;
2962 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
2968 /* Flush the tape buffer. The tape will be positioned correctly unless
2969 seek_next is true. */
2970 static int osst_flush_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int seek_next)
2972 struct st_partstat * STps;
2973 int backspace = 0, result = 0;
2975 char * name = tape_name(STp);
2979 * If there was a bus reset, block further access
2982 if( STp->pos_unknown)
2985 if (STp->ready != ST_READY)
2988 STps = &(STp->ps[STp->partition]);
2989 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
2990 STp->write_type = OS_WRITE_DATA;
2991 return osst_flush_write_buffer(STp, aSRpnt);
2993 if (STp->block_size == 0)
2997 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3000 if (!STp->can_bsr) {
3001 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3002 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3003 (STp->buffer)->buffer_bytes = 0;
3004 (STp->buffer)->read_pointer = 0;
3005 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3009 if (STps->eof == ST_FM_HIT) {
3010 result = cross_eof(STp, aSRpnt, FALSE); /* Back over the EOF hit */
3012 STps->eof = ST_NOEOF;
3014 if (STps->drv_file >= 0)
3016 STps->drv_block = 0;
3019 if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3020 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3022 else if (STps->eof == ST_FM_HIT) {
3023 if (STps->drv_file >= 0)
3025 STps->drv_block = 0;
3026 STps->eof = ST_NOEOF;
3032 static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int synchronous)
3034 unsigned char cmd[MAX_COMMAND_SIZE];
3035 Scsi_Request * SRpnt;
3038 char * name = tape_name(STp);
3041 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3043 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3045 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3048 /* error recovery may have bumped us past the header partition */
3049 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3051 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3053 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3058 osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 60);
3059 /* TODO: Check for an error ! */
3061 // osst_build_stats(STp, &SRpnt);
3063 STp->ps[STp->partition].rw = ST_WRITING;
3064 STp->write_type = OS_WRITE_DATA;
3066 memset(cmd, 0, MAX_COMMAND_SIZE);
3069 cmd[4] = 1; /* one frame at a time... */
3070 blks = STp->buffer->buffer_bytes / STp->block_size;
3073 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3074 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3076 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3077 STp->logical_blk_num - blks, STp->block_size, blks);
3081 STp->write_pending = 1;
3083 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE, STp->timeout,
3084 MAX_WRITE_RETRIES, synchronous);
3090 if (STp->buffer->syscall_result != 0) {
3093 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3095 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
3096 (SRpnt->sr_sense_buffer[2] & 0x40)) {
3097 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
3101 if (osst_write_error_recovery(STp, aSRpnt, 1))
3106 STp->first_frame_position++;
3114 /* Lock or unlock the drive door. Don't use when Scsi_Request allocated. */
3115 static int do_door_lock(OS_Scsi_Tape * STp, int do_lock)
3119 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
3121 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3123 retval = scsi_ioctl(STp->device, cmd, NULL);
3125 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3128 STp->door_locked = ST_LOCK_FAILS;
3133 /* Set the internal state after reset */
3134 static void reset_state(OS_Scsi_Tape *STp)
3137 struct st_partstat *STps;
3139 STp->pos_unknown = 0;
3140 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3141 STps = &(STp->ps[i]);
3143 STps->eof = ST_NOEOF;
3145 STps->last_block_valid = FALSE;
3146 STps->drv_block = -1;
3147 STps->drv_file = -1;
3152 /* Entry points to osst */
3155 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3157 ssize_t total, retval = 0;
3158 ssize_t i, do_count, blks, transfer;
3159 int write_threshold;
3160 int doing_write = 0;
3161 const char __user * b_point;
3162 Scsi_Request * SRpnt = NULL;
3163 struct st_modedef * STm;
3164 struct st_partstat * STps;
3165 OS_Scsi_Tape * STp = filp->private_data;
3166 char * name = tape_name(STp);
3169 if (down_interruptible(&STp->lock))
3170 return (-ERESTARTSYS);
3173 * If we are in the middle of error recovery, don't let anyone
3174 * else try and use this device. Also, if error recovery fails, it
3175 * may try and take the device offline, in which case all further
3176 * access to the device is prohibited.
3178 if( !scsi_block_when_processing_errors(STp->device) ) {
3183 if (STp->ready != ST_READY) {
3184 if (STp->ready == ST_NO_TAPE)
3185 retval = (-ENOMEDIUM);
3190 STm = &(STp->modes[STp->current_mode]);
3191 if (!STm->defined) {
3199 * If there was a bus reset, block further access
3202 if (STp->pos_unknown) {
3209 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3215 if (STp->write_prot) {
3220 /* Write must be integral number of blocks */
3221 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3222 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3223 name, count, STp->block_size<1024?
3224 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3229 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3230 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3231 name, STp->first_frame_position);
3236 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3237 STp->door_locked = ST_LOCKED_AUTO;
3239 STps = &(STp->ps[STp->partition]);
3241 if (STps->rw == ST_READING) {
3243 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3244 STps->drv_file, STps->drv_block);
3246 retval = osst_flush_buffer(STp, &SRpnt, 0);
3251 if (STps->rw != ST_WRITING) {
3252 /* Are we totally rewriting this tape? */
3253 if (!STp->header_ok ||
3254 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3255 (STps->drv_file == 0 && STps->drv_block == 0)) {
3256 STp->wrt_pass_cntr++;
3258 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3259 name, STp->wrt_pass_cntr);
3261 osst_reset_header(STp, &SRpnt);
3262 STps->drv_file = STps->drv_block = 0;
3264 /* Do we know where we'll be writing on the tape? */
3266 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3267 STps->drv_file < 0 || STps->drv_block < 0) {
3268 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3269 STps->drv_file = STp->filemark_cnt;
3270 STps->drv_block = 0;
3273 /* We have no idea where the tape is positioned - give up */
3276 "%s:D: Cannot write at indeterminate position.\n", name);
3282 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3283 STp->filemark_cnt = STps->drv_file;
3284 STp->last_mark_ppos =
3285 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3287 "%s:W: Overwriting file %d with old write pass counter %d\n",
3288 name, STps->drv_file, STp->wrt_pass_cntr);
3290 "%s:W: may lead to stale data being accepted on reading back!\n",
3294 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3295 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3299 STp->fast_open = FALSE;
3301 if (!STp->header_ok) {
3303 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3309 if ((STp->buffer)->writing) {
3310 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3311 osst_write_behind_check(STp);
3312 if ((STp->buffer)->syscall_result) {
3315 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3316 (STp->buffer)->midlevel_result);
3318 if ((STp->buffer)->midlevel_result == INT_MAX)
3319 STps->eof = ST_EOM_OK;
3321 STps->eof = ST_EOM_ERROR;
3324 if (STps->eof == ST_EOM_OK) {
3328 else if (STps->eof == ST_EOM_ERROR) {
3333 /* Check the buffer readability in cases where copy_user might catch
3334 the problems after some tape movement. */
3335 if ((copy_from_user(&i, buf, 1) != 0 ||
3336 copy_from_user(&i, buf + count - 1, 1) != 0)) {
3341 if (!STm->do_buffer_writes) {
3342 write_threshold = 1;
3345 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3346 if (!STm->do_async_writes)
3352 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3353 name, count, STps->drv_file, STps->drv_block,
3354 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3357 while ((STp->buffer)->buffer_bytes + count > write_threshold)
3360 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3361 (STp->buffer)->buffer_bytes;
3362 if (do_count > count)
3365 i = append_to_buffer(b_point, STp->buffer, do_count);
3371 blks = do_count / STp->block_size;
3372 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3374 i = osst_write_frame(STp, &SRpnt, TRUE);
3376 if (i == (-ENOSPC)) {
3377 transfer = STp->buffer->writing; /* FIXME -- check this logic */
3378 if (transfer <= do_count) {
3379 filp->f_pos += do_count - transfer;
3380 count -= do_count - transfer;
3381 if (STps->drv_block >= 0) {
3382 STps->drv_block += (do_count - transfer) / STp->block_size;
3384 STps->eof = ST_EOM_OK;
3385 retval = (-ENOSPC); /* EOM within current request */
3388 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3393 STps->eof = ST_EOM_ERROR;
3394 STps->drv_block = (-1); /* Too cautious? */
3395 retval = (-EIO); /* EOM for old data */
3398 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3406 if (SRpnt != NULL) {
3407 scsi_release_request(SRpnt);
3410 STp->buffer->buffer_bytes = 0;
3413 retval = total - count;
3417 filp->f_pos += do_count;
3418 b_point += do_count;
3420 if (STps->drv_block >= 0) {
3421 STps->drv_block += blks;
3423 STp->buffer->buffer_bytes = 0;
3425 } /* end while write threshold exceeded */
3429 i = append_to_buffer(b_point, STp->buffer, count);
3434 blks = count / STp->block_size;
3435 STp->logical_blk_num += blks;
3436 if (STps->drv_block >= 0) {
3437 STps->drv_block += blks;
3439 filp->f_pos += count;
3443 if (doing_write && (STp->buffer)->syscall_result != 0) {
3444 retval = (STp->buffer)->syscall_result;
3448 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3449 /* Schedule an asynchronous write */
3450 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3451 STp->block_size) * STp->block_size;
3452 STp->dirty = !((STp->buffer)->writing ==
3453 (STp->buffer)->buffer_bytes);
3455 i = osst_write_frame(STp, &SRpnt, FALSE);
3460 SRpnt = NULL; /* Prevent releasing this request! */
3462 STps->at_sm &= (total == 0);
3464 STps->eof = ST_NOEOF;
3469 if (SRpnt != NULL) scsi_release_request(SRpnt);
3478 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3480 ssize_t total, retval = 0;
3481 ssize_t i, transfer;
3483 struct st_modedef * STm;
3484 struct st_partstat * STps;
3485 Scsi_Request * SRpnt = NULL;
3486 OS_Scsi_Tape * STp = filp->private_data;
3487 char * name = tape_name(STp);
3490 if (down_interruptible(&STp->lock))
3491 return (-ERESTARTSYS);
3494 * If we are in the middle of error recovery, don't let anyone
3495 * else try and use this device. Also, if error recovery fails, it
3496 * may try and take the device offline, in which case all further
3497 * access to the device is prohibited.
3499 if( !scsi_block_when_processing_errors(STp->device) ) {
3504 if (STp->ready != ST_READY) {
3505 if (STp->ready == ST_NO_TAPE)
3506 retval = (-ENOMEDIUM);
3511 STm = &(STp->modes[STp->current_mode]);
3512 if (!STm->defined) {
3518 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3523 /* Must have initialized medium */
3524 if (!STp->header_ok) {
3529 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3530 STp->door_locked = ST_LOCKED_AUTO;
3532 STps = &(STp->ps[STp->partition]);
3533 if (STps->rw == ST_WRITING) {
3534 retval = osst_flush_buffer(STp, &SRpnt, 0);
3538 /* FIXME -- this may leave the tape without EOD and up2date headers */
3541 if ((count % STp->block_size) != 0) {
3543 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3544 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3548 if (debugging && STps->eof != ST_NOEOF)
3549 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3550 STps->eof, (STp->buffer)->buffer_bytes);
3552 if ((STp->buffer)->buffer_bytes == 0 &&
3553 STps->eof >= ST_EOD_1) {
3554 if (STps->eof < ST_EOD) {
3559 retval = (-EIO); /* EOM or Blank Check */
3563 /* Check the buffer writability before any tape movement. Don't alter
3565 if (copy_from_user(&i, buf, 1) != 0 ||
3566 copy_to_user (buf, &i, 1) != 0 ||
3567 copy_from_user(&i, buf + count - 1, 1) != 0 ||
3568 copy_to_user (buf + count - 1, &i, 1) != 0) {
3573 /* Loop until enough data in buffer or a special condition found */
3574 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3576 /* Get new data if the buffer is empty */
3577 if ((STp->buffer)->buffer_bytes == 0) {
3578 if (STps->eof == ST_FM_HIT)
3580 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3581 if (special < 0) { /* No need to continue read */
3582 STp->frame_in_buffer = 0;
3588 /* Move the data from driver buffer to user buffer */
3589 if ((STp->buffer)->buffer_bytes > 0) {
3591 if (debugging && STps->eof != ST_NOEOF)
3592 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3593 STps->eof, (STp->buffer)->buffer_bytes, count - total);
3595 /* force multiple of block size, note block_size may have been adjusted */
3596 transfer = (((STp->buffer)->buffer_bytes < count - total ?
3597 (STp->buffer)->buffer_bytes : count - total)/
3598 STp->block_size) * STp->block_size;
3600 if (transfer == 0) {
3602 "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
3603 name, count, STp->block_size < 1024?
3604 STp->block_size:STp->block_size/1024,
3605 STp->block_size<1024?'b':'k');
3608 i = from_buffer(STp->buffer, buf, transfer);
3613 STp->logical_blk_num += transfer / STp->block_size;
3614 STps->drv_block += transfer / STp->block_size;
3615 filp->f_pos += transfer;
3620 if ((STp->buffer)->buffer_bytes == 0) {
3623 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3624 name, STp->frame_seq_number);
3626 STp->frame_in_buffer = 0;
3627 STp->frame_seq_number++; /* frame to look for next time */
3629 } /* for (total = 0, special = 0; total < count && !special; ) */
3631 /* Change the eof state if no data from tape or buffer */
3633 if (STps->eof == ST_FM_HIT) {
3634 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3635 STps->drv_block = 0;
3636 if (STps->drv_file >= 0)
3639 else if (STps->eof == ST_EOD_1) {
3640 STps->eof = ST_EOD_2;
3641 if (STps->drv_block > 0 && STps->drv_file >= 0)
3643 STps->drv_block = 0;
3645 else if (STps->eof == ST_EOD_2)
3648 else if (STps->eof == ST_FM)
3649 STps->eof = ST_NOEOF;
3654 if (SRpnt != NULL) scsi_release_request(SRpnt);
3662 /* Set the driver options */
3663 static void osst_log_options(OS_Scsi_Tape *STp, struct st_modedef *STm,
3667 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3668 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3669 STm->do_read_ahead);
3671 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3672 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3674 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3675 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3676 STp->scsi2_logical);
3678 "%s:I: sysv: %d\n", name, STm->sysv);
3681 "%s:D: debugging: %d\n",
3687 static int osst_set_options(OS_Scsi_Tape *STp, long options)
3691 struct st_modedef * STm;
3692 char * name = tape_name(STp);
3694 STm = &(STp->modes[STp->current_mode]);
3695 if (!STm->defined) {
3696 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3697 modes_defined = TRUE;
3700 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3701 name, STp->current_mode);
3705 code = options & MT_ST_OPTIONS;
3706 if (code == MT_ST_BOOLEANS) {
3707 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3708 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3709 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3710 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3711 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3712 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3713 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3714 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3715 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3716 if ((STp->device)->scsi_level >= SCSI_2)
3717 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3718 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3719 STm->sysv = (options & MT_ST_SYSV) != 0;
3721 debugging = (options & MT_ST_DEBUGGING) != 0;
3723 osst_log_options(STp, STm, name);
3725 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3726 value = (code == MT_ST_SETBOOLEANS);
3727 if ((options & MT_ST_BUFFER_WRITES) != 0)
3728 STm->do_buffer_writes = value;
3729 if ((options & MT_ST_ASYNC_WRITES) != 0)
3730 STm->do_async_writes = value;
3731 if ((options & MT_ST_DEF_WRITES) != 0)
3732 STm->defaults_for_writes = value;
3733 if ((options & MT_ST_READ_AHEAD) != 0)
3734 STm->do_read_ahead = value;
3735 if ((options & MT_ST_TWO_FM) != 0)
3736 STp->two_fm = value;
3737 if ((options & MT_ST_FAST_MTEOM) != 0)
3738 STp->fast_mteom = value;
3739 if ((options & MT_ST_AUTO_LOCK) != 0)
3740 STp->do_auto_lock = value;
3741 if ((options & MT_ST_CAN_BSR) != 0)
3742 STp->can_bsr = value;
3743 if ((options & MT_ST_NO_BLKLIMS) != 0)
3744 STp->omit_blklims = value;
3745 if ((STp->device)->scsi_level >= SCSI_2 &&
3746 (options & MT_ST_CAN_PARTITIONS) != 0)
3747 STp->can_partitions = value;
3748 if ((options & MT_ST_SCSI2LOGICAL) != 0)
3749 STp->scsi2_logical = value;
3750 if ((options & MT_ST_SYSV) != 0)
3753 if ((options & MT_ST_DEBUGGING) != 0)
3756 osst_log_options(STp, STm, name);
3758 else if (code == MT_ST_WRITE_THRESHOLD) {
3759 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3760 if (value < 1 || value > osst_buffer_size) {
3761 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3765 STp->write_threshold = value;
3766 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3769 else if (code == MT_ST_DEF_BLKSIZE) {
3770 value = (options & ~MT_ST_OPTIONS);
3771 if (value == ~MT_ST_OPTIONS) {
3772 STm->default_blksize = (-1);
3773 printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3776 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3777 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3781 STm->default_blksize = value;
3782 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
3783 name, STm->default_blksize);
3786 else if (code == MT_ST_TIMEOUTS) {
3787 value = (options & ~MT_ST_OPTIONS);
3788 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
3789 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
3790 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
3791 (value & ~MT_ST_SET_LONG_TIMEOUT));
3794 STp->timeout = value * HZ;
3795 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
3798 else if (code == MT_ST_DEF_OPTIONS) {
3799 code = (options & ~MT_ST_CLEAR_DEFAULT);
3800 value = (options & MT_ST_CLEAR_DEFAULT);
3801 if (code == MT_ST_DEF_DENSITY) {
3802 if (value == MT_ST_CLEAR_DEFAULT) {
3803 STm->default_density = (-1);
3804 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
3807 STm->default_density = value & 0xff;
3808 printk(KERN_INFO "%s:I: Density default set to %x\n",
3809 name, STm->default_density);
3812 else if (code == MT_ST_DEF_DRVBUFFER) {
3813 if (value == MT_ST_CLEAR_DEFAULT) {
3814 STp->default_drvbuffer = 0xff;
3815 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
3818 STp->default_drvbuffer = value & 7;
3819 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
3820 name, STp->default_drvbuffer);
3823 else if (code == MT_ST_DEF_COMPRESSION) {
3824 if (value == MT_ST_CLEAR_DEFAULT) {
3825 STm->default_compression = ST_DONT_TOUCH;
3826 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
3829 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
3830 printk(KERN_INFO "%s:I: Compression default set to %x\n",
3842 /* Internal ioctl function */
3843 static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned int cmd_in, unsigned long arg)
3847 int i, ioctl_result;
3849 unsigned char cmd[MAX_COMMAND_SIZE];
3850 Scsi_Request * SRpnt = * aSRpnt;
3851 struct st_partstat * STps;
3852 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
3853 int datalen = 0, direction = SCSI_DATA_NONE;
3854 char * name = tape_name(STp);
3856 if (STp->ready != ST_READY && cmd_in != MTLOAD) {
3857 if (STp->ready == ST_NO_TAPE)
3858 return (-ENOMEDIUM);
3862 timeout = STp->long_timeout;
3863 STps = &(STp->ps[STp->partition]);
3864 fileno = STps->drv_file;
3865 blkno = STps->drv_block;
3866 at_sm = STps->at_sm;
3867 frame_seq_numbr = STp->frame_seq_number;
3868 logical_blk_num = STp->logical_blk_num;
3870 memset(cmd, 0, MAX_COMMAND_SIZE);
3873 chg_eof = FALSE; /* Changed from the FSF after this */
3877 if (STp->linux_media)
3878 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
3880 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
3884 at_sm &= (arg == 0);
3888 chg_eof = FALSE; /* Changed from the FSF after this */
3892 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
3895 blkno = (-1); /* We can't know the block number */
3896 at_sm &= (arg == 0);
3903 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
3904 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
3906 if (cmd_in == MTFSR) {
3907 logical_blk_num += arg;
3908 if (blkno >= 0) blkno += arg;
3911 logical_blk_num -= arg;
3912 if (blkno >= 0) blkno -= arg;
3914 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
3915 fileno = STps->drv_file;
3916 blkno = STps->drv_block;
3917 at_sm &= (arg == 0);
3922 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
3923 cmd[2] = (arg >> 16);
3924 cmd[3] = (arg >> 8);
3928 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
3929 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
3932 blkno = fileno = (-1);
3938 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
3940 cmd[2] = (ltmp >> 16);
3941 cmd[3] = (ltmp >> 8);
3947 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
3948 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
3953 blkno = fileno = (-1);
3958 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
3959 STp->write_type = OS_WRITE_DATA;
3960 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
3965 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
3967 for (i=0; i<arg; i++)
3968 ioctl_result |= osst_write_filemark(STp, &SRpnt);
3969 if (fileno >= 0) fileno += arg;
3970 if (blkno >= 0) blkno = 0;
3974 if (STp->write_prot)
3978 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
3979 if (cmd_in == MTWSM)
3981 cmd[2] = (arg >> 16);
3982 cmd[3] = (arg >> 8);
3984 timeout = STp->timeout;
3987 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
3988 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
3993 at_sm = (cmd_in == MTWSM);
3999 cmd[0] = START_STOP;
4000 cmd[1] = 1; /* Don't wait for completion */
4001 if (cmd_in == MTLOAD) {
4002 if (STp->ready == ST_NO_TAPE)
4003 cmd[4] = 4; /* open tray */
4005 cmd[4] = 1; /* load */
4007 if (cmd_in == MTRETEN)
4008 cmd[4] = 3; /* retension then mount */
4009 if (cmd_in == MTOFFL)
4010 cmd[4] = 4; /* rewind then eject */
4011 timeout = STp->timeout;
4016 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4019 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4022 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4025 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4030 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4035 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4037 return 0; /* Should do something ? */
4042 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4044 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4045 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4046 ioctl_result = -EIO;
4049 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4051 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4053 ioctl_result = -EIO;
4056 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4057 fileno = STp->filemark_cnt;
4062 if (STp->write_prot)
4064 ioctl_result = osst_reset_header(STp, &SRpnt);
4065 i = osst_write_eod(STp, &SRpnt);
4066 if (i < ioctl_result) ioctl_result = i;
4067 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4068 if (i < ioctl_result) ioctl_result = i;
4069 fileno = blkno = at_sm = 0 ;
4073 cmd[0] = REZERO_UNIT; /* rewind */
4077 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4079 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4082 case MTSETBLK: /* Set block length */
4083 if ((STps->drv_block == 0 ) &&
4085 ((STp->buffer)->buffer_bytes == 0) &&
4086 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4087 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4088 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4090 * Only allowed to change the block size if you opened the
4091 * device at the beginning of a file before writing anything.
4092 * Note, that when reading, changing block_size is futile,
4093 * as the size used when writing overrides it.
4095 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4096 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4097 name, STp->block_size);
4100 case MTSETDENSITY: /* Set tape density */
4101 case MTSETDRVBUFFER: /* Set drive buffering */
4102 case SET_DENS_AND_BLK: /* Set density and block size */
4104 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4105 return (-EIO); /* Not allowed if data in buffer */
4106 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4107 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4108 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4109 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4110 name, (int)(arg & MT_ST_BLKSIZE_MASK),
4111 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4114 return 0; /* FIXME silently ignore if block size didn't change */
4120 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, TRUE);
4122 ioctl_result = (STp->buffer)->syscall_result;
4126 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4128 return ioctl_result;
4131 if (!ioctl_result) { /* SCSI command successful */
4132 STp->frame_seq_number = frame_seq_numbr;
4133 STp->logical_blk_num = logical_blk_num;
4139 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4142 if (!ioctl_result) { /* success */
4144 if (cmd_in == MTFSFM) {
4148 if (cmd_in == MTBSFM) {
4152 STps->drv_block = blkno;
4153 STps->drv_file = fileno;
4154 STps->at_sm = at_sm;
4156 if (cmd_in == MTEOM)
4158 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4159 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4161 STp->logical_blk_num++;
4162 STp->frame_seq_number++;
4163 STp->frame_in_buffer = 0;
4164 STp->buffer->read_pointer = 0;
4166 else if (cmd_in == MTFSF)
4167 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4169 STps->eof = ST_NOEOF;
4171 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4172 STp->rew_at_close = 0;
4173 else if (cmd_in == MTLOAD) {
4174 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4175 STp->ps[i].rw = ST_IDLE;
4176 STp->ps[i].last_block_valid = FALSE;/* FIXME - where else is this field maintained? */
4181 if (cmd_in == MTREW) {
4182 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4183 if (ioctl_result > 0)
4187 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4188 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4189 STps->drv_file = STps->drv_block = -1;
4191 STps->drv_file = STps->drv_block = 0;
4192 STps->eof = ST_NOEOF;
4193 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4194 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4195 STps->drv_file = STps->drv_block = -1;
4197 STps->drv_file = STp->filemark_cnt;
4198 STps->drv_block = 0;
4201 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4202 STps->drv_file = STps->drv_block = (-1);
4203 STps->eof = ST_NOEOF;
4205 } else if (cmd_in == MTERASE) {
4207 } else if (SRpnt) { /* SCSI command was not completely successful. */
4208 if (SRpnt->sr_sense_buffer[2] & 0x40) {
4209 STps->eof = ST_EOM_OK;
4210 STps->drv_block = 0;
4213 STps->eof = ST_NOEOF;
4215 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == BLANK_CHECK)
4218 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4219 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4223 return ioctl_result;
4227 /* Open the device */
4228 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4230 unsigned short flags;
4231 int i, b_size, new_session = FALSE, retval = 0;
4232 unsigned char cmd[MAX_COMMAND_SIZE];
4233 Scsi_Request * SRpnt = NULL;
4235 struct st_modedef * STm;
4236 struct st_partstat * STps;
4238 int dev = TAPE_NR(inode);
4239 int mode = TAPE_MODE(inode);
4241 nonseekable_open(inode, filp);
4242 write_lock(&os_scsi_tapes_lock);
4243 if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4244 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4245 write_unlock(&os_scsi_tapes_lock);
4249 name = tape_name(STp);
4252 write_unlock(&os_scsi_tapes_lock);
4254 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4258 if (scsi_device_get(STp->device)) {
4259 write_unlock(&os_scsi_tapes_lock);
4261 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4265 filp->private_data = STp;
4267 write_unlock(&os_scsi_tapes_lock);
4268 STp->rew_at_close = TAPE_REWIND(inode);
4270 if( !scsi_block_when_processing_errors(STp->device) ) {
4274 if (mode != STp->current_mode) {
4277 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4278 name, STp->current_mode, mode);
4281 STp->current_mode = mode;
4283 STm = &(STp->modes[STp->current_mode]);
4285 flags = filp->f_flags;
4286 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4288 STp->raw = TAPE_IS_RAW(inode);
4292 /* Allocate data segments for this device's tape buffer */
4293 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4294 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4295 retval = (-EOVERFLOW);
4298 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4299 for (i = 0, b_size = 0;
4300 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4301 b_size += STp->buffer->sg[i++].length);
4302 STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
4304 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4305 STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4306 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4307 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4310 STp->buffer->aux = NULL; /* this had better never happen! */
4311 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4315 STp->buffer->writing = 0;
4316 STp->buffer->syscall_result = 0;
4318 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4319 STps = &(STp->ps[i]);
4322 STp->ready = ST_READY;
4324 STp->nbr_waits = STp->nbr_finished = 0;
4327 memset (cmd, 0, MAX_COMMAND_SIZE);
4328 cmd[0] = TEST_UNIT_READY;
4330 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
4332 retval = (STp->buffer)->syscall_result;
4335 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4336 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
4337 SRpnt->sr_sense_buffer[12] == 4 ) {
4339 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sr_sense_buffer[13]);
4341 if (filp->f_flags & O_NONBLOCK) {
4345 if (SRpnt->sr_sense_buffer[13] == 2) { /* initialize command required (LOAD) */
4346 memset (cmd, 0, MAX_COMMAND_SIZE);
4347 cmd[0] = START_STOP;
4350 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
4351 STp->timeout, MAX_READY_RETRIES, TRUE);
4353 osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0);
4355 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4356 (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4358 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4362 for (i=0; i < 10; i++) {
4364 memset (cmd, 0, MAX_COMMAND_SIZE);
4365 cmd[0] = TEST_UNIT_READY;
4367 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
4368 STp->timeout, MAX_READY_RETRIES, TRUE);
4369 if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
4370 (SRpnt->sr_sense_buffer[2] & 0x0f) != UNIT_ATTENTION)
4374 STp->pos_unknown = 0;
4375 STp->partition = STp->new_partition = 0;
4376 if (STp->can_partitions)
4377 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4378 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4379 STps = &(STp->ps[i]);
4380 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4381 STps->eof = ST_NOEOF;
4383 STps->last_block_valid = FALSE;
4384 STps->drv_block = 0;
4385 STps->drv_file = 0 ;
4388 STp->recover_count = 0;
4391 * if we have valid headers from before, and the drive/tape seem untouched,
4392 * open without reconfiguring and re-reading the headers
4394 if (!STp->buffer->syscall_result && STp->header_ok &&
4395 !SRpnt->sr_result && SRpnt->sr_sense_buffer[0] == 0) {
4397 memset(cmd, 0, MAX_COMMAND_SIZE);
4398 cmd[0] = MODE_SENSE;
4400 cmd[2] = VENDOR_IDENT_PAGE;
4401 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4403 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
4405 if (STp->buffer->syscall_result ||
4406 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4407 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4408 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4409 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4411 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4412 STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4413 STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4414 STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4415 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4419 i = STp->first_frame_position;
4420 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4421 if (STp->door_locked == ST_UNLOCKED) {
4422 if (do_door_lock(STp, 1))
4423 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4425 STp->door_locked = ST_LOCKED_AUTO;
4427 if (!STp->frame_in_buffer) {
4428 STp->block_size = (STm->default_blksize > 0) ?
4429 STm->default_blksize : OS_DATA_SIZE;
4430 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4432 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4433 STp->fast_open = TRUE;
4434 scsi_release_request(SRpnt);
4438 if (i != STp->first_frame_position)
4439 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4440 name, i, STp->first_frame_position);
4444 STp->fast_open = FALSE;
4446 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4447 (SRpnt->sr_sense_buffer[2] != 2 || SRpnt->sr_sense_buffer[12] != 0x3A) ) {
4449 memset(cmd, 0, MAX_COMMAND_SIZE);
4450 cmd[0] = MODE_SELECT;
4452 cmd[4] = 4 + MODE_HEADER_LENGTH;
4454 (STp->buffer)->b_data[0] = cmd[4] - 1;
4455 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4456 (STp->buffer)->b_data[2] = 0; /* Reserved */
4457 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4458 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4459 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4460 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4461 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4464 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4466 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
4470 for (i=0; i < 10; i++) {
4472 memset (cmd, 0, MAX_COMMAND_SIZE);
4473 cmd[0] = TEST_UNIT_READY;
4475 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
4476 STp->timeout, MAX_READY_RETRIES, TRUE);
4477 if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
4478 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY)
4481 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) {
4482 STp->pos_unknown = 0;
4483 STp->partition = STp->new_partition = 0;
4484 if (STp->can_partitions)
4485 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4486 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4487 STps = &(STp->ps[i]);
4489 STps->eof = ST_NOEOF;
4491 STps->last_block_valid = FALSE;
4492 STps->drv_block = 0;
4493 STps->drv_file = 0 ;
4500 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4501 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4503 if ((STp->buffer)->syscall_result != 0) {
4504 if ((STp->device)->scsi_level >= SCSI_2 &&
4505 (SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4506 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
4507 SRpnt->sr_sense_buffer[12] == 0x3a) { /* Check ASC */
4508 STp->ready = ST_NO_TAPE;
4510 STp->ready = ST_NOT_READY;
4511 scsi_release_request(SRpnt);
4513 STp->density = 0; /* Clear the erroneous "residue" */
4514 STp->write_prot = 0;
4515 STp->block_size = 0;
4516 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4517 STp->partition = STp->new_partition = 0;
4518 STp->door_locked = ST_UNLOCKED;
4522 osst_configure_onstream(STp, &SRpnt);
4524 STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4525 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4526 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4527 STp->buffer->buffer_bytes =
4528 STp->buffer->read_pointer =
4529 STp->frame_in_buffer = 0;
4533 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4534 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4535 (STp->buffer)->buffer_blocks);
4538 if (STp->drv_write_prot) {
4539 STp->write_prot = 1;
4542 printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4544 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4550 if (new_session) { /* Change the drive parameters for the new mode */
4553 printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4555 STp->density_changed = STp->blksize_changed = FALSE;
4556 STp->compression_changed = FALSE;
4560 * properly position the tape and check the ADR headers
4562 if (STp->door_locked == ST_UNLOCKED) {
4563 if (do_door_lock(STp, 1))
4564 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4566 STp->door_locked = ST_LOCKED_AUTO;
4569 osst_analyze_headers(STp, &SRpnt);
4571 scsi_release_request(SRpnt);
4578 scsi_release_request(SRpnt);
4579 normalize_buffer(STp->buffer);
4582 scsi_device_put(STp->device);
4588 /* Flush the tape buffer before close */
4589 static int os_scsi_tape_flush(struct file * filp)
4591 int result = 0, result2;
4592 OS_Scsi_Tape * STp = filp->private_data;
4593 struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4594 struct st_partstat * STps = &(STp->ps[STp->partition]);
4595 Scsi_Request * SRpnt = NULL;
4596 char * name = tape_name(STp);
4598 if (file_count(filp) > 1)
4601 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4602 STp->write_type = OS_WRITE_DATA;
4603 result = osst_flush_write_buffer(STp, &SRpnt);
4604 if (result != 0 && result != (-ENOSPC))
4607 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4611 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4612 name, (long)(filp->f_pos));
4613 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4614 name, STp->nbr_waits, STp->nbr_finished);
4617 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4620 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4621 name, 1+STp->two_fm);
4624 else if (!STp->rew_at_close) {
4625 STps = &(STp->ps[STp->partition]);
4626 if (!STm->sysv || STps->rw != ST_READING) {
4628 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4629 else if (STps->eof == ST_FM_HIT) {
4630 result = cross_eof(STp, &SRpnt, FALSE);
4632 if (STps->drv_file >= 0)
4634 STps->drv_block = 0;
4638 STps->eof = ST_NOEOF;
4641 else if ((STps->eof == ST_NOEOF &&
4642 !(result = cross_eof(STp, &SRpnt, TRUE))) ||
4643 STps->eof == ST_FM_HIT) {
4644 if (STps->drv_file >= 0)
4646 STps->drv_block = 0;
4652 if (STp->rew_at_close) {
4653 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4654 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4655 if (result == 0 && result2 < 0)
4658 if (SRpnt) scsi_release_request(SRpnt);
4660 if (STp->recover_count) {
4661 printk(KERN_INFO "%s:I: %d recovered errors in", name, STp->recover_count);
4662 if (STp->write_count)
4663 printk(" %d frames written", STp->write_count);
4664 if (STp->read_count)
4665 printk(" %d frames read", STp->read_count);
4667 STp->recover_count = 0;
4669 STp->write_count = 0;
4670 STp->read_count = 0;
4676 /* Close the device and release it */
4677 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4680 OS_Scsi_Tape * STp = filp->private_data;
4681 Scsi_Request * SRpnt = NULL;
4683 if (SRpnt) scsi_release_request(SRpnt);
4685 if (STp->door_locked == ST_LOCKED_AUTO)
4686 do_door_lock(STp, 0);
4691 normalize_buffer(STp->buffer);
4692 write_lock(&os_scsi_tapes_lock);
4694 write_unlock(&os_scsi_tapes_lock);
4696 scsi_device_put(STp->device);
4702 /* The ioctl command */
4703 static int osst_ioctl(struct inode * inode,struct file * file,
4704 unsigned int cmd_in, unsigned long arg)
4706 int i, cmd_nr, cmd_type, retval = 0;
4708 struct st_modedef * STm;
4709 struct st_partstat * STps;
4710 Scsi_Request * SRpnt = NULL;
4711 OS_Scsi_Tape * STp = file->private_data;
4712 char * name = tape_name(STp);
4713 void __user *p = (void __user *)arg;
4715 if (down_interruptible(&STp->lock))
4716 return -ERESTARTSYS;
4719 if (debugging && !STp->in_use) {
4720 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4725 STm = &(STp->modes[STp->current_mode]);
4726 STps = &(STp->ps[STp->partition]);
4729 * If we are in the middle of error recovery, don't let anyone
4730 * else try and use this device. Also, if error recovery fails, it
4731 * may try and take the device offline, in which case all further
4732 * access to the device is prohibited.
4734 if( !scsi_block_when_processing_errors(STp->device) ) {
4739 cmd_type = _IOC_TYPE(cmd_in);
4740 cmd_nr = _IOC_NR(cmd_in);
4742 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4743 cmd_type, cmd_nr, STp->raw?"raw":"normal");
4745 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4749 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
4754 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
4760 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
4761 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
4766 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
4771 if (!STp->pos_unknown) {
4773 if (STps->eof == ST_FM_HIT) {
4774 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
4776 if (STps->drv_file >= 0)
4777 STps->drv_file += 1;
4779 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
4781 if (STps->drv_file >= 0)
4782 STps->drv_file += 1;
4786 if (mtc.mt_op == MTSEEK) {
4787 /* Old position must be restored if partition will be changed */
4788 i = !STp->can_partitions || (STp->new_partition != STp->partition);
4791 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
4792 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
4793 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
4794 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
4795 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
4796 mtc.mt_op == MTCOMPRESSION;
4798 i = osst_flush_buffer(STp, &SRpnt, i);
4806 * If there was a bus reset, block further access
4807 * to this device. If the user wants to rewind the tape,
4808 * then reset the flag and allow access again.
4810 if(mtc.mt_op != MTREW &&
4811 mtc.mt_op != MTOFFL &&
4812 mtc.mt_op != MTRETEN &&
4813 mtc.mt_op != MTERASE &&
4814 mtc.mt_op != MTSEEK &&
4815 mtc.mt_op != MTEOM) {
4820 /* remove this when the midlevel properly clears was_reset */
4821 STp->device->was_reset = 0;
4824 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK &&
4825 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
4826 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER &&
4827 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART &&
4828 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) {
4831 * The user tells us to move to another position on the tape.
4832 * If we were appending to the tape content, that would leave
4833 * the tape without proper end, in that case write EOD and
4834 * update the header to reflect its position.
4837 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
4838 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
4839 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
4840 STp->logical_blk_num, STps->drv_file, STps->drv_block );
4842 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
4843 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
4844 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4845 i = osst_write_trailer(STp, &SRpnt,
4846 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4848 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
4849 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
4850 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
4860 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
4861 do_door_lock(STp, 0); /* Ignore result! */
4863 if (mtc.mt_op == MTSETDRVBUFFER &&
4864 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
4865 retval = osst_set_options(STp, mtc.mt_count);
4869 if (mtc.mt_op == MTSETPART) {
4870 if (mtc.mt_count >= STp->nbr_partitions)
4873 STp->new_partition = mtc.mt_count;
4879 if (mtc.mt_op == MTMKPART) {
4880 if (!STp->can_partitions) {
4884 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
4885 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
4889 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4890 STp->ps[i].rw = ST_IDLE;
4891 STp->ps[i].at_sm = 0;
4892 STp->ps[i].last_block_valid = FALSE;
4894 STp->partition = STp->new_partition = 0;
4895 STp->nbr_partitions = 1; /* Bad guess ?-) */
4896 STps->drv_block = STps->drv_file = 0;
4901 if (mtc.mt_op == MTSEEK) {
4903 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
4905 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
4906 if (!STp->can_partitions)
4907 STp->ps[0].rw = ST_IDLE;
4912 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
4913 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
4918 cross_eof(STp, &SRpnt, FALSE);
4920 if (mtc.mt_op == MTCOMPRESSION)
4921 retval = -EINVAL; /* OnStream drives don't have compression hardware */
4923 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
4924 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
4925 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
4929 if (!STm->defined) {
4934 if ((i = osst_flush_buffer(STp, &SRpnt, FALSE)) < 0) {
4939 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
4940 struct mtget mt_status;
4942 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
4947 mt_status.mt_type = MT_ISONSTREAM_SC;
4948 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
4949 mt_status.mt_dsreg =
4950 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
4951 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
4952 mt_status.mt_blkno = STps->drv_block;
4953 mt_status.mt_fileno = STps->drv_file;
4954 if (STp->block_size != 0) {
4955 if (STps->rw == ST_WRITING)
4956 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
4957 else if (STps->rw == ST_READING)
4958 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
4959 STp->block_size - 1) / STp->block_size;
4962 mt_status.mt_gstat = 0;
4963 if (STp->drv_write_prot)
4964 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
4965 if (mt_status.mt_blkno == 0) {
4966 if (mt_status.mt_fileno == 0)
4967 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
4969 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
4971 mt_status.mt_resid = STp->partition;
4972 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
4973 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
4974 else if (STps->eof >= ST_EOM_OK)
4975 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
4976 if (STp->density == 1)
4977 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
4978 else if (STp->density == 2)
4979 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
4980 else if (STp->density == 3)
4981 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
4982 if (STp->ready == ST_READY)
4983 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
4984 if (STp->ready == ST_NO_TAPE)
4985 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
4987 mt_status.mt_gstat |= GMT_SM(0xffffffff);
4988 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
4989 STp->drv_buffer != 0)
4990 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
4992 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
4998 STp->recover_erreg = 0; /* Clear after read */
5001 } /* End of MTIOCGET */
5003 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5004 struct mtpos mt_pos;
5006 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5011 blk = osst_get_frame_position(STp, &SRpnt);
5013 blk = osst_get_sector(STp, &SRpnt);
5018 mt_pos.mt_blkno = blk;
5019 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5024 if (SRpnt) scsi_release_request(SRpnt);
5028 return scsi_ioctl(STp->device, cmd_in, p);
5031 if (SRpnt) scsi_release_request(SRpnt);
5039 /* Memory handling routines */
5041 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5042 static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5047 if (from_initialization)
5048 priority = GFP_ATOMIC;
5050 priority = GFP_KERNEL;
5052 i = sizeof(OSST_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5053 tb = (OSST_buffer *)kmalloc(i, priority);
5055 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5059 tb->sg_segs = tb->orig_sg_segs = 0;
5060 tb->use_sg = max_sg;
5063 tb->buffer_size = 0;
5067 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5068 i, max_sg, need_dma);
5073 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5074 static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma)
5076 int segs, nbr, max_segs, b_size, priority, order, got;
5078 if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5081 if (STbuffer->sg_segs) {
5082 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5083 normalize_buffer(STbuffer);
5085 /* See how many segments we can use -- need at least two */
5086 nbr = max_segs = STbuffer->use_sg;
5090 priority = GFP_KERNEL;
5092 priority |= GFP_DMA;
5094 priority |= __GFP_NOWARN;
5096 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5097 big enough to reach the goal (code assumes no segments in place) */
5098 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5099 STbuffer->sg[0].page = alloc_pages(priority, order);
5100 STbuffer->sg[0].offset = 0;
5101 if (STbuffer->sg[0].page != NULL) {
5102 STbuffer->sg[0].length = b_size;
5103 STbuffer->b_data = page_address(STbuffer->sg[0].page);
5107 if (STbuffer->sg[0].page == NULL) {
5108 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5111 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5112 for (segs=STbuffer->sg_segs=1, got=b_size;
5113 segs < max_segs && got < OS_FRAME_SIZE; ) {
5114 STbuffer->sg[segs].page =
5115 alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5116 STbuffer->sg[segs].offset = 0;
5117 if (STbuffer->sg[segs].page == NULL) {
5118 if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
5119 b_size /= 2; /* Large enough for the rest of the buffers */
5123 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5126 STbuffer->buffer_size = got;
5128 normalize_buffer(STbuffer);
5131 STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
5132 got += STbuffer->sg[segs].length;
5133 STbuffer->buffer_size = got;
5134 STbuffer->sg_segs = ++segs;
5139 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5140 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5142 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5143 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5144 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5152 /* Release the segments */
5153 static void normalize_buffer(OSST_buffer *STbuffer)
5155 int i, order, b_size;
5157 for (i=0; i < STbuffer->sg_segs; i++) {
5159 for (b_size = PAGE_SIZE, order = 0;
5160 b_size < STbuffer->sg[i].length;
5161 b_size *= 2, order++);
5163 __free_pages(STbuffer->sg[i].page, order);
5164 STbuffer->buffer_size -= STbuffer->sg[i].length;
5167 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5168 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5169 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5171 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5175 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5176 negative error code. */
5177 static int append_to_buffer(const char __user *ubp, OSST_buffer *st_bp, int do_count)
5179 int i, cnt, res, offset;
5181 for (i=0, offset=st_bp->buffer_bytes;
5182 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5183 offset -= st_bp->sg[i].length;
5184 if (i == st_bp->sg_segs) { /* Should never happen */
5185 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5188 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5189 cnt = st_bp->sg[i].length - offset < do_count ?
5190 st_bp->sg[i].length - offset : do_count;
5191 res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
5195 st_bp->buffer_bytes += cnt;
5199 if (do_count) { /* Should never happen */
5200 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5208 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5209 negative error code. */
5210 static int from_buffer(OSST_buffer *st_bp, char __user *ubp, int do_count)
5212 int i, cnt, res, offset;
5214 for (i=0, offset=st_bp->read_pointer;
5215 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5216 offset -= st_bp->sg[i].length;
5217 if (i == st_bp->sg_segs) { /* Should never happen */
5218 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5221 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5222 cnt = st_bp->sg[i].length - offset < do_count ?
5223 st_bp->sg[i].length - offset : do_count;
5224 res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
5228 st_bp->buffer_bytes -= cnt;
5229 st_bp->read_pointer += cnt;
5233 if (do_count) { /* Should never happen */
5234 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5240 /* Sets the tail of the buffer after fill point to zero.
5241 Returns zero (success) or negative error code. */
5242 static int osst_zero_buffer_tail(OSST_buffer *st_bp)
5244 int i, offset, do_count, cnt;
5246 for (i = 0, offset = st_bp->buffer_bytes;
5247 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5248 offset -= st_bp->sg[i].length;
5249 if (i == st_bp->sg_segs) { /* Should never happen */
5250 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5253 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5254 i < st_bp->sg_segs && do_count > 0; i++) {
5255 cnt = st_bp->sg[i].length - offset < do_count ?
5256 st_bp->sg[i].length - offset : do_count ;
5257 memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
5261 if (do_count) { /* Should never happen */
5262 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5268 /* Copy a osst 32K chunk of memory into the buffer.
5269 Returns zero (success) or negative error code. */
5270 static int osst_copy_to_buffer(OSST_buffer *st_bp, unsigned char *ptr)
5272 int i, cnt, do_count = OS_DATA_SIZE;
5274 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5275 cnt = st_bp->sg[i].length < do_count ?
5276 st_bp->sg[i].length : do_count ;
5277 memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
5281 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5282 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5289 /* Copy a osst 32K chunk of memory from the buffer.
5290 Returns zero (success) or negative error code. */
5291 static int osst_copy_from_buffer(OSST_buffer *st_bp, unsigned char *ptr)
5293 int i, cnt, do_count = OS_DATA_SIZE;
5295 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5296 cnt = st_bp->sg[i].length < do_count ?
5297 st_bp->sg[i].length : do_count ;
5298 memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
5302 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5303 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5311 /* Module housekeeping */
5313 static void validate_options (void)
5316 osst_max_dev = max_dev;
5317 if (write_threshold_kbs > 0)
5318 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5319 if (osst_write_threshold > osst_buffer_size)
5320 osst_write_threshold = osst_buffer_size;
5321 if (max_sg_segs >= OSST_FIRST_SG)
5322 osst_max_sg_segs = max_sg_segs;
5324 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5325 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5330 /* Set the boot options. Syntax: osst=xxx,yyy,...
5331 where xxx is write threshold in 1024 byte blocks,
5332 and yyy is number of s/g segments to use. */
5333 static int __init osst_setup (char *str)
5338 stp = get_options(str, ARRAY_SIZE(ints), ints);
5341 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5342 *parms[i].val = ints[i + 1];
5344 while (stp != NULL) {
5345 for (i = 0; i < ARRAY_SIZE(parms); i++) {
5346 int len = strlen(parms[i].name);
5347 if (!strncmp(stp, parms[i].name, len) &&
5348 (*(stp + len) == ':' || *(stp + len) == '=')) {
5350 simple_strtoul(stp + len + 1, NULL, 0);
5354 if (i >= sizeof(parms) / sizeof(struct osst_dev_parm))
5355 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5357 stp = strchr(stp, ',');
5366 __setup("osst=", osst_setup);
5370 static struct file_operations osst_fops = {
5371 .owner = THIS_MODULE,
5373 .write = osst_write,
5374 .ioctl = osst_ioctl,
5375 .open = os_scsi_tape_open,
5376 .flush = os_scsi_tape_flush,
5377 .release = os_scsi_tape_close,
5380 static int osst_supports(Scsi_Device * SDp)
5382 struct osst_support_data {
5386 char *driver_hint; /* Name of the correct driver, NULL if unknown */
5389 static struct osst_support_data support_list[] = {
5390 /* {"XXX", "Yy-", "", NULL}, example */
5394 struct osst_support_data *rp;
5396 /* We are willing to drive OnStream SC-x0 as well as the
5397 * * IDE, ParPort, FireWire, USB variants, if accessible by
5398 * * emulation layer (ide-scsi, usb-storage, ...) */
5400 for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5401 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5402 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5403 !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5409 * osst startup / cleanup code
5412 static int osst_probe(struct device *dev)
5414 Scsi_Device * SDp = to_scsi_device(dev);
5415 OS_Scsi_Tape * tpnt;
5416 struct st_modedef * STm;
5417 struct st_partstat * STps;
5418 OSST_buffer * buffer;
5419 struct gendisk * drive;
5420 int i, mode, dev_num;
5422 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5425 drive = alloc_disk(1);
5427 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5431 /* if this is the first attach, build the infrastructure */
5432 write_lock(&os_scsi_tapes_lock);
5433 if (os_scsi_tapes == NULL) {
5435 (OS_Scsi_Tape **)kmalloc(osst_max_dev * sizeof(OS_Scsi_Tape *),
5437 if (os_scsi_tapes == NULL) {
5438 write_unlock(&os_scsi_tapes_lock);
5439 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5442 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5445 if (osst_nr_dev >= osst_max_dev) {
5446 write_unlock(&os_scsi_tapes_lock);
5447 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5451 /* find a free minor number */
5452 for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++);
5453 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5456 /* allocate a OS_Scsi_Tape for this device */
5457 tpnt = (OS_Scsi_Tape *)kmalloc(sizeof(OS_Scsi_Tape), GFP_ATOMIC);
5459 write_unlock(&os_scsi_tapes_lock);
5460 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5463 memset(tpnt, 0, sizeof(OS_Scsi_Tape));
5465 /* allocate a buffer for this device */
5466 i = SDp->host->sg_tablesize;
5467 if (osst_max_sg_segs < i)
5468 i = osst_max_sg_segs;
5469 buffer = new_tape_buffer(TRUE, SDp->host->unchecked_isa_dma, i);
5470 if (buffer == NULL) {
5471 write_unlock(&os_scsi_tapes_lock);
5472 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5476 os_scsi_tapes[dev_num] = tpnt;
5477 tpnt->buffer = buffer;
5479 drive->private_data = &tpnt->driver;
5480 sprintf(drive->disk_name, "osst%d", dev_num);
5481 tpnt->driver = &osst_template;
5482 tpnt->drive = drive;
5484 tpnt->capacity = 0xfffff;
5486 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
5487 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5489 tpnt->do_auto_lock = OSST_AUTO_LOCK;
5490 tpnt->can_bsr = OSST_IN_FILE_POS;
5491 tpnt->can_partitions = 0;
5492 tpnt->two_fm = OSST_TWO_FM;
5493 tpnt->fast_mteom = OSST_FAST_MTEOM;
5494 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5495 tpnt->write_threshold = osst_write_threshold;
5496 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5497 tpnt->partition = 0;
5498 tpnt->new_partition = 0;
5499 tpnt->nbr_partitions = 0;
5500 tpnt->min_block = 512;
5501 tpnt->max_block = OS_DATA_SIZE;
5502 tpnt->timeout = OSST_TIMEOUT;
5503 tpnt->long_timeout = OSST_LONG_TIMEOUT;
5505 /* Recognize OnStream tapes */
5506 /* We don't need to test for OnStream, as this has been done in detect () */
5507 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5508 tpnt->omit_blklims = 1;
5510 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5511 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5512 tpnt->frame_in_buffer = 0;
5513 tpnt->header_ok = 0;
5514 tpnt->linux_media = 0;
5515 tpnt->header_cache = NULL;
5517 for (i=0; i < ST_NBR_MODES; i++) {
5518 STm = &(tpnt->modes[i]);
5519 STm->defined = FALSE;
5520 STm->sysv = OSST_SYSV;
5521 STm->defaults_for_writes = 0;
5522 STm->do_async_writes = OSST_ASYNC_WRITES;
5523 STm->do_buffer_writes = OSST_BUFFER_WRITES;
5524 STm->do_read_ahead = OSST_READ_AHEAD;
5525 STm->default_compression = ST_DONT_TOUCH;
5526 STm->default_blksize = 512;
5527 STm->default_density = (-1); /* No forced density */
5530 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5531 STps = &(tpnt->ps[i]);
5533 STps->eof = ST_NOEOF;
5535 STps->last_block_valid = FALSE;
5536 STps->drv_block = (-1);
5537 STps->drv_file = (-1);
5540 tpnt->current_mode = 0;
5541 tpnt->modes[0].defined = TRUE;
5542 tpnt->modes[2].defined = TRUE;
5543 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = FALSE;
5545 init_MUTEX(&tpnt->lock);
5547 write_unlock(&os_scsi_tapes_lock);
5549 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
5551 devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)),
5552 S_IFCHR | S_IRUGO | S_IWUGO,
5553 "%s/ot%s", SDp->devfs_name, osst_formats[mode]);
5555 /* No-rewind entry */
5556 devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5) + 128),
5557 S_IFCHR | S_IRUGO | S_IWUGO,
5558 "%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
5560 drive->number = devfs_register_tape(SDp->devfs_name);
5563 "osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as %s\n",
5564 SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, tape_name(tpnt));
5573 static int osst_remove(struct device *dev)
5575 Scsi_Device * SDp = to_scsi_device(dev);
5576 OS_Scsi_Tape * tpnt;
5579 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
5582 write_lock(&os_scsi_tapes_lock);
5583 for(i=0; i < osst_max_dev; i++) {
5584 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
5585 tpnt->device = NULL;
5586 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
5587 devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]);
5588 devfs_remove("%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
5590 devfs_unregister_tape(tpnt->drive->number);
5591 put_disk(tpnt->drive);
5592 os_scsi_tapes[i] = NULL;
5594 write_unlock(&os_scsi_tapes_lock);
5595 if (tpnt->header_cache != NULL) vfree(tpnt->header_cache);
5597 normalize_buffer(tpnt->buffer);
5598 kfree(tpnt->buffer);
5604 write_unlock(&os_scsi_tapes_lock);
5608 static int __init init_osst(void)
5610 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
5614 if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
5615 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
5622 static void __exit exit_osst (void)
5627 scsi_unregister_driver(&osst_template.gendrv);
5628 unregister_chrdev(OSST_MAJOR, "osst");
5630 if (os_scsi_tapes) {
5631 for (i=0; i < osst_max_dev; ++i) {
5632 if (!(STp = os_scsi_tapes[i])) continue;
5633 /* This is defensive, supposed to happen during detach */
5634 if (STp->header_cache)
5635 vfree(STp->header_cache);
5637 normalize_buffer(STp->buffer);
5640 put_disk(STp->drive);
5643 kfree(os_scsi_tapes);
5645 printk(KERN_INFO "osst :I: Unloaded.\n");
5648 module_init(init_osst);
5649 module_exit(exit_osst);