2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
3 file Documentation/scsi/st.txt for more information.
7 OnStream SCSI Tape support (osst) cloned from st.c by
8 Willem Riede (osst@riede.org) Feb 2000
9 Fixes ... Kurt Garloff <garloff@suse.de> Mar 2000
11 Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
12 Contribution and ideas from several people including (in alphabetical
13 order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
14 Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
16 Copyright 1992 - 2002 Kai Makisara / 2000 - 2004 Willem Riede
19 $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
21 Microscopic alterations - Rik Ling, 2000/12/21
22 Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
23 Some small formal changes - aeb, 950809
26 static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $";
27 const char * osst_version = "0.99.3";
29 /* The "failure to reconnect" firmware bug */
30 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
31 #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/
32 #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
34 #include <linux/module.h>
37 #include <linux/kernel.h>
38 #include <linux/sched.h>
39 #include <linux/proc_fs.h>
41 #include <linux/init.h>
42 #include <linux/string.h>
43 #include <linux/errno.h>
44 #include <linux/mtio.h>
45 #include <linux/ioctl.h>
46 #include <linux/fcntl.h>
47 #include <linux/spinlock.h>
48 #include <linux/vmalloc.h>
49 #include <linux/blkdev.h>
50 #include <linux/moduleparam.h>
51 #include <linux/devfs_fs_kernel.h>
52 #include <linux/delay.h>
53 #include <asm/uaccess.h>
55 #include <asm/system.h>
57 /* The driver prints some debugging information on the console if DEBUG
58 is defined and non-zero. */
61 /* The message level for the debug messages is currently set to KERN_NOTICE
62 so that people can easily see the messages. Later when the debugging messages
63 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
64 #define OSST_DEB_MSG KERN_NOTICE
66 #include <scsi/scsi.h>
67 #include <scsi/scsi_dbg.h>
68 #include <scsi/scsi_device.h>
69 #include <scsi/scsi_driver.h>
70 #include <scsi/scsi_eh.h>
71 #include <scsi/scsi_host.h>
72 #include <scsi/scsi_ioctl.h>
73 #include <scsi/scsi_request.h>
75 #define ST_KILOBYTE 1024
79 #include "osst_options.h"
80 #include "osst_detect.h"
82 static int max_dev = 0;
83 static int write_threshold_kbs = 0;
84 static int max_sg_segs = 0;
87 MODULE_AUTHOR("Willem Riede");
88 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
89 MODULE_LICENSE("GPL");
91 module_param(max_dev, int, 0444);
92 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
94 module_param(write_threshold_kbs, int, 0644);
95 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
97 module_param(max_sg_segs, int, 0644);
98 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
100 static struct osst_dev_parm {
103 } parms[] __initdata = {
104 { "max_dev", &max_dev },
105 { "write_threshold_kbs", &write_threshold_kbs },
106 { "max_sg_segs", &max_sg_segs }
110 static char *osst_formats[ST_NBR_MODES] ={"", "l", "m", "a"};
112 /* Some default definitions have been moved to osst_options.h */
113 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
114 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
116 /* The buffer size should fit into the 24 bits for length in the
117 6-byte SCSI read and write commands. */
118 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
119 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
123 static int debugging = 1;
124 /* uncomment define below to test error recovery */
125 // #define OSST_INJECT_ERRORS 1
128 /* Do not retry! The drive firmware already retries when appropriate,
129 and when it tries to tell us something, we had better listen... */
130 #define MAX_RETRIES 0
132 #define NO_TAPE NOT_READY
134 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
135 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
136 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
138 #define OSST_TIMEOUT (200 * HZ)
139 #define OSST_LONG_TIMEOUT (1800 * HZ)
141 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
142 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
143 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
144 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
146 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
148 #define SET_DENS_AND_BLK 0x10001
150 static int osst_buffer_size = OSST_BUFFER_SIZE;
151 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
152 static int osst_max_sg_segs = OSST_MAX_SG;
153 static int osst_max_dev = OSST_MAX_TAPES;
154 static int osst_nr_dev;
156 static struct osst_tape **os_scsi_tapes = NULL;
157 static DEFINE_RWLOCK(os_scsi_tapes_lock);
159 static int modes_defined = 0;
161 static struct osst_buffer *new_tape_buffer(int, int, int);
162 static int enlarge_buffer(struct osst_buffer *, int);
163 static void normalize_buffer(struct osst_buffer *);
164 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
165 static int from_buffer(struct osst_buffer *, char __user *, int);
166 static int osst_zero_buffer_tail(struct osst_buffer *);
167 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
168 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
170 static int osst_probe(struct device *);
171 static int osst_remove(struct device *);
173 struct scsi_driver osst_template = {
174 .owner = THIS_MODULE,
178 .remove = osst_remove,
182 static int osst_int_ioctl(struct osst_tape *STp, struct scsi_request ** aSRpnt,
183 unsigned int cmd_in, unsigned long arg);
185 static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int frame, int skip);
187 static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt);
189 static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt);
191 static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending);
193 static inline char *tape_name(struct osst_tape *tape)
195 return tape->drive->disk_name;
198 /* Routines that handle the interaction with mid-layer SCSI routines */
200 /* Convert the result to success code */
201 static int osst_chk_result(struct osst_tape * STp, struct scsi_request * SRpnt)
203 char *name = tape_name(STp);
204 int result = SRpnt->sr_result;
205 unsigned char * sense = SRpnt->sr_sense_buffer, scode;
211 sense[0] = 0; /* We don't have sense data if this byte is zero */
214 if ((driver_byte(result) & DRIVER_MASK) == DRIVER_SENSE)
215 scode = sense[2] & 0x0f;
217 sense[0] = 0; /* We don't have sense data if this byte is zero */
222 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
224 SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
225 SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
227 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
228 name, scode, sense[12], sense[13]);
229 if (driver_byte(result) & DRIVER_SENSE)
230 scsi_print_req_sense("osst ", SRpnt);
234 if (!(driver_byte(result) & DRIVER_SENSE) ||
235 ((sense[0] & 0x70) == 0x70 &&
237 scode != RECOVERED_ERROR &&
238 /* scode != UNIT_ATTENTION && */
239 scode != BLANK_CHECK &&
240 scode != VOLUME_OVERFLOW &&
241 SRpnt->sr_cmnd[0] != MODE_SENSE &&
242 SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
243 if (driver_byte(result) & DRIVER_SENSE) {
244 printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
245 scsi_print_req_sense("osst:", SRpnt);
248 static int notyetprinted = 1;
251 "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
252 name, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
257 "%s:I: This warning may be caused by your scsi controller,\n", name);
259 "%s:I: it has been reported with some Buslogic cards.\n", name);
263 STp->pos_unknown |= STp->device->was_reset;
265 if ((sense[0] & 0x70) == 0x70 &&
266 scode == RECOVERED_ERROR) {
267 STp->recover_count++;
268 STp->recover_erreg++;
271 if (SRpnt->sr_cmnd[0] == READ_6)
273 else if (SRpnt->sr_cmnd[0] == WRITE_6)
277 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
281 if ((sense[2] & 0xe0) == 0)
288 /* Wakeup from interrupt */
289 static void osst_sleep_done (struct scsi_cmnd * SCpnt)
291 struct osst_tape * STp = container_of(SCpnt->request->rq_disk->private_data, struct osst_tape, driver);
293 if ((STp->buffer)->writing &&
294 (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
295 (SCpnt->sense_buffer[2] & 0x40)) {
296 /* EOM at write-behind, has all been written? */
297 if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
298 STp->buffer->midlevel_result = SCpnt->result; /* Error */
300 STp->buffer->midlevel_result = INT_MAX; /* OK */
303 STp->buffer->midlevel_result = SCpnt->result;
304 SCpnt->request->rq_status = RQ_SCSI_DONE;
305 STp->buffer->last_SRpnt = SCpnt->sc_request;
308 STp->write_pending = 0;
310 complete(SCpnt->request->waiting);
314 /* Do the scsi command. Waits until command performed if do_wait is true.
315 Otherwise osst_write_behind_check() is used to check that the command
317 static struct scsi_request * osst_do_scsi(struct scsi_request *SRpnt, struct osst_tape *STp,
318 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
321 #ifdef OSST_INJECT_ERRORS
322 static int inject = 0;
323 static int repeat = 0;
326 if ((SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC)) == NULL) {
327 printk(KERN_ERR "%s:E: Can't get SCSI request.\n", tape_name(STp));
328 if (signal_pending(current))
329 (STp->buffer)->syscall_result = (-EINTR);
331 (STp->buffer)->syscall_result = (-EBUSY);
336 init_completion(&STp->wait);
337 SRpnt->sr_use_sg = (bytes > (STp->buffer)->sg[0].length) ?
338 (STp->buffer)->use_sg : 0;
339 if (SRpnt->sr_use_sg) {
340 bp = (char *)&(STp->buffer->sg[0]);
341 if (STp->buffer->sg_segs < SRpnt->sr_use_sg)
342 SRpnt->sr_use_sg = STp->buffer->sg_segs;
345 bp = (STp->buffer)->b_data;
346 SRpnt->sr_data_direction = direction;
347 SRpnt->sr_cmd_len = 0;
348 SRpnt->sr_request->waiting = &(STp->wait);
349 SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
350 SRpnt->sr_request->rq_disk = STp->drive;
352 scsi_do_req(SRpnt, (void *)cmd, bp, bytes, osst_sleep_done, timeout, retries);
355 wait_for_completion(SRpnt->sr_request->waiting);
356 SRpnt->sr_request->waiting = NULL;
357 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
358 #ifdef OSST_INJECT_ERRORS
359 if (STp->buffer->syscall_result == 0 &&
362 ( (++ inject % 83) == 29 ||
363 (STp->first_frame_position == 240
364 /* or STp->read_error_frame to fail again on the block calculated above */ &&
366 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
367 STp->buffer->last_result_fatal = 1;
375 /* Handle the write-behind checking (downs the semaphore) */
376 static void osst_write_behind_check(struct osst_tape *STp)
378 struct osst_buffer * STbuffer;
380 STbuffer = STp->buffer;
383 if (STp->write_pending)
388 wait_for_completion(&(STp->wait));
389 (STp->buffer)->last_SRpnt->sr_request->waiting = NULL;
391 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
393 if ((STp->buffer)->syscall_result)
394 (STp->buffer)->syscall_result =
395 osst_write_error_recovery(STp, &((STp->buffer)->last_SRpnt), 1);
397 STp->first_frame_position++;
399 scsi_release_request((STp->buffer)->last_SRpnt);
401 if (STbuffer->writing < STbuffer->buffer_bytes)
402 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
404 STbuffer->buffer_bytes -= STbuffer->writing;
405 STbuffer->writing = 0;
412 /* Onstream specific Routines */
414 * Initialize the OnStream AUX
416 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
417 int logical_blk_num, int blk_sz, int blk_cnt)
419 os_aux_t *aux = STp->buffer->aux;
420 os_partition_t *par = &aux->partition;
421 os_dat_t *dat = &aux->dat;
423 if (STp->raw) return;
425 memset(aux, 0, sizeof(*aux));
426 aux->format_id = htonl(0);
427 memcpy(aux->application_sig, "LIN4", 4);
428 aux->hdwr = htonl(0);
429 aux->frame_type = frame_type;
431 switch (frame_type) {
432 case OS_FRAME_TYPE_HEADER:
433 aux->update_frame_cntr = htonl(STp->update_frame_cntr);
434 par->partition_num = OS_CONFIG_PARTITION;
435 par->par_desc_ver = OS_PARTITION_VERSION;
436 par->wrt_pass_cntr = htons(0xffff);
437 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
438 par->first_frame_ppos = htonl(0);
439 par->last_frame_ppos = htonl(0xbb7);
440 aux->frame_seq_num = htonl(0);
441 aux->logical_blk_num_high = htonl(0);
442 aux->logical_blk_num = htonl(0);
443 aux->next_mark_ppos = htonl(STp->first_mark_ppos);
445 case OS_FRAME_TYPE_DATA:
446 case OS_FRAME_TYPE_MARKER:
451 dat->dat_list[0].blk_sz = htonl(blk_sz);
452 dat->dat_list[0].blk_cnt = htons(blk_cnt);
453 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
454 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
455 dat->dat_list[0].reserved = 0;
456 case OS_FRAME_TYPE_EOD:
457 aux->update_frame_cntr = htonl(0);
458 par->partition_num = OS_DATA_PARTITION;
459 par->par_desc_ver = OS_PARTITION_VERSION;
460 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
461 par->first_frame_ppos = htonl(STp->first_data_ppos);
462 par->last_frame_ppos = htonl(STp->capacity);
463 aux->frame_seq_num = htonl(frame_seq_number);
464 aux->logical_blk_num_high = htonl(0);
465 aux->logical_blk_num = htonl(logical_blk_num);
467 default: ; /* probably FILL */
469 aux->filemark_cnt = ntohl(STp->filemark_cnt);
470 aux->phys_fm = ntohl(0xffffffff);
471 aux->last_mark_ppos = ntohl(STp->last_mark_ppos);
472 aux->last_mark_lbn = ntohl(STp->last_mark_lbn);
476 * Verify that we have the correct tape frame
478 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
480 char * name = tape_name(STp);
481 os_aux_t * aux = STp->buffer->aux;
482 os_partition_t * par = &(aux->partition);
483 struct st_partstat * STps = &(STp->ps[STp->partition]);
484 int blk_cnt, blk_sz, i;
487 if (STp->buffer->syscall_result) {
488 for (i=0; i < STp->buffer->sg_segs; i++)
489 memset(page_address(STp->buffer->sg[i].page),
490 0, STp->buffer->sg[i].length);
491 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
493 STp->buffer->buffer_bytes = OS_FRAME_SIZE;
496 if (STp->buffer->syscall_result) {
498 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
502 if (ntohl(aux->format_id) != 0) {
504 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
508 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
509 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
511 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
515 if (par->partition_num != OS_DATA_PARTITION) {
516 if (!STp->linux_media || STp->linux_media_version != 2) {
518 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
519 name, par->partition_num);
524 if (par->par_desc_ver != OS_PARTITION_VERSION) {
526 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
530 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
532 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
533 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
537 if (aux->frame_type != OS_FRAME_TYPE_DATA &&
538 aux->frame_type != OS_FRAME_TYPE_EOD &&
539 aux->frame_type != OS_FRAME_TYPE_MARKER) {
542 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
546 if (aux->frame_type == OS_FRAME_TYPE_EOD &&
547 STp->first_frame_position < STp->eod_frame_ppos) {
548 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
549 STp->first_frame_position);
552 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
555 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
556 name, ntohl(aux->frame_seq_num), frame_seq_number);
560 if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
561 STps->eof = ST_FM_HIT;
563 i = ntohl(aux->filemark_cnt);
564 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
565 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
567 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
568 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
569 i, STp->first_frame_position - 1);
571 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
572 if (i >= STp->filemark_cnt)
573 STp->filemark_cnt = i+1;
576 if (aux->frame_type == OS_FRAME_TYPE_EOD) {
577 STps->eof = ST_EOD_1;
578 STp->frame_in_buffer = 1;
580 if (aux->frame_type == OS_FRAME_TYPE_DATA) {
581 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
582 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
583 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
584 STp->buffer->read_pointer = 0;
585 STp->frame_in_buffer = 1;
587 /* See what block size was used to write file */
588 if (STp->block_size != blk_sz && blk_sz > 0) {
590 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
591 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
592 STp->block_size<1024?STp->block_size:STp->block_size/1024,
593 STp->block_size<1024?'b':'k');
594 STp->block_size = blk_sz;
595 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
597 STps->eof = ST_NOEOF;
599 STp->frame_seq_number = ntohl(aux->frame_seq_num);
600 STp->logical_blk_num = ntohl(aux->logical_blk_num);
604 if (STp->read_error_frame == 0)
605 STp->read_error_frame = STp->first_frame_position - 1;
610 * Wait for the unit to become Ready
612 static int osst_wait_ready(struct osst_tape * STp, struct scsi_request ** aSRpnt,
613 unsigned timeout, int initial_delay)
615 unsigned char cmd[MAX_COMMAND_SIZE];
616 struct scsi_request * SRpnt;
617 unsigned long startwait = jiffies;
620 char * name = tape_name(STp);
622 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
625 if (initial_delay > 0)
626 msleep(jiffies_to_msecs(initial_delay));
628 memset(cmd, 0, MAX_COMMAND_SIZE);
629 cmd[0] = TEST_UNIT_READY;
631 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
633 if (!SRpnt) return (-EBUSY);
635 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
636 (( SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
637 (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8) ) ||
638 ( SRpnt->sr_sense_buffer[2] == 6 && SRpnt->sr_sense_buffer[12] == 0x28 &&
639 SRpnt->sr_sense_buffer[13] == 0 ) )) {
642 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
643 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
649 memset(cmd, 0, MAX_COMMAND_SIZE);
650 cmd[0] = TEST_UNIT_READY;
652 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
658 if ( STp->buffer->syscall_result &&
659 osst_write_error_recovery(STp, aSRpnt, 0) ) {
661 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
662 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
663 STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
664 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
669 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
675 * Wait for a tape to be inserted in the unit
677 static int osst_wait_for_medium(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned timeout)
679 unsigned char cmd[MAX_COMMAND_SIZE];
680 struct scsi_request * SRpnt;
681 unsigned long startwait = jiffies;
684 char * name = tape_name(STp);
686 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
689 memset(cmd, 0, MAX_COMMAND_SIZE);
690 cmd[0] = TEST_UNIT_READY;
692 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
694 if (!SRpnt) return (-EBUSY);
696 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
697 SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 0x3a &&
698 SRpnt->sr_sense_buffer[13] == 0 ) {
701 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
702 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
708 memset(cmd, 0, MAX_COMMAND_SIZE);
709 cmd[0] = TEST_UNIT_READY;
711 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
717 if ( STp->buffer->syscall_result && SRpnt->sr_sense_buffer[2] != 2 &&
718 SRpnt->sr_sense_buffer[12] != 4 && SRpnt->sr_sense_buffer[13] == 1) {
720 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
721 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
722 STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
723 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
728 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
733 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct scsi_request ** aSRpnt, int frame)
737 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
738 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
739 if (retval) return (retval);
740 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
741 return (osst_get_frame_position(STp, aSRpnt));
745 * Wait for write(s) to complete
747 static int osst_flush_drive_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt)
749 unsigned char cmd[MAX_COMMAND_SIZE];
750 struct scsi_request * SRpnt;
752 int delay = OSST_WAIT_WRITE_COMPLETE;
754 char * name = tape_name(STp);
756 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
759 memset(cmd, 0, MAX_COMMAND_SIZE);
760 cmd[0] = WRITE_FILEMARKS;
763 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
765 if (!SRpnt) return (-EBUSY);
766 if (STp->buffer->syscall_result) {
767 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == 2 && SRpnt->sr_sense_buffer[12] == 4) {
768 if (SRpnt->sr_sense_buffer[13] == 8) {
769 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
772 result = osst_write_error_recovery(STp, aSRpnt, 0);
774 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
775 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
780 #define OSST_POLL_PER_SEC 10
781 static int osst_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int curr, int minlast, int to)
783 unsigned long startwait = jiffies;
784 char * name = tape_name(STp);
786 char notyetprinted = 1;
788 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
789 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
791 while (time_before (jiffies, startwait + to*HZ))
794 result = osst_get_frame_position(STp, aSRpnt);
796 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
797 return 0; /* successful recovery leaves drive ready for frame */
798 if (result < 0) break;
799 if (STp->first_frame_position == curr &&
801 (signed)STp->last_frame_position > (signed)curr + minlast) ||
802 (minlast >= 0 && STp->cur_frames > minlast)
806 if (debugging || jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC)
808 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
809 name, curr, curr+minlast, STp->first_frame_position,
810 STp->last_frame_position, STp->cur_frames,
811 result, (jiffies-startwait)/HZ,
812 (((jiffies-startwait)%HZ)*10)/HZ);
817 if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted)
819 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
820 name, curr, curr+minlast, STp->first_frame_position,
821 STp->last_frame_position, STp->cur_frames, result);
825 msleep(1000 / OSST_POLL_PER_SEC);
828 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
829 name, curr, curr+minlast, STp->first_frame_position,
830 STp->last_frame_position, STp->cur_frames,
831 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
836 static int osst_recover_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int writing)
838 struct scsi_request * SRpnt;
839 unsigned char cmd[MAX_COMMAND_SIZE];
840 unsigned long startwait = jiffies;
842 char * name = tape_name(STp);
846 char * olddata = STp->buffer->b_data;
847 int oldsize = STp->buffer->buffer_size;
849 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
851 memset(cmd, 0, MAX_COMMAND_SIZE);
852 cmd[0] = WRITE_FILEMARKS;
854 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
857 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
859 if (STp->buffer->syscall_result && (SRpnt->sr_sense_buffer[2] & 0x0f) != 2) {
861 /* some failure - not just not-ready */
862 retval = osst_write_error_recovery(STp, aSRpnt, 0);
865 set_current_state(TASK_INTERRUPTIBLE);
866 schedule_timeout (HZ / OSST_POLL_PER_SEC);
868 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
869 memset(cmd, 0, MAX_COMMAND_SIZE);
870 cmd[0] = READ_POSITION;
872 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
875 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
876 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
879 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
881 /* TODO - figure out which error conditions can be handled */
882 if (STp->buffer->syscall_result)
884 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
885 (*aSRpnt)->sr_sense_buffer[ 2] & 0x0f,
886 (*aSRpnt)->sr_sense_buffer[12],
887 (*aSRpnt)->sr_sense_buffer[13]);
893 * Read the next OnStream tape frame at the current location
895 static int osst_read_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int timeout)
897 unsigned char cmd[MAX_COMMAND_SIZE];
898 struct scsi_request * SRpnt;
901 os_aux_t * aux = STp->buffer->aux;
902 char * name = tape_name(STp);
906 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
907 retval = osst_recover_wait_frame(STp, aSRpnt, 0);
909 memset(cmd, 0, MAX_COMMAND_SIZE);
916 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
918 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
919 STp->timeout, MAX_RETRIES, 1);
924 if ((STp->buffer)->syscall_result) {
926 if (STp->read_error_frame == 0) {
927 STp->read_error_frame = STp->first_frame_position;
929 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
934 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
936 SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],
937 SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],
938 SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5],
939 SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7]);
943 STp->first_frame_position++;
948 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
951 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
952 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
953 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
954 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
955 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
956 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
957 if (aux->frame_type==2)
958 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
959 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
960 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
966 static int osst_initiate_read(struct osst_tape * STp, struct scsi_request ** aSRpnt)
968 struct st_partstat * STps = &(STp->ps[STp->partition]);
969 struct scsi_request * SRpnt ;
970 unsigned char cmd[MAX_COMMAND_SIZE];
972 char * name = tape_name(STp);
974 if (STps->rw != ST_READING) { /* Initialize read operation */
975 if (STps->rw == ST_WRITING || STp->dirty) {
976 STp->write_type = OS_WRITE_DATA;
977 osst_flush_write_buffer(STp, aSRpnt);
978 osst_flush_drive_buffer(STp, aSRpnt);
980 STps->rw = ST_READING;
981 STp->frame_in_buffer = 0;
984 * Issue a read 0 command to get the OnStream drive
985 * read frames into its buffer.
987 memset(cmd, 0, MAX_COMMAND_SIZE);
992 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
994 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
996 if ((retval = STp->buffer->syscall_result))
997 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
1003 static int osst_get_logical_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1004 int frame_seq_number, int quiet)
1006 struct st_partstat * STps = &(STp->ps[STp->partition]);
1007 char * name = tape_name(STp);
1015 * If we want just any frame (-1) and there is a frame in the buffer, return it
1017 if (frame_seq_number == -1 && STp->frame_in_buffer) {
1019 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1024 * Search and wait for the next logical tape frame
1028 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1029 name, frame_seq_number);
1030 if (STp->read_error_frame) {
1031 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1033 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1034 name, STp->read_error_frame);
1036 STp->read_error_frame = 0;
1043 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1044 name, frame_seq_number, cnt);
1046 if ( osst_initiate_read(STp, aSRpnt)
1047 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1050 position = osst_get_frame_position(STp, aSRpnt);
1051 if (position >= 0xbae && position < 0xbb8)
1053 else if (position > STp->eod_frame_ppos || ++bad == 10) {
1054 position = STp->read_error_frame - 1;
1062 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1065 osst_set_frame_position(STp, aSRpnt, position, 0);
1068 if (osst_verify_frame(STp, frame_seq_number, quiet))
1070 if (osst_verify_frame(STp, -1, quiet)) {
1071 x = ntohl(STp->buffer->aux->frame_seq_num);
1072 if (STp->fast_open) {
1074 "%s:W: Found logical frame %d instead of %d after fast open\n",
1075 name, x, frame_seq_number);
1077 STp->read_error_frame = 0;
1080 if (x > frame_seq_number) {
1082 /* positioning backwards did not bring us to the desired frame */
1083 position = STp->read_error_frame - 1;
1086 position = osst_get_frame_position(STp, aSRpnt)
1087 + frame_seq_number - x - 1;
1089 if (STp->first_frame_position >= 3000 && position < 3000)
1094 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1095 name, x, frame_seq_number,
1096 STp->first_frame_position - position);
1098 osst_set_frame_position(STp, aSRpnt, position, 0);
1104 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1106 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1108 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1111 STp->frame_in_buffer = 0;
1114 STp->recover_count++;
1115 STp->recover_erreg++;
1116 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1117 name, STp->read_error_frame);
1122 if (debugging || STps->eof)
1124 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1125 name, frame_seq_number, STp->frame_seq_number, STps->eof);
1128 STp->read_error_frame = 0;
1132 static int osst_seek_logical_blk(struct osst_tape * STp, struct scsi_request ** aSRpnt, int logical_blk_num)
1134 struct st_partstat * STps = &(STp->ps[STp->partition]);
1135 char * name = tape_name(STp);
1137 int frame_seq_estimate, ppos_estimate, move;
1139 if (logical_blk_num < 0) logical_blk_num = 0;
1141 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1142 name, logical_blk_num, STp->logical_blk_num,
1143 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1144 STp->block_size<1024?'b':'k');
1146 /* Do we know where we are? */
1147 if (STps->drv_block >= 0) {
1148 move = logical_blk_num - STp->logical_blk_num;
1149 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1150 move /= (OS_DATA_SIZE / STp->block_size);
1151 frame_seq_estimate = STp->frame_seq_number + move;
1153 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1155 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1156 else ppos_estimate = frame_seq_estimate + 20;
1157 while (++retries < 10) {
1158 if (ppos_estimate > STp->eod_frame_ppos-2) {
1159 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1160 ppos_estimate = STp->eod_frame_ppos - 2;
1162 if (frame_seq_estimate < 0) {
1163 frame_seq_estimate = 0;
1166 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1167 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1168 /* we've located the estimated frame, now does it have our block? */
1169 if (logical_blk_num < STp->logical_blk_num ||
1170 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1171 if (STps->eof == ST_FM_HIT)
1172 move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1174 move = logical_blk_num - STp->logical_blk_num;
1175 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1176 move /= (OS_DATA_SIZE / STp->block_size);
1178 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1181 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1182 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1183 STp->logical_blk_num, logical_blk_num, move);
1185 frame_seq_estimate += move;
1186 ppos_estimate += move;
1189 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1190 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1191 STp->logical_blk_num = logical_blk_num;
1194 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1195 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1196 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1199 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1200 if (STps->eof == ST_FM_HIT) {
1202 STps->drv_block = 0;
1204 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1205 STp->logical_blk_num -
1206 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1209 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1213 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1215 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1217 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1218 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1219 STp->logical_blk_num, logical_blk_num);
1221 if (frame_seq_estimate != STp->frame_seq_number)
1222 ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1227 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1228 name, logical_blk_num, STp->logical_blk_num, retries);
1232 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1233 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1234 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1235 * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1237 #define OSST_FRAME_SHIFT 6
1238 #define OSST_SECTOR_SHIFT 9
1239 #define OSST_SECTOR_MASK 0x03F
1241 static int osst_get_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt)
1245 char * name = tape_name(STp);
1248 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1249 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1250 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1251 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1252 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1253 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1255 /* do we know where we are inside a file? */
1256 if (STp->ps[STp->partition].drv_block >= 0) {
1257 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1258 STp->first_frame_position) << OSST_FRAME_SHIFT;
1259 if (STp->ps[STp->partition].rw == ST_WRITING)
1260 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1262 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1264 sector = osst_get_frame_position(STp, aSRpnt);
1266 sector <<= OSST_FRAME_SHIFT;
1271 static int osst_seek_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt, int sector)
1273 struct st_partstat * STps = &(STp->ps[STp->partition]);
1274 int frame = sector >> OSST_FRAME_SHIFT,
1275 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1278 char * name = tape_name(STp);
1280 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1281 name, sector, frame, offset);
1283 if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1285 if (frame <= STp->first_data_ppos) {
1286 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1287 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1289 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1290 if (r < 0) return r;
1292 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1293 if (r < 0) return r;
1295 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1298 STp->logical_blk_num += offset / STp->block_size;
1299 STp->buffer->read_pointer = offset;
1300 STp->buffer->buffer_bytes -= offset;
1302 STp->frame_seq_number++;
1303 STp->frame_in_buffer = 0;
1304 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1305 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1307 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1308 if (STps->eof == ST_FM_HIT) {
1310 STps->drv_block = 0;
1312 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1313 STp->logical_blk_num -
1314 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1317 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1320 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1321 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1322 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1328 * Read back the drive's internal buffer contents, as a part
1329 * of the write error recovery mechanism for old OnStream
1330 * firmware revisions.
1331 * Precondition for this function to work: all frames in the
1332 * drive's buffer must be of one type (DATA, MARK or EOD)!
1334 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1335 unsigned int frame, unsigned int skip, int pending)
1337 struct scsi_request * SRpnt = * aSRpnt;
1338 unsigned char * buffer, * p;
1339 unsigned char cmd[MAX_COMMAND_SIZE];
1340 int flag, new_frame, i;
1341 int nframes = STp->cur_frames;
1342 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1343 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1344 - (nframes + pending - 1);
1345 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1346 - (nframes + pending - 1) * blks_per_frame;
1347 char * name = tape_name(STp);
1348 unsigned long startwait = jiffies;
1350 int dbg = debugging;
1353 if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
1356 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1357 name, nframes, pending?" and one that was pending":"");
1359 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1361 if (pending && debugging)
1362 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1363 name, frame_seq_number + nframes,
1364 logical_blk_num + nframes * blks_per_frame,
1365 p[0], p[1], p[2], p[3]);
1367 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1369 memset(cmd, 0, MAX_COMMAND_SIZE);
1370 cmd[0] = 0x3C; /* Buffer Read */
1371 cmd[1] = 6; /* Retrieve Faulty Block */
1372 cmd[7] = 32768 >> 8;
1373 cmd[8] = 32768 & 0xff;
1375 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1376 STp->timeout, MAX_RETRIES, 1);
1378 if ((STp->buffer)->syscall_result || !SRpnt) {
1379 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1380 vfree((void *)buffer);
1384 osst_copy_from_buffer(STp->buffer, p);
1387 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1388 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1392 osst_get_frame_position(STp, aSRpnt);
1395 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1397 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1398 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1400 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1403 if (STp->write_type == OS_WRITE_HEADER) {
1405 p += skip * OS_DATA_SIZE;
1407 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1412 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1413 name, new_frame+i, frame_seq_number+i);
1415 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1416 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1417 osst_get_frame_position(STp, aSRpnt);
1420 if (new_frame > frame + 1000) {
1421 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1422 vfree((void *)buffer);
1425 if ( i >= nframes + pending ) break;
1428 osst_copy_to_buffer(STp->buffer, p);
1430 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1432 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1433 logical_blk_num + i*blks_per_frame,
1434 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1435 memset(cmd, 0, MAX_COMMAND_SIZE);
1443 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1444 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1445 p[0], p[1], p[2], p[3]);
1447 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1448 STp->timeout, MAX_RETRIES, 1);
1450 if (STp->buffer->syscall_result)
1453 p += OS_DATA_SIZE; i++;
1455 /* if we just sent the last frame, wait till all successfully written */
1456 if ( i == nframes + pending ) {
1458 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1460 memset(cmd, 0, MAX_COMMAND_SIZE);
1461 cmd[0] = WRITE_FILEMARKS;
1463 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1464 STp->timeout, MAX_RETRIES, 1);
1467 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1468 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1472 flag = STp->buffer->syscall_result;
1473 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1475 memset(cmd, 0, MAX_COMMAND_SIZE);
1476 cmd[0] = TEST_UNIT_READY;
1478 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1481 if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
1482 (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) {
1483 /* in the process of becoming ready */
1487 if (STp->buffer->syscall_result)
1493 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1499 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
1500 SRpnt->sr_sense_buffer[12] == 0 &&
1501 SRpnt->sr_sense_buffer[13] == 2) {
1502 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1503 vfree((void *)buffer);
1504 return (-EIO); /* hit end of tape = fail */
1506 i = ((SRpnt->sr_sense_buffer[3] << 24) |
1507 (SRpnt->sr_sense_buffer[4] << 16) |
1508 (SRpnt->sr_sense_buffer[5] << 8) |
1509 SRpnt->sr_sense_buffer[6] ) - new_frame;
1510 p = &buffer[i * OS_DATA_SIZE];
1512 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1514 osst_get_frame_position(STp, aSRpnt);
1516 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1517 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1522 /* error recovery did not successfully complete */
1523 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1524 STp->write_type == OS_WRITE_HEADER?"header":"body");
1527 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1528 vfree((void *)buffer);
1532 static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1533 unsigned int frame, unsigned int skip, int pending)
1535 unsigned char cmd[MAX_COMMAND_SIZE];
1536 struct scsi_request * SRpnt;
1537 char * name = tape_name(STp);
1539 int attempts = 1000 / skip;
1541 unsigned long startwait = jiffies;
1543 int dbg = debugging;
1546 while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1551 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1553 expected = frame+skip+STp->cur_frames+pending;
1555 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1556 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1558 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1561 set_current_state(TASK_INTERRUPTIBLE);
1562 schedule_timeout(HZ / 10);
1564 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1566 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1567 name, STp->first_frame_position,
1568 STp->last_frame_position, STp->cur_frames);
1570 frame = STp->last_frame_position;
1574 if (pending && STp->cur_frames < 50) {
1576 memset(cmd, 0, MAX_COMMAND_SIZE);
1581 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1582 name, STp->frame_seq_number-1, STp->first_frame_position);
1584 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1585 STp->timeout, MAX_RETRIES, 1);
1588 if (STp->buffer->syscall_result) { /* additional write error */
1589 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
1590 SRpnt->sr_sense_buffer[12] == 0 &&
1591 SRpnt->sr_sense_buffer[13] == 2) {
1593 "%s:E: Volume overflow in write error recovery\n",
1595 break; /* hit end of tape = fail */
1604 if (STp->cur_frames == 0) {
1607 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1609 if (STp->first_frame_position != expected) {
1610 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1611 name, STp->first_frame_position, expected);
1618 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1619 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1623 set_current_state(TASK_INTERRUPTIBLE);
1624 schedule_timeout(HZ / 10);
1626 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1634 * Error recovery algorithm for the OnStream tape.
1637 static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending)
1639 struct scsi_request * SRpnt = * aSRpnt;
1640 struct st_partstat * STps = & STp->ps[STp->partition];
1641 char * name = tape_name(STp);
1644 unsigned int frame, skip;
1646 rw_state = STps->rw;
1648 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) != 3
1649 || SRpnt->sr_sense_buffer[12] != 12
1650 || SRpnt->sr_sense_buffer[13] != 0) {
1652 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1653 SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
1657 frame = (SRpnt->sr_sense_buffer[3] << 24) |
1658 (SRpnt->sr_sense_buffer[4] << 16) |
1659 (SRpnt->sr_sense_buffer[5] << 8) |
1660 SRpnt->sr_sense_buffer[6];
1661 skip = SRpnt->sr_sense_buffer[9];
1664 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1666 osst_get_frame_position(STp, aSRpnt);
1668 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1669 name, STp->first_frame_position, STp->last_frame_position);
1671 switch (STp->write_type) {
1674 case OS_WRITE_NEW_MARK:
1676 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1677 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1678 if (STp->os_fw_rev >= 10600)
1679 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1681 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1682 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1684 retval?"" :"Don't worry, ",
1685 retval?" not ":" ");
1687 case OS_WRITE_LAST_MARK:
1688 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1689 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1692 case OS_WRITE_HEADER:
1693 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1694 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1697 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1698 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1700 osst_get_frame_position(STp, aSRpnt);
1702 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1703 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1704 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1707 STp->recover_count++;
1708 STp->recover_erreg++;
1712 STps->rw = rw_state;
1716 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1717 int mt_op, int mt_count)
1719 char * name = tape_name(STp);
1721 int last_mark_ppos = -1;
1724 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1726 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1728 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1732 if (STp->linux_media_version >= 4) {
1734 * direct lookup in header filemark list
1736 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1737 if (STp->header_ok &&
1738 STp->header_cache != NULL &&
1739 (cnt - mt_count) >= 0 &&
1740 (cnt - mt_count) < OS_FM_TAB_MAX &&
1741 (cnt - mt_count) < STp->filemark_cnt &&
1742 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1744 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1746 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1747 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1748 STp->header_cache == NULL?"lack of header cache":"count out of range");
1750 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1752 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1753 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1754 STp->buffer->aux->last_mark_ppos))?"match":"error",
1755 mt_count, last_mark_ppos);
1757 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1758 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1759 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1762 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1766 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1767 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1768 name, last_mark_ppos);
1774 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1778 while (cnt != mt_count) {
1779 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1780 if (last_mark_ppos == -1)
1783 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1785 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1787 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1789 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1793 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1794 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1795 name, last_mark_ppos);
1800 if (mt_op == MTBSFM) {
1801 STp->frame_seq_number++;
1802 STp->frame_in_buffer = 0;
1803 STp->buffer->buffer_bytes = 0;
1804 STp->buffer->read_pointer = 0;
1805 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1811 * ADRL 1.1 compatible "slow" space filemarks fwd version
1813 * Just scans for the filemark sequentially.
1815 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1816 int mt_op, int mt_count)
1820 char * name = tape_name(STp);
1822 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1824 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1826 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1831 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1833 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1837 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1839 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1841 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1843 if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1845 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1846 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1848 STp->eod_frame_ppos = STp->first_frame_position-1;
1852 if (cnt == mt_count)
1854 STp->frame_in_buffer = 0;
1856 if (mt_op == MTFSF) {
1857 STp->frame_seq_number++;
1858 STp->frame_in_buffer = 0;
1859 STp->buffer->buffer_bytes = 0;
1860 STp->buffer->read_pointer = 0;
1861 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1867 * Fast linux specific version of OnStream FSF
1869 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1870 int mt_op, int mt_count)
1872 char * name = tape_name(STp);
1874 next_mark_ppos = -1;
1877 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
1879 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1881 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1886 if (STp->linux_media_version >= 4) {
1888 * direct lookup in header filemark list
1890 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
1891 if (STp->header_ok &&
1892 STp->header_cache != NULL &&
1893 (cnt + mt_count) < OS_FM_TAB_MAX &&
1894 (cnt + mt_count) < STp->filemark_cnt &&
1895 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1896 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
1898 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
1900 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
1901 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1902 STp->header_cache == NULL?"lack of header cache":"count out of range");
1904 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1906 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1907 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
1908 STp->buffer->aux->last_mark_ppos))?"match":"error",
1909 mt_count, next_mark_ppos);
1911 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
1913 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1915 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1917 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);
1930 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
1931 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
1932 name, cnt+mt_count, next_mark_ppos,
1933 ntohl(STp->buffer->aux->filemark_cnt));
1939 * Find nearest (usually previous) marker, then jump from marker to marker
1942 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1944 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1946 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1950 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
1951 if (STp->first_mark_ppos == -1) {
1953 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1955 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1957 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
1958 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1961 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
1966 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1967 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
1968 name, STp->first_mark_ppos);
1972 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
1978 while (cnt != mt_count) {
1979 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
1980 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
1982 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1984 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
1987 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
1989 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
1991 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1993 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
1998 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1999 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2000 name, next_mark_ppos);
2005 if (mt_op == MTFSF) {
2006 STp->frame_seq_number++;
2007 STp->frame_in_buffer = 0;
2008 STp->buffer->buffer_bytes = 0;
2009 STp->buffer->read_pointer = 0;
2010 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2016 * In debug mode, we want to see as many errors as possible
2017 * to test the error recovery mechanism.
2020 static void osst_set_retries(struct osst_tape * STp, struct scsi_request ** aSRpnt, int retries)
2022 unsigned char cmd[MAX_COMMAND_SIZE];
2023 struct scsi_request * SRpnt = * aSRpnt;
2024 char * name = tape_name(STp);
2026 memset(cmd, 0, MAX_COMMAND_SIZE);
2027 cmd[0] = MODE_SELECT;
2029 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2031 (STp->buffer)->b_data[0] = cmd[4] - 1;
2032 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
2033 (STp->buffer)->b_data[2] = 0; /* Reserved */
2034 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
2035 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2036 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2037 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2038 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2041 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2043 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2046 if ((STp->buffer)->syscall_result)
2047 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2052 static int osst_write_filemark(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2055 int this_mark_ppos = STp->first_frame_position;
2056 int this_mark_lbn = STp->logical_blk_num;
2058 char * name = tape_name(STp);
2061 if (STp->raw) return 0;
2063 STp->write_type = OS_WRITE_NEW_MARK;
2065 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2066 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2069 result = osst_flush_write_buffer(STp, aSRpnt);
2070 result |= osst_flush_drive_buffer(STp, aSRpnt);
2071 STp->last_mark_ppos = this_mark_ppos;
2072 STp->last_mark_lbn = this_mark_lbn;
2073 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2074 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2075 if (STp->filemark_cnt++ == 0)
2076 STp->first_mark_ppos = this_mark_ppos;
2080 static int osst_write_eod(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2084 char * name = tape_name(STp);
2087 if (STp->raw) return 0;
2089 STp->write_type = OS_WRITE_EOD;
2090 STp->eod_frame_ppos = STp->first_frame_position;
2092 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2093 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2097 result = osst_flush_write_buffer(STp, aSRpnt);
2098 result |= osst_flush_drive_buffer(STp, aSRpnt);
2099 STp->eod_frame_lfa = --(STp->frame_seq_number);
2103 static int osst_write_filler(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count)
2105 char * name = tape_name(STp);
2108 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2110 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2111 osst_set_frame_position(STp, aSRpnt, where, 0);
2112 STp->write_type = OS_WRITE_FILLER;
2114 memcpy(STp->buffer->b_data, "Filler", 6);
2115 STp->buffer->buffer_bytes = 6;
2117 if (osst_flush_write_buffer(STp, aSRpnt)) {
2118 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2123 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2125 return osst_flush_drive_buffer(STp, aSRpnt);
2128 static int __osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count)
2130 char * name = tape_name(STp);
2134 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2136 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2137 osst_set_frame_position(STp, aSRpnt, where, 0);
2138 STp->write_type = OS_WRITE_HEADER;
2140 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2141 STp->buffer->buffer_bytes = sizeof(os_header_t);
2143 if (osst_flush_write_buffer(STp, aSRpnt)) {
2144 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2148 result = osst_flush_drive_buffer(STp, aSRpnt);
2150 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2155 static int osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int locate_eod)
2157 os_header_t * header;
2159 char * name = tape_name(STp);
2162 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2164 if (STp->raw) return 0;
2166 if (STp->header_cache == NULL) {
2167 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2168 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2171 memset(STp->header_cache, 0, sizeof(os_header_t));
2173 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2176 if (STp->header_ok) STp->update_frame_cntr++;
2177 else STp->update_frame_cntr = 0;
2179 header = STp->header_cache;
2180 strcpy(header->ident_str, "ADR_SEQ");
2181 header->major_rev = 1;
2182 header->minor_rev = 4;
2183 header->ext_trk_tb_off = htons(17192);
2184 header->pt_par_num = 1;
2185 header->partition[0].partition_num = OS_DATA_PARTITION;
2186 header->partition[0].par_desc_ver = OS_PARTITION_VERSION;
2187 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2188 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2189 header->partition[0].last_frame_ppos = htonl(STp->capacity);
2190 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2191 header->cfg_col_width = htonl(20);
2192 header->dat_col_width = htonl(1500);
2193 header->qfa_col_width = htonl(0);
2194 header->ext_track_tb.nr_stream_part = 1;
2195 header->ext_track_tb.et_ent_sz = 32;
2196 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2197 header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2198 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2199 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2200 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa);
2201 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
2202 header->dat_fm_tab.fm_part_num = 0;
2203 header->dat_fm_tab.fm_tab_ent_sz = 4;
2204 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2205 STp->filemark_cnt:OS_FM_TAB_MAX);
2207 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2208 if (STp->update_frame_cntr == 0)
2209 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2210 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2214 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2216 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2219 printk(KERN_ERR "%s:E: Write header failed\n", name);
2221 memcpy(STp->application_sig, "LIN4", 4);
2222 STp->linux_media = 1;
2223 STp->linux_media_version = 4;
2229 static int osst_reset_header(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2231 if (STp->header_cache != NULL)
2232 memset(STp->header_cache, 0, sizeof(os_header_t));
2234 STp->logical_blk_num = STp->frame_seq_number = 0;
2235 STp->frame_in_buffer = 0;
2236 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2237 STp->filemark_cnt = 0;
2238 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2239 return osst_write_header(STp, aSRpnt, 1);
2242 static int __osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt, int ppos)
2244 char * name = tape_name(STp);
2245 os_header_t * header;
2248 int linux_media_version,
2254 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2255 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2256 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2257 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2258 if (osst_initiate_read (STp, aSRpnt)) {
2259 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2263 if (osst_read_frame(STp, aSRpnt, 180)) {
2265 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2269 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2270 aux = STp->buffer->aux;
2271 if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2273 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2277 if (ntohl(aux->frame_seq_num) != 0 ||
2278 ntohl(aux->logical_blk_num) != 0 ||
2279 aux->partition.partition_num != OS_CONFIG_PARTITION ||
2280 ntohl(aux->partition.first_frame_ppos) != 0 ||
2281 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2283 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2284 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2285 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2286 ntohl(aux->partition.last_frame_ppos));
2290 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2291 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2292 strlcpy(id_string, header->ident_str, 8);
2294 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2298 update_frame_cntr = ntohl(aux->update_frame_cntr);
2299 if (update_frame_cntr < STp->update_frame_cntr) {
2301 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2302 name, ppos, update_frame_cntr, STp->update_frame_cntr);
2306 if (header->major_rev != 1 || header->minor_rev != 4 ) {
2308 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2309 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2310 header->minor_rev > 4 )? "Invalid" : "Warning:",
2311 header->major_rev, header->minor_rev);
2313 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2317 if (header->pt_par_num != 1)
2318 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2319 name, header->pt_par_num);
2321 memcpy(id_string, aux->application_sig, 4);
2323 if (memcmp(id_string, "LIN", 3) == 0) {
2324 STp->linux_media = 1;
2325 linux_media_version = id_string[3] - '0';
2326 if (linux_media_version != 4)
2327 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2328 name, linux_media_version);
2330 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2333 if (linux_media_version < STp->linux_media_version) {
2335 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2336 name, ppos, linux_media_version);
2340 if (linux_media_version > STp->linux_media_version) {
2342 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2343 name, ppos, linux_media_version);
2345 memcpy(STp->application_sig, id_string, 5);
2346 STp->linux_media_version = linux_media_version;
2347 STp->update_frame_cntr = -1;
2349 if (update_frame_cntr > STp->update_frame_cntr) {
2351 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2352 name, ppos, update_frame_cntr);
2354 if (STp->header_cache == NULL) {
2355 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2356 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2360 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2363 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2364 header = STp->header_cache; /* further accesses from cached (full) copy */
2366 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2367 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2368 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2369 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2370 STp->filemark_cnt = ntohl(aux->filemark_cnt);
2371 STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2372 STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2373 STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2374 STp->update_frame_cntr = update_frame_cntr;
2376 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2377 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2378 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2379 STp->first_data_ppos,
2380 ntohl(header->partition[0].last_frame_ppos),
2381 ntohl(header->partition[0].eod_frame_ppos));
2382 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2383 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2385 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2387 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2389 memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2390 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2391 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2393 if (header->minor_rev == 4 &&
2394 (header->ext_trk_tb_off != htons(17192) ||
2395 header->partition[0].partition_num != OS_DATA_PARTITION ||
2396 header->partition[0].par_desc_ver != OS_PARTITION_VERSION ||
2397 header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2398 header->cfg_col_width != htonl(20) ||
2399 header->dat_col_width != htonl(1500) ||
2400 header->qfa_col_width != htonl(0) ||
2401 header->ext_track_tb.nr_stream_part != 1 ||
2402 header->ext_track_tb.et_ent_sz != 32 ||
2403 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION ||
2404 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2405 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2406 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2407 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) ||
2408 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION ||
2409 header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2410 header->dat_fm_tab.fm_tab_ent_cnt !=
2411 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2412 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2419 static int osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2424 char * name = tape_name(STp);
2426 position = osst_get_frame_position(STp, aSRpnt);
2429 STp->header_ok = STp->linux_media = 1;
2430 STp->linux_media_version = 0;
2433 STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2434 STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2435 STp->eod_frame_ppos = STp->first_data_ppos = -1;
2436 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2438 printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2441 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2442 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2444 first = position==10?0xbae: 5;
2445 last = position==10?0xbb3:10;
2447 for (ppos = first; ppos < last; ppos++)
2448 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2451 first = position==10? 5:0xbae;
2452 last = position==10?10:0xbb3;
2454 for (ppos = first; ppos < last; ppos++)
2455 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2459 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2460 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2461 osst_set_frame_position(STp, aSRpnt, 10, 0);
2464 if (position <= STp->first_data_ppos) {
2465 position = STp->first_data_ppos;
2466 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2468 osst_set_frame_position(STp, aSRpnt, position, 0);
2474 static int osst_verify_position(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2476 int frame_position = STp->first_frame_position;
2477 int frame_seq_numbr = STp->frame_seq_number;
2478 int logical_blk_num = STp->logical_blk_num;
2479 int halfway_frame = STp->frame_in_buffer;
2480 int read_pointer = STp->buffer->read_pointer;
2481 int prev_mark_ppos = -1;
2482 int actual_mark_ppos, i, n;
2484 char * name = tape_name(STp);
2486 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2488 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2489 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2491 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2495 if (STp->linux_media_version >= 4) {
2496 for (i=0; i<STp->filemark_cnt; i++)
2497 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2500 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2501 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2502 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2503 if (frame_position != STp->first_frame_position ||
2504 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2505 prev_mark_ppos != actual_mark_ppos ) {
2507 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2508 STp->first_frame_position, frame_position,
2509 STp->frame_seq_number + (halfway_frame?0:1),
2510 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2514 if (halfway_frame) {
2515 /* prepare buffer for append and rewrite on top of original */
2516 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2517 STp->buffer->buffer_bytes = read_pointer;
2518 STp->ps[STp->partition].rw = ST_WRITING;
2521 STp->frame_in_buffer = halfway_frame;
2522 STp->frame_seq_number = frame_seq_numbr;
2523 STp->logical_blk_num = logical_blk_num;
2527 /* Acc. to OnStream, the vers. numbering is the following:
2528 * X.XX for released versions (X=digit),
2529 * XXXY for unreleased versions (Y=letter)
2530 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2531 * This fn makes monoton numbers out of this scheme ...
2533 static unsigned int osst_parse_firmware_rev (const char * str)
2535 if (str[1] == '.') {
2536 return (str[0]-'0')*10000
2540 return (str[0]-'0')*10000
2542 +(str[2]-'0')*100 - 100
2548 * Configure the OnStream SCII tape drive for default operation
2550 static int osst_configure_onstream(struct osst_tape *STp, struct scsi_request ** aSRpnt)
2552 unsigned char cmd[MAX_COMMAND_SIZE];
2553 char * name = tape_name(STp);
2554 struct scsi_request * SRpnt = * aSRpnt;
2555 osst_mode_parameter_header_t * header;
2556 osst_block_size_page_t * bs;
2557 osst_capabilities_page_t * cp;
2558 osst_tape_paramtr_page_t * prm;
2559 int drive_buffer_size;
2561 if (STp->ready != ST_READY) {
2563 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2568 if (STp->os_fw_rev < 10600) {
2569 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2570 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2574 * Configure 32.5KB (data+aux) frame size.
2575 * Get the current frame size from the block size mode page
2577 memset(cmd, 0, MAX_COMMAND_SIZE);
2578 cmd[0] = MODE_SENSE;
2580 cmd[2] = BLOCK_SIZE_PAGE;
2581 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2583 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2584 if (SRpnt == NULL) {
2586 printk(OSST_DEB_MSG "osst :D: Busy\n");
2591 if ((STp->buffer)->syscall_result != 0) {
2592 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2596 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2597 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2600 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2601 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No");
2602 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2603 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2607 * Configure default auto columns mode, 32.5KB transfer mode
2615 memset(cmd, 0, MAX_COMMAND_SIZE);
2616 cmd[0] = MODE_SELECT;
2618 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2620 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2622 if ((STp->buffer)->syscall_result != 0) {
2623 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2628 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2630 * In debug mode, we want to see as many errors as possible
2631 * to test the error recovery mechanism.
2633 osst_set_retries(STp, aSRpnt, 0);
2638 * Set vendor name to 'LIN4' for "Linux support version 4".
2641 memset(cmd, 0, MAX_COMMAND_SIZE);
2642 cmd[0] = MODE_SELECT;
2644 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2646 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2647 header->medium_type = 0; /* Medium Type - ignoring */
2648 header->dsp = 0; /* Reserved */
2649 header->bdl = 0; /* Block Descriptor Length */
2651 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2652 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2653 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2654 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2655 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2656 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2657 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2658 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2660 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2663 if ((STp->buffer)->syscall_result != 0) {
2664 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2665 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2669 memset(cmd, 0, MAX_COMMAND_SIZE);
2670 cmd[0] = MODE_SENSE;
2672 cmd[2] = CAPABILITIES_PAGE;
2673 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2675 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2678 if ((STp->buffer)->syscall_result != 0) {
2679 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2683 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2684 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2685 sizeof(osst_mode_parameter_header_t) + header->bdl);
2687 drive_buffer_size = ntohs(cp->buffer_size) / 2;
2689 memset(cmd, 0, MAX_COMMAND_SIZE);
2690 cmd[0] = MODE_SENSE;
2692 cmd[2] = TAPE_PARAMTR_PAGE;
2693 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2695 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2698 if ((STp->buffer)->syscall_result != 0) {
2699 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2703 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2704 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2705 sizeof(osst_mode_parameter_header_t) + header->bdl);
2707 STp->density = prm->density;
2708 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2710 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2711 name, STp->density, STp->capacity / 32, drive_buffer_size);
2719 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2720 it messes up the block number). */
2721 static int cross_eof(struct osst_tape *STp, struct scsi_request ** aSRpnt, int forward)
2724 char * name = tape_name(STp);
2728 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2729 name, forward ? "forward" : "backward");
2733 /* assumes that the filemark is already read by the drive, so this is low cost */
2734 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2737 /* assumes this is only called if we just read the filemark! */
2738 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2741 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2742 name, forward ? "forward" : "backward");
2748 /* Get the tape position. */
2750 static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt)
2752 unsigned char scmd[MAX_COMMAND_SIZE];
2753 struct scsi_request * SRpnt;
2755 char * name = tape_name(STp);
2757 /* KG: We want to be able to use it for checking Write Buffer availability
2758 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2760 char * olddata = STp->buffer->b_data;
2761 int oldsize = STp->buffer->buffer_size;
2763 if (STp->ready != ST_READY) return (-EIO);
2765 memset (scmd, 0, MAX_COMMAND_SIZE);
2766 scmd[0] = READ_POSITION;
2768 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2769 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2770 STp->timeout, MAX_RETRIES, 1);
2772 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2777 if (STp->buffer->syscall_result)
2778 result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */
2780 if (result == -EINVAL)
2781 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2783 if (result == -EIO) { /* re-read position - this needs to preserve media errors */
2784 unsigned char mysense[16];
2785 memcpy (mysense, SRpnt->sr_sense_buffer, 16);
2786 memset (scmd, 0, MAX_COMMAND_SIZE);
2787 scmd[0] = READ_POSITION;
2788 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2789 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2790 STp->timeout, MAX_RETRIES, 1);
2792 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2793 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2794 SRpnt->sr_sense_buffer[2],SRpnt->sr_sense_buffer[12],SRpnt->sr_sense_buffer[13]);
2796 if (!STp->buffer->syscall_result)
2797 memcpy (SRpnt->sr_sense_buffer, mysense, 16);
2799 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2801 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2802 + ((STp->buffer)->b_data[5] << 16)
2803 + ((STp->buffer)->b_data[6] << 8)
2804 + (STp->buffer)->b_data[7];
2805 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2806 + ((STp->buffer)->b_data[ 9] << 16)
2807 + ((STp->buffer)->b_data[10] << 8)
2808 + (STp->buffer)->b_data[11];
2809 STp->cur_frames = (STp->buffer)->b_data[15];
2812 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2813 STp->first_frame_position, STp->last_frame_position,
2814 ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2815 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2819 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2821 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2822 STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2824 STp->first_frame_position = STp->last_frame_position;
2827 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2829 return (result == 0 ? STp->first_frame_position : result);
2833 /* Set the tape block */
2834 static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int ppos, int skip)
2836 unsigned char scmd[MAX_COMMAND_SIZE];
2837 struct scsi_request * SRpnt;
2838 struct st_partstat * STps;
2840 int pp = (ppos == 3000 && !skip)? 0 : ppos;
2841 char * name = tape_name(STp);
2843 if (STp->ready != ST_READY) return (-EIO);
2845 STps = &(STp->ps[STp->partition]);
2847 if (ppos < 0 || ppos > STp->capacity) {
2848 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2849 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2856 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2858 memset (scmd, 0, MAX_COMMAND_SIZE);
2861 scmd[3] = (pp >> 24);
2862 scmd[4] = (pp >> 16);
2863 scmd[5] = (pp >> 8);
2868 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
2874 if ((STp->buffer)->syscall_result != 0) {
2876 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
2877 name, STp->first_frame_position, pp);
2882 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
2883 } while ((pp != ppos) && (pp = ppos));
2884 STp->first_frame_position = STp->last_frame_position = ppos;
2885 STps->eof = ST_NOEOF;
2888 STp->frame_in_buffer = 0;
2892 static int osst_write_trailer(struct osst_tape *STp, struct scsi_request ** aSRpnt, int leave_at_EOT)
2894 struct st_partstat * STps = &(STp->ps[STp->partition]);
2897 if (STp->write_type != OS_WRITE_NEW_MARK) {
2898 /* true unless the user wrote the filemark for us */
2899 result = osst_flush_drive_buffer(STp, aSRpnt);
2900 if (result < 0) goto out;
2901 result = osst_write_filemark(STp, aSRpnt);
2902 if (result < 0) goto out;
2904 if (STps->drv_file >= 0)
2906 STps->drv_block = 0;
2908 result = osst_write_eod(STp, aSRpnt);
2909 osst_write_header(STp, aSRpnt, leave_at_EOT);
2916 /* osst versions of st functions - augmented and stripped to suit OnStream only */
2918 /* Flush the write buffer (never need to write if variable blocksize). */
2919 static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt)
2921 int offset, transfer, blks = 0;
2923 unsigned char cmd[MAX_COMMAND_SIZE];
2924 struct scsi_request * SRpnt = *aSRpnt;
2925 struct st_partstat * STps;
2926 char * name = tape_name(STp);
2928 if ((STp->buffer)->writing) {
2929 if (SRpnt == (STp->buffer)->last_SRpnt)
2931 { printk(OSST_DEB_MSG
2932 "%s:D: aSRpnt points to scsi_request that write_behind_check will release -- cleared\n", name);
2934 *aSRpnt = SRpnt = NULL;
2938 "%s:D: aSRpnt does not point to scsi_request that write_behind_check will release -- strange\n", name);
2940 osst_write_behind_check(STp);
2941 if ((STp->buffer)->syscall_result) {
2944 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
2945 name, (STp->buffer)->midlevel_result);
2947 if ((STp->buffer)->midlevel_result == INT_MAX)
2954 if (STp->dirty == 1) {
2957 STps = &(STp->ps[STp->partition]);
2958 STps->rw = ST_WRITING;
2959 offset = STp->buffer->buffer_bytes;
2960 blks = (offset + STp->block_size - 1) / STp->block_size;
2961 transfer = OS_FRAME_SIZE;
2963 if (offset < OS_DATA_SIZE)
2964 osst_zero_buffer_tail(STp->buffer);
2967 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
2968 result = osst_recover_wait_frame(STp, aSRpnt, 1);
2970 memset(cmd, 0, MAX_COMMAND_SIZE);
2975 switch (STp->write_type) {
2979 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
2980 name, blks, STp->frame_seq_number,
2981 STp->logical_blk_num - blks, STp->logical_blk_num - 1);
2983 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
2984 STp->logical_blk_num - blks, STp->block_size, blks);
2987 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
2988 STp->logical_blk_num, 0, 0);
2990 case OS_WRITE_NEW_MARK:
2991 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
2992 STp->logical_blk_num++, 0, blks=1);
2994 case OS_WRITE_HEADER:
2995 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
2997 default: /* probably FILLER */
2998 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
3002 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
3003 name, offset, transfer, blks);
3006 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3007 STp->timeout, MAX_RETRIES, 1);
3012 if ((STp->buffer)->syscall_result != 0) {
3015 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3016 name, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
3017 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
3019 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
3020 (SRpnt->sr_sense_buffer[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3021 (SRpnt->sr_sense_buffer[2] & 0x0f) == NO_SENSE) {
3023 (STp->buffer)->buffer_bytes = 0;
3027 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3028 printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3032 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
3035 STp->first_frame_position++;
3037 (STp->buffer)->buffer_bytes = 0;
3041 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3047 /* Flush the tape buffer. The tape will be positioned correctly unless
3048 seek_next is true. */
3049 static int osst_flush_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt, int seek_next)
3051 struct st_partstat * STps;
3052 int backspace = 0, result = 0;
3054 char * name = tape_name(STp);
3058 * If there was a bus reset, block further access
3061 if( STp->pos_unknown)
3064 if (STp->ready != ST_READY)
3067 STps = &(STp->ps[STp->partition]);
3068 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
3069 STp->write_type = OS_WRITE_DATA;
3070 return osst_flush_write_buffer(STp, aSRpnt);
3072 if (STp->block_size == 0)
3076 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3079 if (!STp->can_bsr) {
3080 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3081 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3082 (STp->buffer)->buffer_bytes = 0;
3083 (STp->buffer)->read_pointer = 0;
3084 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3088 if (STps->eof == ST_FM_HIT) {
3089 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3091 STps->eof = ST_NOEOF;
3093 if (STps->drv_file >= 0)
3095 STps->drv_block = 0;
3098 if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3099 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3101 else if (STps->eof == ST_FM_HIT) {
3102 if (STps->drv_file >= 0)
3104 STps->drv_block = 0;
3105 STps->eof = ST_NOEOF;
3111 static int osst_write_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int synchronous)
3113 unsigned char cmd[MAX_COMMAND_SIZE];
3114 struct scsi_request * SRpnt;
3117 char * name = tape_name(STp);
3120 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3122 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3124 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3127 /* error recovery may have bumped us past the header partition */
3128 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3130 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3132 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3137 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3138 if (osst_recover_wait_frame(STp, aSRpnt, 1))
3141 // osst_build_stats(STp, &SRpnt);
3143 STp->ps[STp->partition].rw = ST_WRITING;
3144 STp->write_type = OS_WRITE_DATA;
3146 memset(cmd, 0, MAX_COMMAND_SIZE);
3149 cmd[4] = 1; /* one frame at a time... */
3150 blks = STp->buffer->buffer_bytes / STp->block_size;
3153 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3154 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3156 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3157 STp->logical_blk_num - blks, STp->block_size, blks);
3161 STp->write_pending = 1;
3163 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3164 MAX_RETRIES, synchronous);
3170 if (STp->buffer->syscall_result != 0) {
3173 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3175 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
3176 (SRpnt->sr_sense_buffer[2] & 0x40)) {
3177 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
3181 if (osst_write_error_recovery(STp, aSRpnt, 1))
3186 STp->first_frame_position++;
3194 /* Lock or unlock the drive door. Don't use when struct scsi_request allocated. */
3195 static int do_door_lock(struct osst_tape * STp, int do_lock)
3199 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
3201 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3203 retval = scsi_ioctl(STp->device, cmd, NULL);
3205 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3208 STp->door_locked = ST_LOCK_FAILS;
3213 /* Set the internal state after reset */
3214 static void reset_state(struct osst_tape *STp)
3217 struct st_partstat *STps;
3219 STp->pos_unknown = 0;
3220 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3221 STps = &(STp->ps[i]);
3223 STps->eof = ST_NOEOF;
3225 STps->last_block_valid = 0;
3226 STps->drv_block = -1;
3227 STps->drv_file = -1;
3232 /* Entry points to osst */
3235 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3237 ssize_t total, retval = 0;
3238 ssize_t i, do_count, blks, transfer;
3239 int write_threshold;
3240 int doing_write = 0;
3241 const char __user * b_point;
3242 struct scsi_request * SRpnt = NULL;
3243 struct st_modedef * STm;
3244 struct st_partstat * STps;
3245 struct osst_tape * STp = filp->private_data;
3246 char * name = tape_name(STp);
3249 if (down_interruptible(&STp->lock))
3250 return (-ERESTARTSYS);
3253 * If we are in the middle of error recovery, don't let anyone
3254 * else try and use this device. Also, if error recovery fails, it
3255 * may try and take the device offline, in which case all further
3256 * access to the device is prohibited.
3258 if( !scsi_block_when_processing_errors(STp->device) ) {
3263 if (STp->ready != ST_READY) {
3264 if (STp->ready == ST_NO_TAPE)
3265 retval = (-ENOMEDIUM);
3270 STm = &(STp->modes[STp->current_mode]);
3271 if (!STm->defined) {
3279 * If there was a bus reset, block further access
3282 if (STp->pos_unknown) {
3289 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3295 if (STp->write_prot) {
3300 /* Write must be integral number of blocks */
3301 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3302 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3303 name, count, STp->block_size<1024?
3304 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3309 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3310 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3311 name, STp->first_frame_position);
3316 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3317 STp->door_locked = ST_LOCKED_AUTO;
3319 STps = &(STp->ps[STp->partition]);
3321 if (STps->rw == ST_READING) {
3323 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3324 STps->drv_file, STps->drv_block);
3326 retval = osst_flush_buffer(STp, &SRpnt, 0);
3331 if (STps->rw != ST_WRITING) {
3332 /* Are we totally rewriting this tape? */
3333 if (!STp->header_ok ||
3334 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3335 (STps->drv_file == 0 && STps->drv_block == 0)) {
3336 STp->wrt_pass_cntr++;
3338 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3339 name, STp->wrt_pass_cntr);
3341 osst_reset_header(STp, &SRpnt);
3342 STps->drv_file = STps->drv_block = 0;
3344 /* Do we know where we'll be writing on the tape? */
3346 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3347 STps->drv_file < 0 || STps->drv_block < 0) {
3348 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3349 STps->drv_file = STp->filemark_cnt;
3350 STps->drv_block = 0;
3353 /* We have no idea where the tape is positioned - give up */
3356 "%s:D: Cannot write at indeterminate position.\n", name);
3362 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3363 STp->filemark_cnt = STps->drv_file;
3364 STp->last_mark_ppos =
3365 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3367 "%s:W: Overwriting file %d with old write pass counter %d\n",
3368 name, STps->drv_file, STp->wrt_pass_cntr);
3370 "%s:W: may lead to stale data being accepted on reading back!\n",
3374 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3375 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3381 if (!STp->header_ok) {
3383 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3389 if ((STp->buffer)->writing) {
3390 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3391 osst_write_behind_check(STp);
3392 if ((STp->buffer)->syscall_result) {
3395 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3396 (STp->buffer)->midlevel_result);
3398 if ((STp->buffer)->midlevel_result == INT_MAX)
3399 STps->eof = ST_EOM_OK;
3401 STps->eof = ST_EOM_ERROR;
3404 if (STps->eof == ST_EOM_OK) {
3408 else if (STps->eof == ST_EOM_ERROR) {
3413 /* Check the buffer readability in cases where copy_user might catch
3414 the problems after some tape movement. */
3415 if ((copy_from_user(&i, buf, 1) != 0 ||
3416 copy_from_user(&i, buf + count - 1, 1) != 0)) {
3421 if (!STm->do_buffer_writes) {
3422 write_threshold = 1;
3425 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3426 if (!STm->do_async_writes)
3432 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3433 name, count, STps->drv_file, STps->drv_block,
3434 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3437 while ((STp->buffer)->buffer_bytes + count > write_threshold)
3440 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3441 (STp->buffer)->buffer_bytes;
3442 if (do_count > count)
3445 i = append_to_buffer(b_point, STp->buffer, do_count);
3451 blks = do_count / STp->block_size;
3452 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3454 i = osst_write_frame(STp, &SRpnt, 1);
3456 if (i == (-ENOSPC)) {
3457 transfer = STp->buffer->writing; /* FIXME -- check this logic */
3458 if (transfer <= do_count) {
3459 filp->f_pos += do_count - transfer;
3460 count -= do_count - transfer;
3461 if (STps->drv_block >= 0) {
3462 STps->drv_block += (do_count - transfer) / STp->block_size;
3464 STps->eof = ST_EOM_OK;
3465 retval = (-ENOSPC); /* EOM within current request */
3468 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3473 STps->eof = ST_EOM_ERROR;
3474 STps->drv_block = (-1); /* Too cautious? */
3475 retval = (-EIO); /* EOM for old data */
3478 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3486 if (SRpnt != NULL) {
3487 scsi_release_request(SRpnt);
3490 STp->buffer->buffer_bytes = 0;
3493 retval = total - count;
3497 filp->f_pos += do_count;
3498 b_point += do_count;
3500 if (STps->drv_block >= 0) {
3501 STps->drv_block += blks;
3503 STp->buffer->buffer_bytes = 0;
3505 } /* end while write threshold exceeded */
3509 i = append_to_buffer(b_point, STp->buffer, count);
3514 blks = count / STp->block_size;
3515 STp->logical_blk_num += blks;
3516 if (STps->drv_block >= 0) {
3517 STps->drv_block += blks;
3519 filp->f_pos += count;
3523 if (doing_write && (STp->buffer)->syscall_result != 0) {
3524 retval = (STp->buffer)->syscall_result;
3528 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3529 /* Schedule an asynchronous write */
3530 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3531 STp->block_size) * STp->block_size;
3532 STp->dirty = !((STp->buffer)->writing ==
3533 (STp->buffer)->buffer_bytes);
3535 i = osst_write_frame(STp, &SRpnt, 0);
3540 SRpnt = NULL; /* Prevent releasing this request! */
3542 STps->at_sm &= (total == 0);
3544 STps->eof = ST_NOEOF;
3549 if (SRpnt != NULL) scsi_release_request(SRpnt);
3558 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3560 ssize_t total, retval = 0;
3561 ssize_t i, transfer;
3563 struct st_modedef * STm;
3564 struct st_partstat * STps;
3565 struct scsi_request * SRpnt = NULL;
3566 struct osst_tape * STp = filp->private_data;
3567 char * name = tape_name(STp);
3570 if (down_interruptible(&STp->lock))
3571 return (-ERESTARTSYS);
3574 * If we are in the middle of error recovery, don't let anyone
3575 * else try and use this device. Also, if error recovery fails, it
3576 * may try and take the device offline, in which case all further
3577 * access to the device is prohibited.
3579 if( !scsi_block_when_processing_errors(STp->device) ) {
3584 if (STp->ready != ST_READY) {
3585 if (STp->ready == ST_NO_TAPE)
3586 retval = (-ENOMEDIUM);
3591 STm = &(STp->modes[STp->current_mode]);
3592 if (!STm->defined) {
3598 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3603 /* Must have initialized medium */
3604 if (!STp->header_ok) {
3609 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3610 STp->door_locked = ST_LOCKED_AUTO;
3612 STps = &(STp->ps[STp->partition]);
3613 if (STps->rw == ST_WRITING) {
3614 retval = osst_flush_buffer(STp, &SRpnt, 0);
3618 /* FIXME -- this may leave the tape without EOD and up2date headers */
3621 if ((count % STp->block_size) != 0) {
3623 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3624 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3628 if (debugging && STps->eof != ST_NOEOF)
3629 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3630 STps->eof, (STp->buffer)->buffer_bytes);
3632 if ((STp->buffer)->buffer_bytes == 0 &&
3633 STps->eof >= ST_EOD_1) {
3634 if (STps->eof < ST_EOD) {
3639 retval = (-EIO); /* EOM or Blank Check */
3643 /* Check the buffer writability before any tape movement. Don't alter
3645 if (copy_from_user(&i, buf, 1) != 0 ||
3646 copy_to_user (buf, &i, 1) != 0 ||
3647 copy_from_user(&i, buf + count - 1, 1) != 0 ||
3648 copy_to_user (buf + count - 1, &i, 1) != 0) {
3653 /* Loop until enough data in buffer or a special condition found */
3654 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3656 /* Get new data if the buffer is empty */
3657 if ((STp->buffer)->buffer_bytes == 0) {
3658 if (STps->eof == ST_FM_HIT)
3660 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3661 if (special < 0) { /* No need to continue read */
3662 STp->frame_in_buffer = 0;
3668 /* Move the data from driver buffer to user buffer */
3669 if ((STp->buffer)->buffer_bytes > 0) {
3671 if (debugging && STps->eof != ST_NOEOF)
3672 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3673 STps->eof, (STp->buffer)->buffer_bytes, count - total);
3675 /* force multiple of block size, note block_size may have been adjusted */
3676 transfer = (((STp->buffer)->buffer_bytes < count - total ?
3677 (STp->buffer)->buffer_bytes : count - total)/
3678 STp->block_size) * STp->block_size;
3680 if (transfer == 0) {
3682 "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
3683 name, count, STp->block_size < 1024?
3684 STp->block_size:STp->block_size/1024,
3685 STp->block_size<1024?'b':'k');
3688 i = from_buffer(STp->buffer, buf, transfer);
3693 STp->logical_blk_num += transfer / STp->block_size;
3694 STps->drv_block += transfer / STp->block_size;
3695 filp->f_pos += transfer;
3700 if ((STp->buffer)->buffer_bytes == 0) {
3703 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3704 name, STp->frame_seq_number);
3706 STp->frame_in_buffer = 0;
3707 STp->frame_seq_number++; /* frame to look for next time */
3709 } /* for (total = 0, special = 0; total < count && !special; ) */
3711 /* Change the eof state if no data from tape or buffer */
3713 if (STps->eof == ST_FM_HIT) {
3714 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3715 STps->drv_block = 0;
3716 if (STps->drv_file >= 0)
3719 else if (STps->eof == ST_EOD_1) {
3720 STps->eof = ST_EOD_2;
3721 if (STps->drv_block > 0 && STps->drv_file >= 0)
3723 STps->drv_block = 0;
3725 else if (STps->eof == ST_EOD_2)
3728 else if (STps->eof == ST_FM)
3729 STps->eof = ST_NOEOF;
3734 if (SRpnt != NULL) scsi_release_request(SRpnt);
3742 /* Set the driver options */
3743 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3746 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3747 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3748 STm->do_read_ahead);
3750 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3751 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3753 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3754 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3755 STp->scsi2_logical);
3757 "%s:I: sysv: %d\n", name, STm->sysv);
3760 "%s:D: debugging: %d\n",
3766 static int osst_set_options(struct osst_tape *STp, long options)
3770 struct st_modedef * STm;
3771 char * name = tape_name(STp);
3773 STm = &(STp->modes[STp->current_mode]);
3774 if (!STm->defined) {
3775 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3779 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3780 name, STp->current_mode);
3784 code = options & MT_ST_OPTIONS;
3785 if (code == MT_ST_BOOLEANS) {
3786 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3787 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3788 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3789 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3790 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3791 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3792 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3793 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3794 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3795 if ((STp->device)->scsi_level >= SCSI_2)
3796 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3797 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3798 STm->sysv = (options & MT_ST_SYSV) != 0;
3800 debugging = (options & MT_ST_DEBUGGING) != 0;
3802 osst_log_options(STp, STm, name);
3804 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3805 value = (code == MT_ST_SETBOOLEANS);
3806 if ((options & MT_ST_BUFFER_WRITES) != 0)
3807 STm->do_buffer_writes = value;
3808 if ((options & MT_ST_ASYNC_WRITES) != 0)
3809 STm->do_async_writes = value;
3810 if ((options & MT_ST_DEF_WRITES) != 0)
3811 STm->defaults_for_writes = value;
3812 if ((options & MT_ST_READ_AHEAD) != 0)
3813 STm->do_read_ahead = value;
3814 if ((options & MT_ST_TWO_FM) != 0)
3815 STp->two_fm = value;
3816 if ((options & MT_ST_FAST_MTEOM) != 0)
3817 STp->fast_mteom = value;
3818 if ((options & MT_ST_AUTO_LOCK) != 0)
3819 STp->do_auto_lock = value;
3820 if ((options & MT_ST_CAN_BSR) != 0)
3821 STp->can_bsr = value;
3822 if ((options & MT_ST_NO_BLKLIMS) != 0)
3823 STp->omit_blklims = value;
3824 if ((STp->device)->scsi_level >= SCSI_2 &&
3825 (options & MT_ST_CAN_PARTITIONS) != 0)
3826 STp->can_partitions = value;
3827 if ((options & MT_ST_SCSI2LOGICAL) != 0)
3828 STp->scsi2_logical = value;
3829 if ((options & MT_ST_SYSV) != 0)
3832 if ((options & MT_ST_DEBUGGING) != 0)
3835 osst_log_options(STp, STm, name);
3837 else if (code == MT_ST_WRITE_THRESHOLD) {
3838 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3839 if (value < 1 || value > osst_buffer_size) {
3840 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3844 STp->write_threshold = value;
3845 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3848 else if (code == MT_ST_DEF_BLKSIZE) {
3849 value = (options & ~MT_ST_OPTIONS);
3850 if (value == ~MT_ST_OPTIONS) {
3851 STm->default_blksize = (-1);
3852 printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3855 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3856 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3860 STm->default_blksize = value;
3861 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
3862 name, STm->default_blksize);
3865 else if (code == MT_ST_TIMEOUTS) {
3866 value = (options & ~MT_ST_OPTIONS);
3867 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
3868 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
3869 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
3870 (value & ~MT_ST_SET_LONG_TIMEOUT));
3873 STp->timeout = value * HZ;
3874 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
3877 else if (code == MT_ST_DEF_OPTIONS) {
3878 code = (options & ~MT_ST_CLEAR_DEFAULT);
3879 value = (options & MT_ST_CLEAR_DEFAULT);
3880 if (code == MT_ST_DEF_DENSITY) {
3881 if (value == MT_ST_CLEAR_DEFAULT) {
3882 STm->default_density = (-1);
3883 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
3886 STm->default_density = value & 0xff;
3887 printk(KERN_INFO "%s:I: Density default set to %x\n",
3888 name, STm->default_density);
3891 else if (code == MT_ST_DEF_DRVBUFFER) {
3892 if (value == MT_ST_CLEAR_DEFAULT) {
3893 STp->default_drvbuffer = 0xff;
3894 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
3897 STp->default_drvbuffer = value & 7;
3898 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
3899 name, STp->default_drvbuffer);
3902 else if (code == MT_ST_DEF_COMPRESSION) {
3903 if (value == MT_ST_CLEAR_DEFAULT) {
3904 STm->default_compression = ST_DONT_TOUCH;
3905 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
3908 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
3909 printk(KERN_INFO "%s:I: Compression default set to %x\n",
3921 /* Internal ioctl function */
3922 static int osst_int_ioctl(struct osst_tape * STp, struct scsi_request ** aSRpnt,
3923 unsigned int cmd_in, unsigned long arg)
3927 int i, ioctl_result;
3929 unsigned char cmd[MAX_COMMAND_SIZE];
3930 struct scsi_request * SRpnt = * aSRpnt;
3931 struct st_partstat * STps;
3932 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
3933 int datalen = 0, direction = DMA_NONE;
3934 char * name = tape_name(STp);
3936 if (STp->ready != ST_READY && cmd_in != MTLOAD) {
3937 if (STp->ready == ST_NO_TAPE)
3938 return (-ENOMEDIUM);
3942 timeout = STp->long_timeout;
3943 STps = &(STp->ps[STp->partition]);
3944 fileno = STps->drv_file;
3945 blkno = STps->drv_block;
3946 at_sm = STps->at_sm;
3947 frame_seq_numbr = STp->frame_seq_number;
3948 logical_blk_num = STp->logical_blk_num;
3950 memset(cmd, 0, MAX_COMMAND_SIZE);
3953 chg_eof = 0; /* Changed from the FSF after this */
3957 if (STp->linux_media)
3958 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
3960 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
3964 at_sm &= (arg == 0);
3968 chg_eof = 0; /* Changed from the FSF after this */
3972 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
3975 blkno = (-1); /* We can't know the block number */
3976 at_sm &= (arg == 0);
3983 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
3984 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
3986 if (cmd_in == MTFSR) {
3987 logical_blk_num += arg;
3988 if (blkno >= 0) blkno += arg;
3991 logical_blk_num -= arg;
3992 if (blkno >= 0) blkno -= arg;
3994 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
3995 fileno = STps->drv_file;
3996 blkno = STps->drv_block;
3997 at_sm &= (arg == 0);
4002 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4003 cmd[2] = (arg >> 16);
4004 cmd[3] = (arg >> 8);
4008 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4009 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4012 blkno = fileno = (-1);
4018 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4020 cmd[2] = (ltmp >> 16);
4021 cmd[3] = (ltmp >> 8);
4027 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4028 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4033 blkno = fileno = (-1);
4038 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4039 STp->write_type = OS_WRITE_DATA;
4040 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4045 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4047 for (i=0; i<arg; i++)
4048 ioctl_result |= osst_write_filemark(STp, &SRpnt);
4049 if (fileno >= 0) fileno += arg;
4050 if (blkno >= 0) blkno = 0;
4054 if (STp->write_prot)
4058 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
4059 if (cmd_in == MTWSM)
4061 cmd[2] = (arg >> 16);
4062 cmd[3] = (arg >> 8);
4064 timeout = STp->timeout;
4067 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4068 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4073 at_sm = (cmd_in == MTWSM);
4079 cmd[0] = START_STOP;
4080 cmd[1] = 1; /* Don't wait for completion */
4081 if (cmd_in == MTLOAD) {
4082 if (STp->ready == ST_NO_TAPE)
4083 cmd[4] = 4; /* open tray */
4085 cmd[4] = 1; /* load */
4087 if (cmd_in == MTRETEN)
4088 cmd[4] = 3; /* retension then mount */
4089 if (cmd_in == MTOFFL)
4090 cmd[4] = 4; /* rewind then eject */
4091 timeout = STp->timeout;
4096 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4099 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4102 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4105 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4110 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4115 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4117 return 0; /* Should do something ? */
4122 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4124 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4125 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4126 ioctl_result = -EIO;
4129 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4131 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4133 ioctl_result = -EIO;
4136 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4137 fileno = STp->filemark_cnt;
4142 if (STp->write_prot)
4144 ioctl_result = osst_reset_header(STp, &SRpnt);
4145 i = osst_write_eod(STp, &SRpnt);
4146 if (i < ioctl_result) ioctl_result = i;
4147 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4148 if (i < ioctl_result) ioctl_result = i;
4149 fileno = blkno = at_sm = 0 ;
4153 cmd[0] = REZERO_UNIT; /* rewind */
4157 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4159 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4162 case MTSETBLK: /* Set block length */
4163 if ((STps->drv_block == 0 ) &&
4165 ((STp->buffer)->buffer_bytes == 0) &&
4166 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4167 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4168 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4170 * Only allowed to change the block size if you opened the
4171 * device at the beginning of a file before writing anything.
4172 * Note, that when reading, changing block_size is futile,
4173 * as the size used when writing overrides it.
4175 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4176 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4177 name, STp->block_size);
4180 case MTSETDENSITY: /* Set tape density */
4181 case MTSETDRVBUFFER: /* Set drive buffering */
4182 case SET_DENS_AND_BLK: /* Set density and block size */
4184 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4185 return (-EIO); /* Not allowed if data in buffer */
4186 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4187 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4188 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4189 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4190 name, (int)(arg & MT_ST_BLKSIZE_MASK),
4191 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4194 return 0; /* FIXME silently ignore if block size didn't change */
4200 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4202 ioctl_result = (STp->buffer)->syscall_result;
4206 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4208 return ioctl_result;
4211 if (!ioctl_result) { /* SCSI command successful */
4212 STp->frame_seq_number = frame_seq_numbr;
4213 STp->logical_blk_num = logical_blk_num;
4219 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4222 if (!ioctl_result) { /* success */
4224 if (cmd_in == MTFSFM) {
4228 if (cmd_in == MTBSFM) {
4232 STps->drv_block = blkno;
4233 STps->drv_file = fileno;
4234 STps->at_sm = at_sm;
4236 if (cmd_in == MTEOM)
4238 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4239 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4241 STp->logical_blk_num++;
4242 STp->frame_seq_number++;
4243 STp->frame_in_buffer = 0;
4244 STp->buffer->read_pointer = 0;
4246 else if (cmd_in == MTFSF)
4247 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4249 STps->eof = ST_NOEOF;
4251 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4252 STp->rew_at_close = 0;
4253 else if (cmd_in == MTLOAD) {
4254 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4255 STp->ps[i].rw = ST_IDLE;
4256 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4261 if (cmd_in == MTREW) {
4262 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4263 if (ioctl_result > 0)
4267 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4268 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4269 STps->drv_file = STps->drv_block = -1;
4271 STps->drv_file = STps->drv_block = 0;
4272 STps->eof = ST_NOEOF;
4273 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4274 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4275 STps->drv_file = STps->drv_block = -1;
4277 STps->drv_file = STp->filemark_cnt;
4278 STps->drv_block = 0;
4281 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4282 STps->drv_file = STps->drv_block = (-1);
4283 STps->eof = ST_NOEOF;
4285 } else if (cmd_in == MTERASE) {
4287 } else if (SRpnt) { /* SCSI command was not completely successful. */
4288 if (SRpnt->sr_sense_buffer[2] & 0x40) {
4289 STps->eof = ST_EOM_OK;
4290 STps->drv_block = 0;
4293 STps->eof = ST_NOEOF;
4295 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == BLANK_CHECK)
4298 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4299 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4303 return ioctl_result;
4307 /* Open the device */
4308 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4310 unsigned short flags;
4311 int i, b_size, new_session = 0, retval = 0;
4312 unsigned char cmd[MAX_COMMAND_SIZE];
4313 struct scsi_request * SRpnt = NULL;
4314 struct osst_tape * STp;
4315 struct st_modedef * STm;
4316 struct st_partstat * STps;
4318 int dev = TAPE_NR(inode);
4319 int mode = TAPE_MODE(inode);
4321 nonseekable_open(inode, filp);
4322 write_lock(&os_scsi_tapes_lock);
4323 if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4324 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4325 write_unlock(&os_scsi_tapes_lock);
4329 name = tape_name(STp);
4332 write_unlock(&os_scsi_tapes_lock);
4334 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4338 if (scsi_device_get(STp->device)) {
4339 write_unlock(&os_scsi_tapes_lock);
4341 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4345 filp->private_data = STp;
4347 write_unlock(&os_scsi_tapes_lock);
4348 STp->rew_at_close = TAPE_REWIND(inode);
4350 if( !scsi_block_when_processing_errors(STp->device) ) {
4354 if (mode != STp->current_mode) {
4357 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4358 name, STp->current_mode, mode);
4361 STp->current_mode = mode;
4363 STm = &(STp->modes[STp->current_mode]);
4365 flags = filp->f_flags;
4366 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4368 STp->raw = TAPE_IS_RAW(inode);
4372 /* Allocate data segments for this device's tape buffer */
4373 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4374 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4375 retval = (-EOVERFLOW);
4378 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4379 for (i = 0, b_size = 0;
4380 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4381 b_size += STp->buffer->sg[i++].length);
4382 STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
4384 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4385 STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4386 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4387 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4390 STp->buffer->aux = NULL; /* this had better never happen! */
4391 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4395 STp->buffer->writing = 0;
4396 STp->buffer->syscall_result = 0;
4398 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4399 STps = &(STp->ps[i]);
4402 STp->ready = ST_READY;
4404 STp->nbr_waits = STp->nbr_finished = 0;
4407 memset (cmd, 0, MAX_COMMAND_SIZE);
4408 cmd[0] = TEST_UNIT_READY;
4410 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4412 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
4415 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4416 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
4417 SRpnt->sr_sense_buffer[12] == 4 ) {
4419 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sr_sense_buffer[13]);
4421 if (filp->f_flags & O_NONBLOCK) {
4425 if (SRpnt->sr_sense_buffer[13] == 2) { /* initialize command required (LOAD) */
4426 memset (cmd, 0, MAX_COMMAND_SIZE);
4427 cmd[0] = START_STOP;
4430 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4431 STp->timeout, MAX_RETRIES, 1);
4433 osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0);
4435 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4436 (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4438 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4442 for (i=0; i < 10; i++) {
4444 memset (cmd, 0, MAX_COMMAND_SIZE);
4445 cmd[0] = TEST_UNIT_READY;
4447 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4448 STp->timeout, MAX_RETRIES, 1);
4449 if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
4450 (SRpnt->sr_sense_buffer[2] & 0x0f) != UNIT_ATTENTION)
4454 STp->pos_unknown = 0;
4455 STp->partition = STp->new_partition = 0;
4456 if (STp->can_partitions)
4457 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4458 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4459 STps = &(STp->ps[i]);
4460 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4461 STps->eof = ST_NOEOF;
4463 STps->last_block_valid = 0;
4464 STps->drv_block = 0;
4465 STps->drv_file = 0 ;
4468 STp->recover_count = 0;
4469 STp->abort_count = 0;
4472 * if we have valid headers from before, and the drive/tape seem untouched,
4473 * open without reconfiguring and re-reading the headers
4475 if (!STp->buffer->syscall_result && STp->header_ok &&
4476 !SRpnt->sr_result && SRpnt->sr_sense_buffer[0] == 0) {
4478 memset(cmd, 0, MAX_COMMAND_SIZE);
4479 cmd[0] = MODE_SENSE;
4481 cmd[2] = VENDOR_IDENT_PAGE;
4482 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4484 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4486 if (STp->buffer->syscall_result ||
4487 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4488 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4489 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4490 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4492 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4493 STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4494 STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4495 STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4496 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4500 i = STp->first_frame_position;
4501 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4502 if (STp->door_locked == ST_UNLOCKED) {
4503 if (do_door_lock(STp, 1))
4504 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4506 STp->door_locked = ST_LOCKED_AUTO;
4508 if (!STp->frame_in_buffer) {
4509 STp->block_size = (STm->default_blksize > 0) ?
4510 STm->default_blksize : OS_DATA_SIZE;
4511 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4513 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4515 scsi_release_request(SRpnt);
4519 if (i != STp->first_frame_position)
4520 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4521 name, i, STp->first_frame_position);
4527 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4528 (SRpnt->sr_sense_buffer[2] != 2 || SRpnt->sr_sense_buffer[12] != 0x3A) ) {
4530 memset(cmd, 0, MAX_COMMAND_SIZE);
4531 cmd[0] = MODE_SELECT;
4533 cmd[4] = 4 + MODE_HEADER_LENGTH;
4535 (STp->buffer)->b_data[0] = cmd[4] - 1;
4536 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4537 (STp->buffer)->b_data[2] = 0; /* Reserved */
4538 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4539 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4540 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4541 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4542 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4545 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4547 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4551 for (i=0; i < 10; i++) {
4553 memset (cmd, 0, MAX_COMMAND_SIZE);
4554 cmd[0] = TEST_UNIT_READY;
4556 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4557 STp->timeout, MAX_RETRIES, 1);
4558 if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
4559 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY)
4562 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) {
4563 STp->pos_unknown = 0;
4564 STp->partition = STp->new_partition = 0;
4565 if (STp->can_partitions)
4566 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4567 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4568 STps = &(STp->ps[i]);
4570 STps->eof = ST_NOEOF;
4572 STps->last_block_valid = 0;
4573 STps->drv_block = 0;
4574 STps->drv_file = 0 ;
4581 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4582 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4584 if ((STp->buffer)->syscall_result != 0) {
4585 if ((STp->device)->scsi_level >= SCSI_2 &&
4586 (SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4587 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
4588 SRpnt->sr_sense_buffer[12] == 0x3a) { /* Check ASC */
4589 STp->ready = ST_NO_TAPE;
4591 STp->ready = ST_NOT_READY;
4592 scsi_release_request(SRpnt);
4594 STp->density = 0; /* Clear the erroneous "residue" */
4595 STp->write_prot = 0;
4596 STp->block_size = 0;
4597 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4598 STp->partition = STp->new_partition = 0;
4599 STp->door_locked = ST_UNLOCKED;
4603 osst_configure_onstream(STp, &SRpnt);
4605 STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4606 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4607 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4608 STp->buffer->buffer_bytes =
4609 STp->buffer->read_pointer =
4610 STp->frame_in_buffer = 0;
4614 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4615 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4616 (STp->buffer)->buffer_blocks);
4619 if (STp->drv_write_prot) {
4620 STp->write_prot = 1;
4623 printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4625 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4631 if (new_session) { /* Change the drive parameters for the new mode */
4634 printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4636 STp->density_changed = STp->blksize_changed = 0;
4637 STp->compression_changed = 0;
4641 * properly position the tape and check the ADR headers
4643 if (STp->door_locked == ST_UNLOCKED) {
4644 if (do_door_lock(STp, 1))
4645 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4647 STp->door_locked = ST_LOCKED_AUTO;
4650 osst_analyze_headers(STp, &SRpnt);
4652 scsi_release_request(SRpnt);
4659 scsi_release_request(SRpnt);
4660 normalize_buffer(STp->buffer);
4663 scsi_device_put(STp->device);
4669 /* Flush the tape buffer before close */
4670 static int os_scsi_tape_flush(struct file * filp)
4672 int result = 0, result2;
4673 struct osst_tape * STp = filp->private_data;
4674 struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4675 struct st_partstat * STps = &(STp->ps[STp->partition]);
4676 struct scsi_request * SRpnt = NULL;
4677 char * name = tape_name(STp);
4679 if (file_count(filp) > 1)
4682 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4683 STp->write_type = OS_WRITE_DATA;
4684 result = osst_flush_write_buffer(STp, &SRpnt);
4685 if (result != 0 && result != (-ENOSPC))
4688 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4692 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4693 name, (long)(filp->f_pos));
4694 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4695 name, STp->nbr_waits, STp->nbr_finished);
4698 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4701 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4702 name, 1+STp->two_fm);
4705 else if (!STp->rew_at_close) {
4706 STps = &(STp->ps[STp->partition]);
4707 if (!STm->sysv || STps->rw != ST_READING) {
4709 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4710 else if (STps->eof == ST_FM_HIT) {
4711 result = cross_eof(STp, &SRpnt, 0);
4713 if (STps->drv_file >= 0)
4715 STps->drv_block = 0;
4719 STps->eof = ST_NOEOF;
4722 else if ((STps->eof == ST_NOEOF &&
4723 !(result = cross_eof(STp, &SRpnt, 1))) ||
4724 STps->eof == ST_FM_HIT) {
4725 if (STps->drv_file >= 0)
4727 STps->drv_block = 0;
4733 if (STp->rew_at_close) {
4734 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4735 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4736 if (result == 0 && result2 < 0)
4739 if (SRpnt) scsi_release_request(SRpnt);
4741 if (STp->abort_count || STp->recover_count) {
4742 printk(KERN_INFO "%s:I:", name);
4743 if (STp->abort_count)
4744 printk(" %d unrecovered errors", STp->abort_count);
4745 if (STp->recover_count)
4746 printk(" %d recovered errors", STp->recover_count);
4747 if (STp->write_count)
4748 printk(" in %d frames written", STp->write_count);
4749 if (STp->read_count)
4750 printk(" in %d frames read", STp->read_count);
4752 STp->recover_count = 0;
4753 STp->abort_count = 0;
4755 STp->write_count = 0;
4756 STp->read_count = 0;
4762 /* Close the device and release it */
4763 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4766 struct osst_tape * STp = filp->private_data;
4767 struct scsi_request * SRpnt = NULL;
4769 if (SRpnt) scsi_release_request(SRpnt);
4771 if (STp->door_locked == ST_LOCKED_AUTO)
4772 do_door_lock(STp, 0);
4777 normalize_buffer(STp->buffer);
4778 write_lock(&os_scsi_tapes_lock);
4780 write_unlock(&os_scsi_tapes_lock);
4782 scsi_device_put(STp->device);
4788 /* The ioctl command */
4789 static int osst_ioctl(struct inode * inode,struct file * file,
4790 unsigned int cmd_in, unsigned long arg)
4792 int i, cmd_nr, cmd_type, retval = 0;
4794 struct st_modedef * STm;
4795 struct st_partstat * STps;
4796 struct scsi_request * SRpnt = NULL;
4797 struct osst_tape * STp = file->private_data;
4798 char * name = tape_name(STp);
4799 void __user * p = (void __user *)arg;
4801 if (down_interruptible(&STp->lock))
4802 return -ERESTARTSYS;
4805 if (debugging && !STp->in_use) {
4806 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4811 STm = &(STp->modes[STp->current_mode]);
4812 STps = &(STp->ps[STp->partition]);
4815 * If we are in the middle of error recovery, don't let anyone
4816 * else try and use this device. Also, if error recovery fails, it
4817 * may try and take the device offline, in which case all further
4818 * access to the device is prohibited.
4820 if( !scsi_block_when_processing_errors(STp->device) ) {
4825 cmd_type = _IOC_TYPE(cmd_in);
4826 cmd_nr = _IOC_NR(cmd_in);
4828 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4829 cmd_type, cmd_nr, STp->raw?"raw":"normal");
4831 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4835 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
4840 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
4846 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
4847 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
4852 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
4857 if (!STp->pos_unknown) {
4859 if (STps->eof == ST_FM_HIT) {
4860 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
4862 if (STps->drv_file >= 0)
4863 STps->drv_file += 1;
4865 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
4867 if (STps->drv_file >= 0)
4868 STps->drv_file += 1;
4872 if (mtc.mt_op == MTSEEK) {
4873 /* Old position must be restored if partition will be changed */
4874 i = !STp->can_partitions || (STp->new_partition != STp->partition);
4877 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
4878 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
4879 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
4880 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
4881 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
4882 mtc.mt_op == MTCOMPRESSION;
4884 i = osst_flush_buffer(STp, &SRpnt, i);
4892 * If there was a bus reset, block further access
4893 * to this device. If the user wants to rewind the tape,
4894 * then reset the flag and allow access again.
4896 if(mtc.mt_op != MTREW &&
4897 mtc.mt_op != MTOFFL &&
4898 mtc.mt_op != MTRETEN &&
4899 mtc.mt_op != MTERASE &&
4900 mtc.mt_op != MTSEEK &&
4901 mtc.mt_op != MTEOM) {
4906 /* remove this when the midlevel properly clears was_reset */
4907 STp->device->was_reset = 0;
4910 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK &&
4911 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
4912 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER &&
4913 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART &&
4914 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) {
4917 * The user tells us to move to another position on the tape.
4918 * If we were appending to the tape content, that would leave
4919 * the tape without proper end, in that case write EOD and
4920 * update the header to reflect its position.
4923 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
4924 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
4925 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
4926 STp->logical_blk_num, STps->drv_file, STps->drv_block );
4928 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
4929 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
4930 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4931 i = osst_write_trailer(STp, &SRpnt,
4932 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4934 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
4935 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
4936 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
4946 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
4947 do_door_lock(STp, 0); /* Ignore result! */
4949 if (mtc.mt_op == MTSETDRVBUFFER &&
4950 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
4951 retval = osst_set_options(STp, mtc.mt_count);
4955 if (mtc.mt_op == MTSETPART) {
4956 if (mtc.mt_count >= STp->nbr_partitions)
4959 STp->new_partition = mtc.mt_count;
4965 if (mtc.mt_op == MTMKPART) {
4966 if (!STp->can_partitions) {
4970 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
4971 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
4975 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4976 STp->ps[i].rw = ST_IDLE;
4977 STp->ps[i].at_sm = 0;
4978 STp->ps[i].last_block_valid = 0;
4980 STp->partition = STp->new_partition = 0;
4981 STp->nbr_partitions = 1; /* Bad guess ?-) */
4982 STps->drv_block = STps->drv_file = 0;
4987 if (mtc.mt_op == MTSEEK) {
4989 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
4991 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
4992 if (!STp->can_partitions)
4993 STp->ps[0].rw = ST_IDLE;
4998 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
4999 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
5004 cross_eof(STp, &SRpnt, 0);
5006 if (mtc.mt_op == MTCOMPRESSION)
5007 retval = -EINVAL; /* OnStream drives don't have compression hardware */
5009 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5010 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5011 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5015 if (!STm->defined) {
5020 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5025 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
5026 struct mtget mt_status;
5028 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
5033 mt_status.mt_type = MT_ISONSTREAM_SC;
5034 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
5035 mt_status.mt_dsreg =
5036 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
5037 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
5038 mt_status.mt_blkno = STps->drv_block;
5039 mt_status.mt_fileno = STps->drv_file;
5040 if (STp->block_size != 0) {
5041 if (STps->rw == ST_WRITING)
5042 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
5043 else if (STps->rw == ST_READING)
5044 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
5045 STp->block_size - 1) / STp->block_size;
5048 mt_status.mt_gstat = 0;
5049 if (STp->drv_write_prot)
5050 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
5051 if (mt_status.mt_blkno == 0) {
5052 if (mt_status.mt_fileno == 0)
5053 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
5055 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
5057 mt_status.mt_resid = STp->partition;
5058 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
5059 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
5060 else if (STps->eof >= ST_EOM_OK)
5061 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
5062 if (STp->density == 1)
5063 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
5064 else if (STp->density == 2)
5065 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
5066 else if (STp->density == 3)
5067 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
5068 if (STp->ready == ST_READY)
5069 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
5070 if (STp->ready == ST_NO_TAPE)
5071 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
5073 mt_status.mt_gstat |= GMT_SM(0xffffffff);
5074 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
5075 STp->drv_buffer != 0)
5076 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
5078 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
5084 STp->recover_erreg = 0; /* Clear after read */
5087 } /* End of MTIOCGET */
5089 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5090 struct mtpos mt_pos;
5092 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5097 blk = osst_get_frame_position(STp, &SRpnt);
5099 blk = osst_get_sector(STp, &SRpnt);
5104 mt_pos.mt_blkno = blk;
5105 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5110 if (SRpnt) scsi_release_request(SRpnt);
5114 return scsi_ioctl(STp->device, cmd_in, p);
5117 if (SRpnt) scsi_release_request(SRpnt);
5125 /* Memory handling routines */
5127 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5128 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5131 struct osst_buffer *tb;
5133 if (from_initialization)
5134 priority = GFP_ATOMIC;
5136 priority = GFP_KERNEL;
5138 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5139 tb = (struct osst_buffer *)kmalloc(i, priority);
5141 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5145 tb->sg_segs = tb->orig_sg_segs = 0;
5146 tb->use_sg = max_sg;
5149 tb->buffer_size = 0;
5153 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5154 i, max_sg, need_dma);
5159 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5160 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5162 int segs, nbr, max_segs, b_size, priority, order, got;
5164 if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5167 if (STbuffer->sg_segs) {
5168 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5169 normalize_buffer(STbuffer);
5171 /* See how many segments we can use -- need at least two */
5172 nbr = max_segs = STbuffer->use_sg;
5176 priority = GFP_KERNEL /* | __GFP_NOWARN */;
5178 priority |= GFP_DMA;
5180 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5181 big enough to reach the goal (code assumes no segments in place) */
5182 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5183 STbuffer->sg[0].page = alloc_pages(priority, order);
5184 STbuffer->sg[0].offset = 0;
5185 if (STbuffer->sg[0].page != NULL) {
5186 STbuffer->sg[0].length = b_size;
5187 STbuffer->b_data = page_address(STbuffer->sg[0].page);
5191 if (STbuffer->sg[0].page == NULL) {
5192 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5195 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5196 for (segs=STbuffer->sg_segs=1, got=b_size;
5197 segs < max_segs && got < OS_FRAME_SIZE; ) {
5198 STbuffer->sg[segs].page =
5199 alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5200 STbuffer->sg[segs].offset = 0;
5201 if (STbuffer->sg[segs].page == NULL) {
5202 if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
5203 b_size /= 2; /* Large enough for the rest of the buffers */
5207 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5210 STbuffer->buffer_size = got;
5212 normalize_buffer(STbuffer);
5215 STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
5216 got += STbuffer->sg[segs].length;
5217 STbuffer->buffer_size = got;
5218 STbuffer->sg_segs = ++segs;
5223 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5224 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5226 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5227 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5228 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5236 /* Release the segments */
5237 static void normalize_buffer(struct osst_buffer *STbuffer)
5239 int i, order, b_size;
5241 for (i=0; i < STbuffer->sg_segs; i++) {
5243 for (b_size = PAGE_SIZE, order = 0;
5244 b_size < STbuffer->sg[i].length;
5245 b_size *= 2, order++);
5247 __free_pages(STbuffer->sg[i].page, order);
5248 STbuffer->buffer_size -= STbuffer->sg[i].length;
5251 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5252 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5253 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5255 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5259 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5260 negative error code. */
5261 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
5263 int i, cnt, res, offset;
5265 for (i=0, offset=st_bp->buffer_bytes;
5266 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5267 offset -= st_bp->sg[i].length;
5268 if (i == st_bp->sg_segs) { /* Should never happen */
5269 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5272 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5273 cnt = st_bp->sg[i].length - offset < do_count ?
5274 st_bp->sg[i].length - offset : do_count;
5275 res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
5279 st_bp->buffer_bytes += cnt;
5283 if (do_count) { /* Should never happen */
5284 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5292 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5293 negative error code. */
5294 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
5296 int i, cnt, res, offset;
5298 for (i=0, offset=st_bp->read_pointer;
5299 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5300 offset -= st_bp->sg[i].length;
5301 if (i == st_bp->sg_segs) { /* Should never happen */
5302 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5305 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5306 cnt = st_bp->sg[i].length - offset < do_count ?
5307 st_bp->sg[i].length - offset : do_count;
5308 res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
5312 st_bp->buffer_bytes -= cnt;
5313 st_bp->read_pointer += cnt;
5317 if (do_count) { /* Should never happen */
5318 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5324 /* Sets the tail of the buffer after fill point to zero.
5325 Returns zero (success) or negative error code. */
5326 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
5328 int i, offset, do_count, cnt;
5330 for (i = 0, offset = st_bp->buffer_bytes;
5331 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5332 offset -= st_bp->sg[i].length;
5333 if (i == st_bp->sg_segs) { /* Should never happen */
5334 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5337 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5338 i < st_bp->sg_segs && do_count > 0; i++) {
5339 cnt = st_bp->sg[i].length - offset < do_count ?
5340 st_bp->sg[i].length - offset : do_count ;
5341 memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
5345 if (do_count) { /* Should never happen */
5346 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5352 /* Copy a osst 32K chunk of memory into the buffer.
5353 Returns zero (success) or negative error code. */
5354 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5356 int i, cnt, do_count = OS_DATA_SIZE;
5358 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5359 cnt = st_bp->sg[i].length < do_count ?
5360 st_bp->sg[i].length : do_count ;
5361 memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
5365 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5366 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5373 /* Copy a osst 32K chunk of memory from the buffer.
5374 Returns zero (success) or negative error code. */
5375 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5377 int i, cnt, do_count = OS_DATA_SIZE;
5379 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5380 cnt = st_bp->sg[i].length < do_count ?
5381 st_bp->sg[i].length : do_count ;
5382 memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
5386 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5387 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5395 /* Module housekeeping */
5397 static void validate_options (void)
5400 osst_max_dev = max_dev;
5401 if (write_threshold_kbs > 0)
5402 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5403 if (osst_write_threshold > osst_buffer_size)
5404 osst_write_threshold = osst_buffer_size;
5405 if (max_sg_segs >= OSST_FIRST_SG)
5406 osst_max_sg_segs = max_sg_segs;
5408 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5409 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5414 /* Set the boot options. Syntax: osst=xxx,yyy,...
5415 where xxx is write threshold in 1024 byte blocks,
5416 and yyy is number of s/g segments to use. */
5417 static int __init osst_setup (char *str)
5422 stp = get_options(str, ARRAY_SIZE(ints), ints);
5425 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5426 *parms[i].val = ints[i + 1];
5428 while (stp != NULL) {
5429 for (i = 0; i < ARRAY_SIZE(parms); i++) {
5430 int len = strlen(parms[i].name);
5431 if (!strncmp(stp, parms[i].name, len) &&
5432 (*(stp + len) == ':' || *(stp + len) == '=')) {
5434 simple_strtoul(stp + len + 1, NULL, 0);
5438 if (i >= sizeof(parms) / sizeof(struct osst_dev_parm))
5439 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5441 stp = strchr(stp, ',');
5450 __setup("osst=", osst_setup);
5454 static struct file_operations osst_fops = {
5455 .owner = THIS_MODULE,
5457 .write = osst_write,
5458 .ioctl = osst_ioctl,
5459 .open = os_scsi_tape_open,
5460 .flush = os_scsi_tape_flush,
5461 .release = os_scsi_tape_close,
5464 static int osst_supports(struct scsi_device * SDp)
5466 struct osst_support_data {
5470 char *driver_hint; /* Name of the correct driver, NULL if unknown */
5473 static struct osst_support_data support_list[] = {
5474 /* {"XXX", "Yy-", "", NULL}, example */
5478 struct osst_support_data *rp;
5480 /* We are willing to drive OnStream SC-x0 as well as the
5481 * * IDE, ParPort, FireWire, USB variants, if accessible by
5482 * * emulation layer (ide-scsi, usb-storage, ...) */
5484 for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5485 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5486 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5487 !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5493 * sysfs support for osst driver parameter information
5496 static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
5498 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
5501 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
5503 static void osst_create_driverfs_files(struct device_driver *driverfs)
5505 driver_create_file(driverfs, &driver_attr_version);
5508 static void osst_remove_driverfs_files(struct device_driver *driverfs)
5510 driver_remove_file(driverfs, &driver_attr_version);
5514 * sysfs support for accessing ADR header information
5517 static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf)
5519 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5522 if (STp && STp->header_ok && STp->linux_media)
5523 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
5527 CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
5529 static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf)
5531 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5534 if (STp && STp->header_ok && STp->linux_media)
5535 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
5539 CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
5541 static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf)
5543 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5546 if (STp && STp->header_ok && STp->linux_media)
5547 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
5551 CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
5553 static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf)
5555 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5558 if (STp && STp->header_ok && STp->linux_media)
5559 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
5563 CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
5565 static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf)
5567 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5570 if (STp && STp->header_ok && STp->linux_media)
5571 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
5575 CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
5577 static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf)
5579 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5582 if (STp && STp->header_ok && STp->linux_media)
5583 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
5587 CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5589 static struct class_simple * osst_sysfs_class;
5591 static int osst_sysfs_valid = 0;
5593 static void osst_sysfs_init(void)
5595 osst_sysfs_class = class_simple_create(THIS_MODULE, "onstream_tape");
5596 if ( IS_ERR(osst_sysfs_class) )
5597 printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
5599 osst_sysfs_valid = 1;
5602 static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5604 struct class_device *osst_class_member;
5606 if (!osst_sysfs_valid) return;
5608 osst_class_member = class_simple_device_add(osst_sysfs_class, dev, device, "%s", name);
5609 if (IS_ERR(osst_class_member)) {
5610 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5613 class_set_devdata(osst_class_member, STp);
5614 class_device_create_file(osst_class_member, &class_device_attr_ADR_rev);
5615 class_device_create_file(osst_class_member, &class_device_attr_media_version);
5616 class_device_create_file(osst_class_member, &class_device_attr_capacity);
5617 class_device_create_file(osst_class_member, &class_device_attr_BOT_frame);
5618 class_device_create_file(osst_class_member, &class_device_attr_EOD_frame);
5619 class_device_create_file(osst_class_member, &class_device_attr_file_count);
5622 static void osst_sysfs_destroy(dev_t dev)
5624 if (!osst_sysfs_valid) return;
5626 class_simple_device_remove(dev);
5629 static void osst_sysfs_cleanup(void)
5631 if (osst_sysfs_valid) {
5632 class_simple_destroy(osst_sysfs_class);
5633 osst_sysfs_valid = 0;
5638 * osst startup / cleanup code
5641 static int osst_probe(struct device *dev)
5643 struct scsi_device * SDp = to_scsi_device(dev);
5644 struct osst_tape * tpnt;
5645 struct st_modedef * STm;
5646 struct st_partstat * STps;
5647 struct osst_buffer * buffer;
5648 struct gendisk * drive;
5649 int i, mode, dev_num;
5651 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5654 drive = alloc_disk(1);
5656 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5660 /* if this is the first attach, build the infrastructure */
5661 write_lock(&os_scsi_tapes_lock);
5662 if (os_scsi_tapes == NULL) {
5664 (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *),
5666 if (os_scsi_tapes == NULL) {
5667 write_unlock(&os_scsi_tapes_lock);
5668 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5671 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5674 if (osst_nr_dev >= osst_max_dev) {
5675 write_unlock(&os_scsi_tapes_lock);
5676 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5680 /* find a free minor number */
5681 for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++);
5682 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5685 /* allocate a struct osst_tape for this device */
5686 tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
5688 write_unlock(&os_scsi_tapes_lock);
5689 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5692 memset(tpnt, 0, sizeof(struct osst_tape));
5694 /* allocate a buffer for this device */
5695 i = SDp->host->sg_tablesize;
5696 if (osst_max_sg_segs < i)
5697 i = osst_max_sg_segs;
5698 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
5699 if (buffer == NULL) {
5700 write_unlock(&os_scsi_tapes_lock);
5701 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5705 os_scsi_tapes[dev_num] = tpnt;
5706 tpnt->buffer = buffer;
5708 drive->private_data = &tpnt->driver;
5709 sprintf(drive->disk_name, "osst%d", dev_num);
5710 tpnt->driver = &osst_template;
5711 tpnt->drive = drive;
5713 tpnt->capacity = 0xfffff;
5715 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
5716 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5718 tpnt->do_auto_lock = OSST_AUTO_LOCK;
5719 tpnt->can_bsr = OSST_IN_FILE_POS;
5720 tpnt->can_partitions = 0;
5721 tpnt->two_fm = OSST_TWO_FM;
5722 tpnt->fast_mteom = OSST_FAST_MTEOM;
5723 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5724 tpnt->write_threshold = osst_write_threshold;
5725 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5726 tpnt->partition = 0;
5727 tpnt->new_partition = 0;
5728 tpnt->nbr_partitions = 0;
5729 tpnt->min_block = 512;
5730 tpnt->max_block = OS_DATA_SIZE;
5731 tpnt->timeout = OSST_TIMEOUT;
5732 tpnt->long_timeout = OSST_LONG_TIMEOUT;
5734 /* Recognize OnStream tapes */
5735 /* We don't need to test for OnStream, as this has been done in detect () */
5736 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5737 tpnt->omit_blklims = 1;
5739 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5740 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5741 tpnt->frame_in_buffer = 0;
5742 tpnt->header_ok = 0;
5743 tpnt->linux_media = 0;
5744 tpnt->header_cache = NULL;
5746 for (i=0; i < ST_NBR_MODES; i++) {
5747 STm = &(tpnt->modes[i]);
5749 STm->sysv = OSST_SYSV;
5750 STm->defaults_for_writes = 0;
5751 STm->do_async_writes = OSST_ASYNC_WRITES;
5752 STm->do_buffer_writes = OSST_BUFFER_WRITES;
5753 STm->do_read_ahead = OSST_READ_AHEAD;
5754 STm->default_compression = ST_DONT_TOUCH;
5755 STm->default_blksize = 512;
5756 STm->default_density = (-1); /* No forced density */
5759 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5760 STps = &(tpnt->ps[i]);
5762 STps->eof = ST_NOEOF;
5764 STps->last_block_valid = 0;
5765 STps->drv_block = (-1);
5766 STps->drv_file = (-1);
5769 tpnt->current_mode = 0;
5770 tpnt->modes[0].defined = 1;
5771 tpnt->modes[2].defined = 1;
5772 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
5774 init_MUTEX(&tpnt->lock);
5776 write_unlock(&os_scsi_tapes_lock);
5780 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5781 /* No-rewind entry */
5782 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5783 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5785 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
5787 devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)),
5788 S_IFCHR | S_IRUGO | S_IWUGO,
5789 "%s/ot%s", SDp->devfs_name, osst_formats[mode]);
5791 /* No-rewind entry */
5792 devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5) + 128),
5793 S_IFCHR | S_IRUGO | S_IWUGO,
5794 "%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
5796 drive->number = devfs_register_tape(SDp->devfs_name);
5799 "osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as %s\n",
5800 SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, tape_name(tpnt));
5809 static int osst_remove(struct device *dev)
5811 struct scsi_device * SDp = to_scsi_device(dev);
5812 struct osst_tape * tpnt;
5815 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
5818 write_lock(&os_scsi_tapes_lock);
5819 for(i=0; i < osst_max_dev; i++) {
5820 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
5821 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
5822 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
5823 tpnt->device = NULL;
5824 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
5825 devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]);
5826 devfs_remove("%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
5828 devfs_unregister_tape(tpnt->drive->number);
5829 put_disk(tpnt->drive);
5830 os_scsi_tapes[i] = NULL;
5832 write_unlock(&os_scsi_tapes_lock);
5833 if (tpnt->header_cache != NULL) vfree(tpnt->header_cache);
5835 normalize_buffer(tpnt->buffer);
5836 kfree(tpnt->buffer);
5842 write_unlock(&os_scsi_tapes_lock);
5846 static int __init init_osst(void)
5848 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
5853 if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
5854 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
5855 osst_sysfs_cleanup();
5858 osst_create_driverfs_files(&osst_template.gendrv);
5863 static void __exit exit_osst (void)
5866 struct osst_tape * STp;
5868 osst_remove_driverfs_files(&osst_template.gendrv);
5869 scsi_unregister_driver(&osst_template.gendrv);
5870 unregister_chrdev(OSST_MAJOR, "osst");
5871 osst_sysfs_cleanup();
5873 if (os_scsi_tapes) {
5874 for (i=0; i < osst_max_dev; ++i) {
5875 if (!(STp = os_scsi_tapes[i])) continue;
5876 /* This is defensive, supposed to happen during detach */
5877 if (STp->header_cache)
5878 vfree(STp->header_cache);
5880 normalize_buffer(STp->buffer);
5883 put_disk(STp->drive);
5886 kfree(os_scsi_tapes);
5888 printk(KERN_INFO "osst :I: Unloaded.\n");
5891 module_init(init_osst);
5892 module_exit(exit_osst);