2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
3 file Documentation/scsi/st.txt for more information.
7 OnStream SCSI Tape support (osst) cloned from st.c by
8 Willem Riede (osst@riede.org) Feb 2000
9 Fixes ... Kurt Garloff <garloff@suse.de> Mar 2000
11 Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
12 Contribution and ideas from several people including (in alphabetical
13 order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
14 Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
16 Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede
19 $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
21 Microscopic alterations - Rik Ling, 2000/12/21
22 Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
23 Some small formal changes - aeb, 950809
26 static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $";
27 static const char * osst_version = "0.99.4";
29 /* The "failure to reconnect" firmware bug */
30 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
31 #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/
32 #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
34 #include <linux/module.h>
37 #include <linux/kernel.h>
38 #include <linux/sched/signal.h>
39 #include <linux/proc_fs.h>
41 #include <linux/slab.h>
42 #include <linux/init.h>
43 #include <linux/string.h>
44 #include <linux/errno.h>
45 #include <linux/mtio.h>
46 #include <linux/ioctl.h>
47 #include <linux/fcntl.h>
48 #include <linux/spinlock.h>
49 #include <linux/vmalloc.h>
50 #include <linux/blkdev.h>
51 #include <linux/moduleparam.h>
52 #include <linux/delay.h>
53 #include <linux/jiffies.h>
54 #include <linux/mutex.h>
55 #include <linux/uaccess.h>
58 /* The driver prints some debugging information on the console if DEBUG
59 is defined and non-zero. */
62 /* The message level for the debug messages is currently set to KERN_NOTICE
63 so that people can easily see the messages. Later when the debugging messages
64 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
65 #define OSST_DEB_MSG KERN_NOTICE
67 #include <scsi/scsi.h>
68 #include <scsi/scsi_dbg.h>
69 #include <scsi/scsi_device.h>
70 #include <scsi/scsi_driver.h>
71 #include <scsi/scsi_eh.h>
72 #include <scsi/scsi_host.h>
73 #include <scsi/scsi_ioctl.h>
75 #define ST_KILOBYTE 1024
79 #include "osst_options.h"
80 #include "osst_detect.h"
82 static DEFINE_MUTEX(osst_int_mutex);
83 static int max_dev = 0;
84 static int write_threshold_kbs = 0;
85 static int max_sg_segs = 0;
88 MODULE_AUTHOR("Willem Riede");
89 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
90 MODULE_LICENSE("GPL");
91 MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR);
92 MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
94 module_param(max_dev, int, 0444);
95 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
97 module_param(write_threshold_kbs, int, 0644);
98 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
100 module_param(max_sg_segs, int, 0644);
101 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
103 static struct osst_dev_parm {
106 } parms[] __initdata = {
107 { "max_dev", &max_dev },
108 { "write_threshold_kbs", &write_threshold_kbs },
109 { "max_sg_segs", &max_sg_segs }
113 /* Some default definitions have been moved to osst_options.h */
114 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
115 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
117 /* The buffer size should fit into the 24 bits for length in the
118 6-byte SCSI read and write commands. */
119 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
120 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
124 static int debugging = 1;
125 /* uncomment define below to test error recovery */
126 // #define OSST_INJECT_ERRORS 1
129 /* Do not retry! The drive firmware already retries when appropriate,
130 and when it tries to tell us something, we had better listen... */
131 #define MAX_RETRIES 0
133 #define NO_TAPE NOT_READY
135 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
136 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
137 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
139 #define OSST_TIMEOUT (200 * HZ)
140 #define OSST_LONG_TIMEOUT (1800 * HZ)
142 #define TAPE_NR(x) (iminor(x) & ((1 << ST_MODE_SHIFT)-1))
143 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
144 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
145 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
147 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
149 #define SET_DENS_AND_BLK 0x10001
151 static int osst_buffer_size = OSST_BUFFER_SIZE;
152 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
153 static int osst_max_sg_segs = OSST_MAX_SG;
154 static int osst_max_dev = OSST_MAX_TAPES;
155 static int osst_nr_dev;
157 static struct osst_tape **os_scsi_tapes = NULL;
158 static DEFINE_RWLOCK(os_scsi_tapes_lock);
160 static int modes_defined = 0;
162 static struct osst_buffer *new_tape_buffer(int, int, int);
163 static int enlarge_buffer(struct osst_buffer *, int);
164 static void normalize_buffer(struct osst_buffer *);
165 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
166 static int from_buffer(struct osst_buffer *, char __user *, int);
167 static int osst_zero_buffer_tail(struct osst_buffer *);
168 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
169 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
171 static int osst_probe(struct device *);
172 static int osst_remove(struct device *);
174 static struct scsi_driver osst_template = {
177 .owner = THIS_MODULE,
179 .remove = osst_remove,
183 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt,
184 unsigned int cmd_in, unsigned long arg);
186 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip);
188 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt);
190 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt);
192 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending);
194 static inline char *tape_name(struct osst_tape *tape)
196 return tape->drive->disk_name;
199 /* Routines that handle the interaction with mid-layer SCSI routines */
202 /* Normalize Sense */
203 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s)
206 const u8 *sense = SRpnt->sense;
208 s->have_sense = scsi_normalize_sense(SRpnt->sense,
209 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
215 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
216 switch (sense[0] & 0x7f) {
222 s->flags = sense[2] & 0xe0;
229 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
230 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
236 /* Convert the result to success code */
237 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
239 char *name = tape_name(STp);
240 int result = SRpnt->result;
241 u8 * sense = SRpnt->sense, scode;
245 struct st_cmdstatus *cmdstatp;
250 cmdstatp = &STp->buffer->cmdstat;
251 osst_analyze_sense(SRpnt, cmdstatp);
253 if (cmdstatp->have_sense)
254 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
259 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
261 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
262 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
263 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
264 name, scode, sense[12], sense[13]);
265 if (cmdstatp->have_sense)
266 __scsi_print_sense(STp->device, name,
267 SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
271 if (cmdstatp->have_sense && (
273 scode != RECOVERED_ERROR &&
274 /* scode != UNIT_ATTENTION && */
275 scode != BLANK_CHECK &&
276 scode != VOLUME_OVERFLOW &&
277 SRpnt->cmd[0] != MODE_SENSE &&
278 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
279 if (cmdstatp->have_sense) {
280 printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
281 __scsi_print_sense(STp->device, name,
282 SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
285 static int notyetprinted = 1;
288 "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n",
289 name, result, driver_byte(result),
294 "%s:I: This warning may be caused by your scsi controller,\n", name);
296 "%s:I: it has been reported with some Buslogic cards.\n", name);
300 STp->pos_unknown |= STp->device->was_reset;
302 if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
303 STp->recover_count++;
304 STp->recover_erreg++;
307 if (SRpnt->cmd[0] == READ_6)
309 else if (SRpnt->cmd[0] == WRITE_6)
313 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
317 if ((sense[2] & 0xe0) == 0)
324 /* Wakeup from interrupt */
325 static void osst_end_async(struct request *req, blk_status_t status)
327 struct scsi_request *rq = scsi_req(req);
328 struct osst_request *SRpnt = req->end_io_data;
329 struct osst_tape *STp = SRpnt->stp;
330 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
332 STp->buffer->cmdstat.midlevel_result = SRpnt->result = rq->result;
334 STp->write_pending = 0;
337 memcpy(SRpnt->sense, rq->sense, SCSI_SENSE_BUFFERSIZE);
339 complete(SRpnt->waiting);
343 blk_rq_unmap_user(SRpnt->bio);
346 blk_put_request(req);
349 /* osst_request memory management */
350 static struct osst_request *osst_allocate_request(void)
352 return kzalloc(sizeof(struct osst_request), GFP_KERNEL);
355 static void osst_release_request(struct osst_request *streq)
360 static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
361 int cmd_len, int data_direction, void *buffer, unsigned bufflen,
362 int use_sg, int timeout, int retries)
365 struct scsi_request *rq;
366 struct page **pages = NULL;
367 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
370 int write = (data_direction == DMA_TO_DEVICE);
372 req = blk_get_request(SRpnt->stp->device->request_queue,
373 write ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
375 return DRIVER_ERROR << 24;
378 req->rq_flags |= RQF_QUIET;
383 struct scatterlist *sg, *sgl = (struct scatterlist *)buffer;
386 pages = kcalloc(use_sg, sizeof(struct page *), GFP_KERNEL);
390 for_each_sg(sgl, sg, use_sg, i)
391 pages[i] = sg_page(sg);
393 mdata->null_mapped = 1;
395 mdata->page_order = get_order(sgl[0].length);
397 DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order);
400 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
405 SRpnt->bio = req->bio;
406 mdata->pages = pages;
408 } else if (bufflen) {
409 err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL);
414 rq->cmd_len = cmd_len;
415 memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
416 memcpy(rq->cmd, cmd, rq->cmd_len);
417 req->timeout = timeout;
418 rq->retries = retries;
419 req->end_io_data = SRpnt;
421 blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async);
424 blk_put_request(req);
425 return DRIVER_ERROR << 24;
428 /* Do the scsi command. Waits until command performed if do_wait is true.
429 Otherwise osst_write_behind_check() is used to check that the command
431 static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp,
432 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
435 unsigned short use_sg;
436 #ifdef OSST_INJECT_ERRORS
437 static int inject = 0;
438 static int repeat = 0;
440 struct completion *waiting;
442 /* if async, make sure there's no command outstanding */
443 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
444 printk(KERN_ERR "%s: Async command already active.\n",
446 if (signal_pending(current))
447 (STp->buffer)->syscall_result = (-EINTR);
449 (STp->buffer)->syscall_result = (-EBUSY);
454 SRpnt = osst_allocate_request();
456 printk(KERN_ERR "%s: Can't allocate SCSI request.\n",
458 if (signal_pending(current))
459 (STp->buffer)->syscall_result = (-EINTR);
461 (STp->buffer)->syscall_result = (-EBUSY);
467 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
468 which IO is outstanding. It's nulled out when the IO completes. */
470 (STp->buffer)->last_SRpnt = SRpnt;
472 waiting = &STp->wait;
473 init_completion(waiting);
474 SRpnt->waiting = waiting;
476 use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0;
478 bp = (char *)&(STp->buffer->sg[0]);
479 if (STp->buffer->sg_segs < use_sg)
480 use_sg = STp->buffer->sg_segs;
483 bp = (STp->buffer)->b_data;
485 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
486 STp->buffer->cmdstat.have_sense = 0;
487 STp->buffer->syscall_result = 0;
489 if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
490 use_sg, timeout, retries))
491 /* could not allocate the buffer or request was too large */
492 (STp->buffer)->syscall_result = (-EBUSY);
494 wait_for_completion(waiting);
495 SRpnt->waiting = NULL;
496 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
497 #ifdef OSST_INJECT_ERRORS
498 if (STp->buffer->syscall_result == 0 &&
501 ( (++ inject % 83) == 29 ||
502 (STp->first_frame_position == 240
503 /* or STp->read_error_frame to fail again on the block calculated above */ &&
505 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
506 STp->buffer->last_result_fatal = 1;
514 /* Handle the write-behind checking (downs the semaphore) */
515 static void osst_write_behind_check(struct osst_tape *STp)
517 struct osst_buffer * STbuffer;
519 STbuffer = STp->buffer;
522 if (STp->write_pending)
527 wait_for_completion(&(STp->wait));
528 STp->buffer->last_SRpnt->waiting = NULL;
530 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
532 if (STp->buffer->syscall_result)
533 STp->buffer->syscall_result =
534 osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1);
536 STp->first_frame_position++;
538 osst_release_request(STp->buffer->last_SRpnt);
540 if (STbuffer->writing < STbuffer->buffer_bytes)
541 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
543 STbuffer->last_SRpnt = NULL;
544 STbuffer->buffer_bytes -= STbuffer->writing;
545 STbuffer->writing = 0;
552 /* Onstream specific Routines */
554 * Initialize the OnStream AUX
556 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
557 int logical_blk_num, int blk_sz, int blk_cnt)
559 os_aux_t *aux = STp->buffer->aux;
560 os_partition_t *par = &aux->partition;
561 os_dat_t *dat = &aux->dat;
563 if (STp->raw) return;
565 memset(aux, 0, sizeof(*aux));
566 aux->format_id = htonl(0);
567 memcpy(aux->application_sig, "LIN4", 4);
568 aux->hdwr = htonl(0);
569 aux->frame_type = frame_type;
571 switch (frame_type) {
572 case OS_FRAME_TYPE_HEADER:
573 aux->update_frame_cntr = htonl(STp->update_frame_cntr);
574 par->partition_num = OS_CONFIG_PARTITION;
575 par->par_desc_ver = OS_PARTITION_VERSION;
576 par->wrt_pass_cntr = htons(0xffff);
577 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
578 par->first_frame_ppos = htonl(0);
579 par->last_frame_ppos = htonl(0xbb7);
580 aux->frame_seq_num = htonl(0);
581 aux->logical_blk_num_high = htonl(0);
582 aux->logical_blk_num = htonl(0);
583 aux->next_mark_ppos = htonl(STp->first_mark_ppos);
585 case OS_FRAME_TYPE_DATA:
586 case OS_FRAME_TYPE_MARKER:
591 dat->dat_list[0].blk_sz = htonl(blk_sz);
592 dat->dat_list[0].blk_cnt = htons(blk_cnt);
593 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
594 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
595 dat->dat_list[0].reserved = 0;
597 case OS_FRAME_TYPE_EOD:
598 aux->update_frame_cntr = htonl(0);
599 par->partition_num = OS_DATA_PARTITION;
600 par->par_desc_ver = OS_PARTITION_VERSION;
601 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
602 par->first_frame_ppos = htonl(STp->first_data_ppos);
603 par->last_frame_ppos = htonl(STp->capacity);
604 aux->frame_seq_num = htonl(frame_seq_number);
605 aux->logical_blk_num_high = htonl(0);
606 aux->logical_blk_num = htonl(logical_blk_num);
608 default: ; /* probably FILL */
610 aux->filemark_cnt = htonl(STp->filemark_cnt);
611 aux->phys_fm = htonl(0xffffffff);
612 aux->last_mark_ppos = htonl(STp->last_mark_ppos);
613 aux->last_mark_lbn = htonl(STp->last_mark_lbn);
617 * Verify that we have the correct tape frame
619 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
621 char * name = tape_name(STp);
622 os_aux_t * aux = STp->buffer->aux;
623 os_partition_t * par = &(aux->partition);
624 struct st_partstat * STps = &(STp->ps[STp->partition]);
625 unsigned int blk_cnt, blk_sz, i;
628 if (STp->buffer->syscall_result) {
629 for (i=0; i < STp->buffer->sg_segs; i++)
630 memset(page_address(sg_page(&STp->buffer->sg[i])),
631 0, STp->buffer->sg[i].length);
632 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
634 STp->buffer->buffer_bytes = OS_FRAME_SIZE;
637 if (STp->buffer->syscall_result) {
639 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
643 if (ntohl(aux->format_id) != 0) {
645 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
649 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
650 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
652 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
656 if (par->partition_num != OS_DATA_PARTITION) {
657 if (!STp->linux_media || STp->linux_media_version != 2) {
659 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
660 name, par->partition_num);
665 if (par->par_desc_ver != OS_PARTITION_VERSION) {
667 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
671 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
673 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
674 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
678 if (aux->frame_type != OS_FRAME_TYPE_DATA &&
679 aux->frame_type != OS_FRAME_TYPE_EOD &&
680 aux->frame_type != OS_FRAME_TYPE_MARKER) {
683 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
688 if (aux->frame_type == OS_FRAME_TYPE_EOD &&
689 STp->first_frame_position < STp->eod_frame_ppos) {
690 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
691 STp->first_frame_position);
694 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
697 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
698 name, ntohl(aux->frame_seq_num), frame_seq_number);
703 if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
704 STps->eof = ST_FM_HIT;
706 i = ntohl(aux->filemark_cnt);
707 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
708 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
710 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
711 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
712 i, STp->first_frame_position - 1);
714 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
715 if (i >= STp->filemark_cnt)
716 STp->filemark_cnt = i+1;
719 if (aux->frame_type == OS_FRAME_TYPE_EOD) {
720 STps->eof = ST_EOD_1;
721 STp->frame_in_buffer = 1;
723 if (aux->frame_type == OS_FRAME_TYPE_DATA) {
724 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
725 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
726 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
727 STp->buffer->read_pointer = 0;
728 STp->frame_in_buffer = 1;
730 /* See what block size was used to write file */
731 if (STp->block_size != blk_sz && blk_sz > 0) {
733 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
734 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
735 STp->block_size<1024?STp->block_size:STp->block_size/1024,
736 STp->block_size<1024?'b':'k');
737 STp->block_size = blk_sz;
738 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
740 STps->eof = ST_NOEOF;
742 STp->frame_seq_number = ntohl(aux->frame_seq_num);
743 STp->logical_blk_num = ntohl(aux->logical_blk_num);
747 if (STp->read_error_frame == 0)
748 STp->read_error_frame = STp->first_frame_position - 1;
753 * Wait for the unit to become Ready
755 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
756 unsigned timeout, int initial_delay)
758 unsigned char cmd[MAX_COMMAND_SIZE];
759 struct osst_request * SRpnt;
760 unsigned long startwait = jiffies;
763 char * name = tape_name(STp);
765 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
768 if (initial_delay > 0)
769 msleep(jiffies_to_msecs(initial_delay));
771 memset(cmd, 0, MAX_COMMAND_SIZE);
772 cmd[0] = TEST_UNIT_READY;
774 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
776 if (!SRpnt) return (-EBUSY);
778 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
779 (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
780 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) ||
781 ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 &&
782 SRpnt->sense[13] == 0 ) )) {
785 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
786 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
792 memset(cmd, 0, MAX_COMMAND_SIZE);
793 cmd[0] = TEST_UNIT_READY;
795 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
801 if ( STp->buffer->syscall_result &&
802 osst_write_error_recovery(STp, aSRpnt, 0) ) {
804 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
805 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
806 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
807 SRpnt->sense[12], SRpnt->sense[13]);
812 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
818 * Wait for a tape to be inserted in the unit
820 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
822 unsigned char cmd[MAX_COMMAND_SIZE];
823 struct osst_request * SRpnt;
824 unsigned long startwait = jiffies;
827 char * name = tape_name(STp);
829 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
832 memset(cmd, 0, MAX_COMMAND_SIZE);
833 cmd[0] = TEST_UNIT_READY;
835 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
837 if (!SRpnt) return (-EBUSY);
839 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
840 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) {
843 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
844 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
850 memset(cmd, 0, MAX_COMMAND_SIZE);
851 cmd[0] = TEST_UNIT_READY;
853 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
859 if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 &&
860 SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) {
862 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
863 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
864 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
865 SRpnt->sense[12], SRpnt->sense[13]);
870 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
875 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame)
879 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
880 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
881 if (retval) return (retval);
882 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
883 return (osst_get_frame_position(STp, aSRpnt));
887 * Wait for write(s) to complete
889 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
891 unsigned char cmd[MAX_COMMAND_SIZE];
892 struct osst_request * SRpnt;
894 int delay = OSST_WAIT_WRITE_COMPLETE;
896 char * name = tape_name(STp);
898 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
901 memset(cmd, 0, MAX_COMMAND_SIZE);
902 cmd[0] = WRITE_FILEMARKS;
905 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
907 if (!SRpnt) return (-EBUSY);
908 if (STp->buffer->syscall_result) {
909 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) {
910 if (SRpnt->sense[13] == 8) {
911 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
914 result = osst_write_error_recovery(STp, aSRpnt, 0);
916 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
917 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
922 #define OSST_POLL_PER_SEC 10
923 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to)
925 unsigned long startwait = jiffies;
926 char * name = tape_name(STp);
928 char notyetprinted = 1;
930 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
931 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
933 while (time_before (jiffies, startwait + to*HZ))
936 result = osst_get_frame_position(STp, aSRpnt);
938 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
939 return 0; /* successful recovery leaves drive ready for frame */
940 if (result < 0) break;
941 if (STp->first_frame_position == curr &&
943 (signed)STp->last_frame_position > (signed)curr + minlast) ||
944 (minlast >= 0 && STp->cur_frames > minlast)
948 if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC))
950 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
951 name, curr, curr+minlast, STp->first_frame_position,
952 STp->last_frame_position, STp->cur_frames,
953 result, (jiffies-startwait)/HZ,
954 (((jiffies-startwait)%HZ)*10)/HZ);
959 if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted)
961 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
962 name, curr, curr+minlast, STp->first_frame_position,
963 STp->last_frame_position, STp->cur_frames, result);
967 msleep(1000 / OSST_POLL_PER_SEC);
970 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
971 name, curr, curr+minlast, STp->first_frame_position,
972 STp->last_frame_position, STp->cur_frames,
973 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
978 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
980 struct osst_request * SRpnt;
981 unsigned char cmd[MAX_COMMAND_SIZE];
982 unsigned long startwait = jiffies;
984 char * name = tape_name(STp);
988 char * olddata = STp->buffer->b_data;
989 int oldsize = STp->buffer->buffer_size;
991 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
993 memset(cmd, 0, MAX_COMMAND_SIZE);
994 cmd[0] = WRITE_FILEMARKS;
996 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
999 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
1001 if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) {
1003 /* some failure - not just not-ready */
1004 retval = osst_write_error_recovery(STp, aSRpnt, 0);
1007 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
1009 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
1010 memset(cmd, 0, MAX_COMMAND_SIZE);
1011 cmd[0] = READ_POSITION;
1013 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
1016 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
1017 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
1020 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
1022 /* TODO - figure out which error conditions can be handled */
1023 if (STp->buffer->syscall_result)
1025 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
1026 (*aSRpnt)->sense[ 2] & 0x0f,
1027 (*aSRpnt)->sense[12],
1028 (*aSRpnt)->sense[13]);
1034 * Read the next OnStream tape frame at the current location
1036 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
1038 unsigned char cmd[MAX_COMMAND_SIZE];
1039 struct osst_request * SRpnt;
1042 os_aux_t * aux = STp->buffer->aux;
1043 char * name = tape_name(STp);
1047 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
1048 retval = osst_recover_wait_frame(STp, aSRpnt, 0);
1050 memset(cmd, 0, MAX_COMMAND_SIZE);
1057 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
1059 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1060 STp->timeout, MAX_RETRIES, 1);
1065 if ((STp->buffer)->syscall_result) {
1067 if (STp->read_error_frame == 0) {
1068 STp->read_error_frame = STp->first_frame_position;
1070 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
1075 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1077 SRpnt->sense[0], SRpnt->sense[1],
1078 SRpnt->sense[2], SRpnt->sense[3],
1079 SRpnt->sense[4], SRpnt->sense[5],
1080 SRpnt->sense[6], SRpnt->sense[7]);
1084 STp->first_frame_position++;
1089 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
1092 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
1093 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
1094 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
1095 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
1096 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
1097 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
1098 if (aux->frame_type==2)
1099 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
1100 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
1101 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
1107 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
1109 struct st_partstat * STps = &(STp->ps[STp->partition]);
1110 struct osst_request * SRpnt ;
1111 unsigned char cmd[MAX_COMMAND_SIZE];
1113 char * name = tape_name(STp);
1115 if (STps->rw != ST_READING) { /* Initialize read operation */
1116 if (STps->rw == ST_WRITING || STp->dirty) {
1117 STp->write_type = OS_WRITE_DATA;
1118 osst_flush_write_buffer(STp, aSRpnt);
1119 osst_flush_drive_buffer(STp, aSRpnt);
1121 STps->rw = ST_READING;
1122 STp->frame_in_buffer = 0;
1125 * Issue a read 0 command to get the OnStream drive
1126 * read frames into its buffer.
1128 memset(cmd, 0, MAX_COMMAND_SIZE);
1133 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
1135 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
1137 if ((retval = STp->buffer->syscall_result))
1138 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
1144 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt,
1145 int frame_seq_number, int quiet)
1147 struct st_partstat * STps = &(STp->ps[STp->partition]);
1148 char * name = tape_name(STp);
1156 * If we want just any frame (-1) and there is a frame in the buffer, return it
1158 if (frame_seq_number == -1 && STp->frame_in_buffer) {
1160 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1165 * Search and wait for the next logical tape frame
1169 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1170 name, frame_seq_number);
1171 if (STp->read_error_frame) {
1172 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1174 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1175 name, STp->read_error_frame);
1177 STp->read_error_frame = 0;
1184 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1185 name, frame_seq_number, cnt);
1187 if ( osst_initiate_read(STp, aSRpnt)
1188 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1191 position = osst_get_frame_position(STp, aSRpnt);
1192 if (position >= 0xbae && position < 0xbb8)
1194 else if (position > STp->eod_frame_ppos || ++bad == 10) {
1195 position = STp->read_error_frame - 1;
1203 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1206 osst_set_frame_position(STp, aSRpnt, position, 0);
1209 if (osst_verify_frame(STp, frame_seq_number, quiet))
1211 if (osst_verify_frame(STp, -1, quiet)) {
1212 x = ntohl(STp->buffer->aux->frame_seq_num);
1213 if (STp->fast_open) {
1215 "%s:W: Found logical frame %d instead of %d after fast open\n",
1216 name, x, frame_seq_number);
1218 STp->read_error_frame = 0;
1221 if (x > frame_seq_number) {
1223 /* positioning backwards did not bring us to the desired frame */
1224 position = STp->read_error_frame - 1;
1227 position = osst_get_frame_position(STp, aSRpnt)
1228 + frame_seq_number - x - 1;
1230 if (STp->first_frame_position >= 3000 && position < 3000)
1235 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1236 name, x, frame_seq_number,
1237 STp->first_frame_position - position);
1239 osst_set_frame_position(STp, aSRpnt, position, 0);
1245 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1247 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1249 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1252 STp->frame_in_buffer = 0;
1255 STp->recover_count++;
1256 STp->recover_erreg++;
1257 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1258 name, STp->read_error_frame);
1263 if (debugging || STps->eof)
1265 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1266 name, frame_seq_number, STp->frame_seq_number, STps->eof);
1269 STp->read_error_frame = 0;
1273 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num)
1275 struct st_partstat * STps = &(STp->ps[STp->partition]);
1276 char * name = tape_name(STp);
1278 int frame_seq_estimate, ppos_estimate, move;
1280 if (logical_blk_num < 0) logical_blk_num = 0;
1282 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1283 name, logical_blk_num, STp->logical_blk_num,
1284 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1285 STp->block_size<1024?'b':'k');
1287 /* Do we know where we are? */
1288 if (STps->drv_block >= 0) {
1289 move = logical_blk_num - STp->logical_blk_num;
1290 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1291 move /= (OS_DATA_SIZE / STp->block_size);
1292 frame_seq_estimate = STp->frame_seq_number + move;
1294 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1296 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1297 else ppos_estimate = frame_seq_estimate + 20;
1298 while (++retries < 10) {
1299 if (ppos_estimate > STp->eod_frame_ppos-2) {
1300 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1301 ppos_estimate = STp->eod_frame_ppos - 2;
1303 if (frame_seq_estimate < 0) {
1304 frame_seq_estimate = 0;
1307 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1308 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1309 /* we've located the estimated frame, now does it have our block? */
1310 if (logical_blk_num < STp->logical_blk_num ||
1311 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1312 if (STps->eof == ST_FM_HIT)
1313 move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1315 move = logical_blk_num - STp->logical_blk_num;
1316 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1317 move /= (OS_DATA_SIZE / STp->block_size);
1319 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1322 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1323 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1324 STp->logical_blk_num, logical_blk_num, move);
1326 frame_seq_estimate += move;
1327 ppos_estimate += move;
1330 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1331 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1332 STp->logical_blk_num = logical_blk_num;
1335 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1336 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1337 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1340 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1341 if (STps->eof == ST_FM_HIT) {
1343 STps->drv_block = 0;
1345 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1346 STp->logical_blk_num -
1347 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1350 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1354 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1356 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1358 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1359 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1360 STp->logical_blk_num, logical_blk_num);
1362 if (frame_seq_estimate != STp->frame_seq_number)
1363 ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1368 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1369 name, logical_blk_num, STp->logical_blk_num, retries);
1373 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1374 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1375 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1376 * inside each frame. Finally, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1378 #define OSST_FRAME_SHIFT 6
1379 #define OSST_SECTOR_SHIFT 9
1380 #define OSST_SECTOR_MASK 0x03F
1382 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt)
1386 char * name = tape_name(STp);
1389 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1390 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1391 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1392 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1393 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1394 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1396 /* do we know where we are inside a file? */
1397 if (STp->ps[STp->partition].drv_block >= 0) {
1398 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1399 STp->first_frame_position) << OSST_FRAME_SHIFT;
1400 if (STp->ps[STp->partition].rw == ST_WRITING)
1401 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1403 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1405 sector = osst_get_frame_position(STp, aSRpnt);
1407 sector <<= OSST_FRAME_SHIFT;
1412 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector)
1414 struct st_partstat * STps = &(STp->ps[STp->partition]);
1415 int frame = sector >> OSST_FRAME_SHIFT,
1416 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1419 char * name = tape_name(STp);
1421 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1422 name, sector, frame, offset);
1424 if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1426 if (frame <= STp->first_data_ppos) {
1427 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1428 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1430 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1431 if (r < 0) return r;
1433 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1434 if (r < 0) return r;
1436 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1439 STp->logical_blk_num += offset / STp->block_size;
1440 STp->buffer->read_pointer = offset;
1441 STp->buffer->buffer_bytes -= offset;
1443 STp->frame_seq_number++;
1444 STp->frame_in_buffer = 0;
1445 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1446 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1448 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1449 if (STps->eof == ST_FM_HIT) {
1451 STps->drv_block = 0;
1453 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1454 STp->logical_blk_num -
1455 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1458 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1461 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1462 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1463 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1469 * Read back the drive's internal buffer contents, as a part
1470 * of the write error recovery mechanism for old OnStream
1471 * firmware revisions.
1472 * Precondition for this function to work: all frames in the
1473 * drive's buffer must be of one type (DATA, MARK or EOD)!
1475 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
1476 unsigned int frame, unsigned int skip, int pending)
1478 struct osst_request * SRpnt = * aSRpnt;
1479 unsigned char * buffer, * p;
1480 unsigned char cmd[MAX_COMMAND_SIZE];
1481 int flag, new_frame, i;
1482 int nframes = STp->cur_frames;
1483 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1484 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1485 - (nframes + pending - 1);
1486 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1487 - (nframes + pending - 1) * blks_per_frame;
1488 char * name = tape_name(STp);
1489 unsigned long startwait = jiffies;
1491 int dbg = debugging;
1494 if ((buffer = vmalloc(array_size((nframes + 1), OS_DATA_SIZE))) == NULL)
1497 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1498 name, nframes, pending?" and one that was pending":"");
1500 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1502 if (pending && debugging)
1503 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1504 name, frame_seq_number + nframes,
1505 logical_blk_num + nframes * blks_per_frame,
1506 p[0], p[1], p[2], p[3]);
1508 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1510 memset(cmd, 0, MAX_COMMAND_SIZE);
1511 cmd[0] = 0x3C; /* Buffer Read */
1512 cmd[1] = 6; /* Retrieve Faulty Block */
1513 cmd[7] = 32768 >> 8;
1514 cmd[8] = 32768 & 0xff;
1516 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1517 STp->timeout, MAX_RETRIES, 1);
1519 if ((STp->buffer)->syscall_result || !SRpnt) {
1520 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1525 osst_copy_from_buffer(STp->buffer, p);
1528 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1529 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1533 osst_get_frame_position(STp, aSRpnt);
1536 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1538 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1539 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1541 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1544 if (STp->write_type == OS_WRITE_HEADER) {
1546 p += skip * OS_DATA_SIZE;
1548 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1553 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1554 name, new_frame+i, frame_seq_number+i);
1556 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1557 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1558 osst_get_frame_position(STp, aSRpnt);
1561 if (new_frame > frame + 1000) {
1562 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1566 if ( i >= nframes + pending ) break;
1569 osst_copy_to_buffer(STp->buffer, p);
1571 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1573 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1574 logical_blk_num + i*blks_per_frame,
1575 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1576 memset(cmd, 0, MAX_COMMAND_SIZE);
1584 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1585 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1586 p[0], p[1], p[2], p[3]);
1588 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1589 STp->timeout, MAX_RETRIES, 1);
1591 if (STp->buffer->syscall_result)
1594 p += OS_DATA_SIZE; i++;
1596 /* if we just sent the last frame, wait till all successfully written */
1597 if ( i == nframes + pending ) {
1599 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1601 memset(cmd, 0, MAX_COMMAND_SIZE);
1602 cmd[0] = WRITE_FILEMARKS;
1604 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1605 STp->timeout, MAX_RETRIES, 1);
1608 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1609 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1613 flag = STp->buffer->syscall_result;
1614 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1616 memset(cmd, 0, MAX_COMMAND_SIZE);
1617 cmd[0] = TEST_UNIT_READY;
1619 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1622 if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
1623 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
1624 /* in the process of becoming ready */
1628 if (STp->buffer->syscall_result)
1634 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1640 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1641 SRpnt->sense[12] == 0 &&
1642 SRpnt->sense[13] == 2) {
1643 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1645 return (-EIO); /* hit end of tape = fail */
1647 i = ((SRpnt->sense[3] << 24) |
1648 (SRpnt->sense[4] << 16) |
1649 (SRpnt->sense[5] << 8) |
1650 SRpnt->sense[6] ) - new_frame;
1651 p = &buffer[i * OS_DATA_SIZE];
1653 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1655 osst_get_frame_position(STp, aSRpnt);
1657 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1658 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1663 /* error recovery did not successfully complete */
1664 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1665 STp->write_type == OS_WRITE_HEADER?"header":"body");
1668 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1673 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
1674 unsigned int frame, unsigned int skip, int pending)
1676 unsigned char cmd[MAX_COMMAND_SIZE];
1677 struct osst_request * SRpnt;
1678 char * name = tape_name(STp);
1680 int attempts = 1000 / skip;
1682 unsigned long startwait = jiffies;
1684 int dbg = debugging;
1687 while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1692 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1694 expected = frame+skip+STp->cur_frames+pending;
1696 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1697 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1699 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1702 schedule_timeout_interruptible(msecs_to_jiffies(100));
1704 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1706 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1707 name, STp->first_frame_position,
1708 STp->last_frame_position, STp->cur_frames);
1710 frame = STp->last_frame_position;
1714 if (pending && STp->cur_frames < 50) {
1716 memset(cmd, 0, MAX_COMMAND_SIZE);
1721 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1722 name, STp->frame_seq_number-1, STp->first_frame_position);
1724 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1725 STp->timeout, MAX_RETRIES, 1);
1728 if (STp->buffer->syscall_result) { /* additional write error */
1729 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1730 SRpnt->sense[12] == 0 &&
1731 SRpnt->sense[13] == 2) {
1733 "%s:E: Volume overflow in write error recovery\n",
1735 break; /* hit end of tape = fail */
1744 if (STp->cur_frames == 0) {
1747 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1749 if (STp->first_frame_position != expected) {
1750 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1751 name, STp->first_frame_position, expected);
1758 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1759 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1763 schedule_timeout_interruptible(msecs_to_jiffies(100));
1765 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1773 * Error recovery algorithm for the OnStream tape.
1776 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending)
1778 struct osst_request * SRpnt = * aSRpnt;
1779 struct st_partstat * STps = & STp->ps[STp->partition];
1780 char * name = tape_name(STp);
1783 unsigned int frame, skip;
1785 rw_state = STps->rw;
1787 if ((SRpnt->sense[ 2] & 0x0f) != 3
1788 || SRpnt->sense[12] != 12
1789 || SRpnt->sense[13] != 0) {
1791 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1792 SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]);
1796 frame = (SRpnt->sense[3] << 24) |
1797 (SRpnt->sense[4] << 16) |
1798 (SRpnt->sense[5] << 8) |
1800 skip = SRpnt->sense[9];
1803 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1805 osst_get_frame_position(STp, aSRpnt);
1807 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1808 name, STp->first_frame_position, STp->last_frame_position);
1810 switch (STp->write_type) {
1813 case OS_WRITE_NEW_MARK:
1815 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1816 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1817 if (STp->os_fw_rev >= 10600)
1818 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1820 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1821 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1823 retval?"" :"Don't worry, ",
1824 retval?" not ":" ");
1826 case OS_WRITE_LAST_MARK:
1827 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1828 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1831 case OS_WRITE_HEADER:
1832 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1833 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1836 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1837 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1839 osst_get_frame_position(STp, aSRpnt);
1841 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1842 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1843 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1846 STp->recover_count++;
1847 STp->recover_erreg++;
1851 STps->rw = rw_state;
1855 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt,
1856 int mt_op, int mt_count)
1858 char * name = tape_name(STp);
1860 int last_mark_ppos = -1;
1863 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1865 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1867 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1871 if (STp->linux_media_version >= 4) {
1873 * direct lookup in header filemark list
1875 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1876 if (STp->header_ok &&
1877 STp->header_cache != NULL &&
1878 (cnt - mt_count) >= 0 &&
1879 (cnt - mt_count) < OS_FM_TAB_MAX &&
1880 (cnt - mt_count) < STp->filemark_cnt &&
1881 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1883 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1885 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1886 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1887 STp->header_cache == NULL?"lack of header cache":"count out of range");
1889 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1891 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1892 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1893 STp->buffer->aux->last_mark_ppos))?"match":"error",
1894 mt_count, last_mark_ppos);
1896 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1897 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1898 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1901 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1905 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1906 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1907 name, last_mark_ppos);
1913 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1917 while (cnt != mt_count) {
1918 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1919 if (last_mark_ppos == -1)
1922 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1924 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1926 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1928 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1932 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1933 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1934 name, last_mark_ppos);
1939 if (mt_op == MTBSFM) {
1940 STp->frame_seq_number++;
1941 STp->frame_in_buffer = 0;
1942 STp->buffer->buffer_bytes = 0;
1943 STp->buffer->read_pointer = 0;
1944 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1950 * ADRL 1.1 compatible "slow" space filemarks fwd version
1952 * Just scans for the filemark sequentially.
1954 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt,
1955 int mt_op, int mt_count)
1959 char * name = tape_name(STp);
1961 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1963 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1965 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1970 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1972 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1976 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1978 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1980 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1982 if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1984 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1985 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1987 STp->eod_frame_ppos = STp->first_frame_position-1;
1991 if (cnt == mt_count)
1993 STp->frame_in_buffer = 0;
1995 if (mt_op == MTFSF) {
1996 STp->frame_seq_number++;
1997 STp->frame_in_buffer = 0;
1998 STp->buffer->buffer_bytes = 0;
1999 STp->buffer->read_pointer = 0;
2000 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2006 * Fast linux specific version of OnStream FSF
2008 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt,
2009 int mt_op, int mt_count)
2011 char * name = tape_name(STp);
2013 next_mark_ppos = -1;
2016 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
2018 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2020 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
2025 if (STp->linux_media_version >= 4) {
2027 * direct lookup in header filemark list
2029 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
2030 if (STp->header_ok &&
2031 STp->header_cache != NULL &&
2032 (cnt + mt_count) < OS_FM_TAB_MAX &&
2033 (cnt + mt_count) < STp->filemark_cnt &&
2034 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2035 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
2037 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
2039 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
2040 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
2041 STp->header_cache == NULL?"lack of header cache":"count out of range");
2043 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
2045 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2046 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
2047 STp->buffer->aux->last_mark_ppos))?"match":"error",
2048 mt_count, next_mark_ppos);
2050 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
2052 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2054 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2056 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2057 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2059 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2064 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2065 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2066 name, next_mark_ppos);
2069 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
2070 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
2071 name, cnt+mt_count, next_mark_ppos,
2072 ntohl(STp->buffer->aux->filemark_cnt));
2078 * Find nearest (usually previous) marker, then jump from marker to marker
2081 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
2083 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
2085 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
2089 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
2090 if (STp->first_mark_ppos == -1) {
2092 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2094 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2096 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
2097 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2100 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2105 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2106 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
2107 name, STp->first_mark_ppos);
2111 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
2117 while (cnt != mt_count) {
2118 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
2119 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
2121 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2123 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
2126 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
2128 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2130 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2132 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2137 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2138 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2139 name, next_mark_ppos);
2144 if (mt_op == MTFSF) {
2145 STp->frame_seq_number++;
2146 STp->frame_in_buffer = 0;
2147 STp->buffer->buffer_bytes = 0;
2148 STp->buffer->read_pointer = 0;
2149 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2155 * In debug mode, we want to see as many errors as possible
2156 * to test the error recovery mechanism.
2159 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries)
2161 unsigned char cmd[MAX_COMMAND_SIZE];
2162 struct osst_request * SRpnt = * aSRpnt;
2163 char * name = tape_name(STp);
2165 memset(cmd, 0, MAX_COMMAND_SIZE);
2166 cmd[0] = MODE_SELECT;
2168 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2170 (STp->buffer)->b_data[0] = cmd[4] - 1;
2171 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
2172 (STp->buffer)->b_data[2] = 0; /* Reserved */
2173 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
2174 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2175 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2176 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2177 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2180 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2182 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2185 if ((STp->buffer)->syscall_result)
2186 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2191 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt)
2194 int this_mark_ppos = STp->first_frame_position;
2195 int this_mark_lbn = STp->logical_blk_num;
2197 char * name = tape_name(STp);
2200 if (STp->raw) return 0;
2202 STp->write_type = OS_WRITE_NEW_MARK;
2204 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2205 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2208 result = osst_flush_write_buffer(STp, aSRpnt);
2209 result |= osst_flush_drive_buffer(STp, aSRpnt);
2210 STp->last_mark_ppos = this_mark_ppos;
2211 STp->last_mark_lbn = this_mark_lbn;
2212 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2213 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2214 if (STp->filemark_cnt++ == 0)
2215 STp->first_mark_ppos = this_mark_ppos;
2219 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt)
2223 char * name = tape_name(STp);
2226 if (STp->raw) return 0;
2228 STp->write_type = OS_WRITE_EOD;
2229 STp->eod_frame_ppos = STp->first_frame_position;
2231 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2232 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2236 result = osst_flush_write_buffer(STp, aSRpnt);
2237 result |= osst_flush_drive_buffer(STp, aSRpnt);
2238 STp->eod_frame_lfa = --(STp->frame_seq_number);
2242 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2244 char * name = tape_name(STp);
2247 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2249 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2250 osst_set_frame_position(STp, aSRpnt, where, 0);
2251 STp->write_type = OS_WRITE_FILLER;
2253 memcpy(STp->buffer->b_data, "Filler", 6);
2254 STp->buffer->buffer_bytes = 6;
2256 if (osst_flush_write_buffer(STp, aSRpnt)) {
2257 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2262 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2264 return osst_flush_drive_buffer(STp, aSRpnt);
2267 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2269 char * name = tape_name(STp);
2273 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2275 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2276 osst_set_frame_position(STp, aSRpnt, where, 0);
2277 STp->write_type = OS_WRITE_HEADER;
2279 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2280 STp->buffer->buffer_bytes = sizeof(os_header_t);
2282 if (osst_flush_write_buffer(STp, aSRpnt)) {
2283 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2287 result = osst_flush_drive_buffer(STp, aSRpnt);
2289 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2294 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod)
2296 os_header_t * header;
2298 char * name = tape_name(STp);
2301 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2303 if (STp->raw) return 0;
2305 if (STp->header_cache == NULL) {
2306 if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
2307 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2310 memset(STp->header_cache, 0, sizeof(os_header_t));
2312 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2315 if (STp->header_ok) STp->update_frame_cntr++;
2316 else STp->update_frame_cntr = 0;
2318 header = STp->header_cache;
2319 strcpy(header->ident_str, "ADR_SEQ");
2320 header->major_rev = 1;
2321 header->minor_rev = 4;
2322 header->ext_trk_tb_off = htons(17192);
2323 header->pt_par_num = 1;
2324 header->partition[0].partition_num = OS_DATA_PARTITION;
2325 header->partition[0].par_desc_ver = OS_PARTITION_VERSION;
2326 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2327 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2328 header->partition[0].last_frame_ppos = htonl(STp->capacity);
2329 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2330 header->cfg_col_width = htonl(20);
2331 header->dat_col_width = htonl(1500);
2332 header->qfa_col_width = htonl(0);
2333 header->ext_track_tb.nr_stream_part = 1;
2334 header->ext_track_tb.et_ent_sz = 32;
2335 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2336 header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2337 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2338 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2339 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa);
2340 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
2341 header->dat_fm_tab.fm_part_num = 0;
2342 header->dat_fm_tab.fm_tab_ent_sz = 4;
2343 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2344 STp->filemark_cnt:OS_FM_TAB_MAX);
2346 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2347 if (STp->update_frame_cntr == 0)
2348 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2349 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2353 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2355 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2358 printk(KERN_ERR "%s:E: Write header failed\n", name);
2360 memcpy(STp->application_sig, "LIN4", 4);
2361 STp->linux_media = 1;
2362 STp->linux_media_version = 4;
2368 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt)
2370 if (STp->header_cache != NULL)
2371 memset(STp->header_cache, 0, sizeof(os_header_t));
2373 STp->logical_blk_num = STp->frame_seq_number = 0;
2374 STp->frame_in_buffer = 0;
2375 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2376 STp->filemark_cnt = 0;
2377 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2378 return osst_write_header(STp, aSRpnt, 1);
2381 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos)
2383 char * name = tape_name(STp);
2384 os_header_t * header;
2387 int linux_media_version,
2393 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2394 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2395 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2396 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2397 if (osst_initiate_read (STp, aSRpnt)) {
2398 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2402 if (osst_read_frame(STp, aSRpnt, 180)) {
2404 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2408 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2409 aux = STp->buffer->aux;
2410 if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2412 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2416 if (ntohl(aux->frame_seq_num) != 0 ||
2417 ntohl(aux->logical_blk_num) != 0 ||
2418 aux->partition.partition_num != OS_CONFIG_PARTITION ||
2419 ntohl(aux->partition.first_frame_ppos) != 0 ||
2420 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2422 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2423 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2424 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2425 ntohl(aux->partition.last_frame_ppos));
2429 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2430 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2431 strlcpy(id_string, header->ident_str, 8);
2433 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2437 update_frame_cntr = ntohl(aux->update_frame_cntr);
2438 if (update_frame_cntr < STp->update_frame_cntr) {
2440 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2441 name, ppos, update_frame_cntr, STp->update_frame_cntr);
2445 if (header->major_rev != 1 || header->minor_rev != 4 ) {
2447 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2448 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2449 header->minor_rev > 4 )? "Invalid" : "Warning:",
2450 header->major_rev, header->minor_rev);
2452 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2456 if (header->pt_par_num != 1)
2457 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2458 name, header->pt_par_num);
2460 memcpy(id_string, aux->application_sig, 4);
2462 if (memcmp(id_string, "LIN", 3) == 0) {
2463 STp->linux_media = 1;
2464 linux_media_version = id_string[3] - '0';
2465 if (linux_media_version != 4)
2466 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2467 name, linux_media_version);
2469 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2472 if (linux_media_version < STp->linux_media_version) {
2474 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2475 name, ppos, linux_media_version);
2479 if (linux_media_version > STp->linux_media_version) {
2481 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2482 name, ppos, linux_media_version);
2484 memcpy(STp->application_sig, id_string, 5);
2485 STp->linux_media_version = linux_media_version;
2486 STp->update_frame_cntr = -1;
2488 if (update_frame_cntr > STp->update_frame_cntr) {
2490 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2491 name, ppos, update_frame_cntr);
2493 if (STp->header_cache == NULL) {
2494 if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
2495 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2499 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2502 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2503 header = STp->header_cache; /* further accesses from cached (full) copy */
2505 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2506 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2507 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2508 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2509 STp->filemark_cnt = ntohl(aux->filemark_cnt);
2510 STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2511 STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2512 STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2513 STp->update_frame_cntr = update_frame_cntr;
2515 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2516 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2517 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2518 STp->first_data_ppos,
2519 ntohl(header->partition[0].last_frame_ppos),
2520 ntohl(header->partition[0].eod_frame_ppos));
2521 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2522 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2524 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2526 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2528 memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2529 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2530 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2532 if (header->minor_rev == 4 &&
2533 (header->ext_trk_tb_off != htons(17192) ||
2534 header->partition[0].partition_num != OS_DATA_PARTITION ||
2535 header->partition[0].par_desc_ver != OS_PARTITION_VERSION ||
2536 header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2537 header->cfg_col_width != htonl(20) ||
2538 header->dat_col_width != htonl(1500) ||
2539 header->qfa_col_width != htonl(0) ||
2540 header->ext_track_tb.nr_stream_part != 1 ||
2541 header->ext_track_tb.et_ent_sz != 32 ||
2542 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION ||
2543 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2544 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2545 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2546 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) ||
2547 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION ||
2548 header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2549 header->dat_fm_tab.fm_tab_ent_cnt !=
2550 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2551 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2558 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt)
2563 char * name = tape_name(STp);
2565 position = osst_get_frame_position(STp, aSRpnt);
2568 STp->header_ok = STp->linux_media = 1;
2569 STp->linux_media_version = 0;
2572 STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2573 STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2574 STp->eod_frame_ppos = STp->first_data_ppos = -1;
2575 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2577 printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2580 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2581 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2583 first = position==10?0xbae: 5;
2584 last = position==10?0xbb3:10;
2586 for (ppos = first; ppos < last; ppos++)
2587 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2590 first = position==10? 5:0xbae;
2591 last = position==10?10:0xbb3;
2593 for (ppos = first; ppos < last; ppos++)
2594 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2598 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2599 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2600 osst_set_frame_position(STp, aSRpnt, 10, 0);
2603 if (position <= STp->first_data_ppos) {
2604 position = STp->first_data_ppos;
2605 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2607 osst_set_frame_position(STp, aSRpnt, position, 0);
2613 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt)
2615 int frame_position = STp->first_frame_position;
2616 int frame_seq_numbr = STp->frame_seq_number;
2617 int logical_blk_num = STp->logical_blk_num;
2618 int halfway_frame = STp->frame_in_buffer;
2619 int read_pointer = STp->buffer->read_pointer;
2620 int prev_mark_ppos = -1;
2621 int actual_mark_ppos, i, n;
2623 char * name = tape_name(STp);
2625 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2627 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2628 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2630 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2634 if (STp->linux_media_version >= 4) {
2635 for (i=0; i<STp->filemark_cnt; i++)
2636 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2639 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2640 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2641 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2642 if (frame_position != STp->first_frame_position ||
2643 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2644 prev_mark_ppos != actual_mark_ppos ) {
2646 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2647 STp->first_frame_position, frame_position,
2648 STp->frame_seq_number + (halfway_frame?0:1),
2649 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2653 if (halfway_frame) {
2654 /* prepare buffer for append and rewrite on top of original */
2655 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2656 STp->buffer->buffer_bytes = read_pointer;
2657 STp->ps[STp->partition].rw = ST_WRITING;
2660 STp->frame_in_buffer = halfway_frame;
2661 STp->frame_seq_number = frame_seq_numbr;
2662 STp->logical_blk_num = logical_blk_num;
2666 /* Acc. to OnStream, the vers. numbering is the following:
2667 * X.XX for released versions (X=digit),
2668 * XXXY for unreleased versions (Y=letter)
2669 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2670 * This fn makes monoton numbers out of this scheme ...
2672 static unsigned int osst_parse_firmware_rev (const char * str)
2674 if (str[1] == '.') {
2675 return (str[0]-'0')*10000
2679 return (str[0]-'0')*10000
2681 +(str[2]-'0')*100 - 100
2687 * Configure the OnStream SCII tape drive for default operation
2689 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
2691 unsigned char cmd[MAX_COMMAND_SIZE];
2692 char * name = tape_name(STp);
2693 struct osst_request * SRpnt = * aSRpnt;
2694 osst_mode_parameter_header_t * header;
2695 osst_block_size_page_t * bs;
2696 osst_capabilities_page_t * cp;
2697 osst_tape_paramtr_page_t * prm;
2698 int drive_buffer_size;
2700 if (STp->ready != ST_READY) {
2702 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2707 if (STp->os_fw_rev < 10600) {
2708 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2709 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2713 * Configure 32.5KB (data+aux) frame size.
2714 * Get the current frame size from the block size mode page
2716 memset(cmd, 0, MAX_COMMAND_SIZE);
2717 cmd[0] = MODE_SENSE;
2719 cmd[2] = BLOCK_SIZE_PAGE;
2720 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2722 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2723 if (SRpnt == NULL) {
2725 printk(OSST_DEB_MSG "osst :D: Busy\n");
2730 if ((STp->buffer)->syscall_result != 0) {
2731 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2735 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2736 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2739 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2740 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No");
2741 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2742 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2746 * Configure default auto columns mode, 32.5KB transfer mode
2754 memset(cmd, 0, MAX_COMMAND_SIZE);
2755 cmd[0] = MODE_SELECT;
2757 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2759 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2761 if ((STp->buffer)->syscall_result != 0) {
2762 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2767 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2769 * In debug mode, we want to see as many errors as possible
2770 * to test the error recovery mechanism.
2772 osst_set_retries(STp, aSRpnt, 0);
2777 * Set vendor name to 'LIN4' for "Linux support version 4".
2780 memset(cmd, 0, MAX_COMMAND_SIZE);
2781 cmd[0] = MODE_SELECT;
2783 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2785 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2786 header->medium_type = 0; /* Medium Type - ignoring */
2787 header->dsp = 0; /* Reserved */
2788 header->bdl = 0; /* Block Descriptor Length */
2790 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2791 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2792 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2793 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2794 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2795 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2796 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2797 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2799 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2802 if ((STp->buffer)->syscall_result != 0) {
2803 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2804 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2808 memset(cmd, 0, MAX_COMMAND_SIZE);
2809 cmd[0] = MODE_SENSE;
2811 cmd[2] = CAPABILITIES_PAGE;
2812 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2814 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2817 if ((STp->buffer)->syscall_result != 0) {
2818 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2822 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2823 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2824 sizeof(osst_mode_parameter_header_t) + header->bdl);
2826 drive_buffer_size = ntohs(cp->buffer_size) / 2;
2828 memset(cmd, 0, MAX_COMMAND_SIZE);
2829 cmd[0] = MODE_SENSE;
2831 cmd[2] = TAPE_PARAMTR_PAGE;
2832 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2834 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2837 if ((STp->buffer)->syscall_result != 0) {
2838 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2842 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2843 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2844 sizeof(osst_mode_parameter_header_t) + header->bdl);
2846 STp->density = prm->density;
2847 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2849 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2850 name, STp->density, STp->capacity / 32, drive_buffer_size);
2858 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2859 it messes up the block number). */
2860 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward)
2863 char * name = tape_name(STp);
2867 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2868 name, forward ? "forward" : "backward");
2872 /* assumes that the filemark is already read by the drive, so this is low cost */
2873 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2876 /* assumes this is only called if we just read the filemark! */
2877 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2880 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2881 name, forward ? "forward" : "backward");
2887 /* Get the tape position. */
2889 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
2891 unsigned char scmd[MAX_COMMAND_SIZE];
2892 struct osst_request * SRpnt;
2894 char * name = tape_name(STp);
2896 /* KG: We want to be able to use it for checking Write Buffer availability
2897 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2899 char * olddata = STp->buffer->b_data;
2900 int oldsize = STp->buffer->buffer_size;
2902 if (STp->ready != ST_READY) return (-EIO);
2904 memset (scmd, 0, MAX_COMMAND_SIZE);
2905 scmd[0] = READ_POSITION;
2907 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2908 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2909 STp->timeout, MAX_RETRIES, 1);
2911 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2916 if (STp->buffer->syscall_result)
2917 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */
2919 if (result == -EINVAL)
2920 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2922 if (result == -EIO) { /* re-read position - this needs to preserve media errors */
2923 unsigned char mysense[16];
2924 memcpy (mysense, SRpnt->sense, 16);
2925 memset (scmd, 0, MAX_COMMAND_SIZE);
2926 scmd[0] = READ_POSITION;
2927 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2928 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2929 STp->timeout, MAX_RETRIES, 1);
2931 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2932 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2933 SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]);
2935 if (!STp->buffer->syscall_result)
2936 memcpy (SRpnt->sense, mysense, 16);
2938 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2940 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2941 + ((STp->buffer)->b_data[5] << 16)
2942 + ((STp->buffer)->b_data[6] << 8)
2943 + (STp->buffer)->b_data[7];
2944 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2945 + ((STp->buffer)->b_data[ 9] << 16)
2946 + ((STp->buffer)->b_data[10] << 8)
2947 + (STp->buffer)->b_data[11];
2948 STp->cur_frames = (STp->buffer)->b_data[15];
2951 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2952 STp->first_frame_position, STp->last_frame_position,
2953 ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2954 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2958 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2960 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2961 STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2963 STp->first_frame_position = STp->last_frame_position;
2966 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2968 return (result == 0 ? STp->first_frame_position : result);
2972 /* Set the tape block */
2973 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip)
2975 unsigned char scmd[MAX_COMMAND_SIZE];
2976 struct osst_request * SRpnt;
2977 struct st_partstat * STps;
2979 int pp = (ppos == 3000 && !skip)? 0 : ppos;
2980 char * name = tape_name(STp);
2982 if (STp->ready != ST_READY) return (-EIO);
2984 STps = &(STp->ps[STp->partition]);
2986 if (ppos < 0 || ppos > STp->capacity) {
2987 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2988 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2995 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2997 memset (scmd, 0, MAX_COMMAND_SIZE);
3000 scmd[3] = (pp >> 24);
3001 scmd[4] = (pp >> 16);
3002 scmd[5] = (pp >> 8);
3007 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
3013 if ((STp->buffer)->syscall_result != 0) {
3015 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
3016 name, STp->first_frame_position, pp);
3021 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
3022 } while ((pp != ppos) && (pp = ppos));
3023 STp->first_frame_position = STp->last_frame_position = ppos;
3024 STps->eof = ST_NOEOF;
3027 STp->frame_in_buffer = 0;
3031 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT)
3033 struct st_partstat * STps = &(STp->ps[STp->partition]);
3036 if (STp->write_type != OS_WRITE_NEW_MARK) {
3037 /* true unless the user wrote the filemark for us */
3038 result = osst_flush_drive_buffer(STp, aSRpnt);
3039 if (result < 0) goto out;
3040 result = osst_write_filemark(STp, aSRpnt);
3041 if (result < 0) goto out;
3043 if (STps->drv_file >= 0)
3045 STps->drv_block = 0;
3047 result = osst_write_eod(STp, aSRpnt);
3048 osst_write_header(STp, aSRpnt, leave_at_EOT);
3055 /* osst versions of st functions - augmented and stripped to suit OnStream only */
3057 /* Flush the write buffer (never need to write if variable blocksize). */
3058 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt)
3060 int offset, transfer, blks = 0;
3062 unsigned char cmd[MAX_COMMAND_SIZE];
3063 struct osst_request * SRpnt = *aSRpnt;
3064 struct st_partstat * STps;
3065 char * name = tape_name(STp);
3067 if ((STp->buffer)->writing) {
3068 if (SRpnt == (STp->buffer)->last_SRpnt)
3070 { printk(OSST_DEB_MSG
3071 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name);
3073 *aSRpnt = SRpnt = NULL;
3077 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name);
3079 osst_write_behind_check(STp);
3080 if ((STp->buffer)->syscall_result) {
3083 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
3084 name, (STp->buffer)->midlevel_result);
3086 if ((STp->buffer)->midlevel_result == INT_MAX)
3093 if (STp->dirty == 1) {
3096 STps = &(STp->ps[STp->partition]);
3097 STps->rw = ST_WRITING;
3098 offset = STp->buffer->buffer_bytes;
3099 blks = (offset + STp->block_size - 1) / STp->block_size;
3100 transfer = OS_FRAME_SIZE;
3102 if (offset < OS_DATA_SIZE)
3103 osst_zero_buffer_tail(STp->buffer);
3106 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
3107 result = osst_recover_wait_frame(STp, aSRpnt, 1);
3109 memset(cmd, 0, MAX_COMMAND_SIZE);
3114 switch (STp->write_type) {
3118 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
3119 name, blks, STp->frame_seq_number,
3120 STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3122 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3123 STp->logical_blk_num - blks, STp->block_size, blks);
3126 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
3127 STp->logical_blk_num, 0, 0);
3129 case OS_WRITE_NEW_MARK:
3130 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
3131 STp->logical_blk_num++, 0, blks=1);
3133 case OS_WRITE_HEADER:
3134 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
3136 default: /* probably FILLER */
3137 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
3141 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transferring %d bytes in %d lblocks.\n",
3142 name, offset, transfer, blks);
3145 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3146 STp->timeout, MAX_RETRIES, 1);
3151 if ((STp->buffer)->syscall_result != 0) {
3154 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3155 name, SRpnt->sense[0], SRpnt->sense[2],
3156 SRpnt->sense[12], SRpnt->sense[13]);
3158 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3159 (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3160 (SRpnt->sense[2] & 0x0f) == NO_SENSE) {
3162 (STp->buffer)->buffer_bytes = 0;
3166 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3167 printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3171 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
3174 STp->first_frame_position++;
3176 (STp->buffer)->buffer_bytes = 0;
3180 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3186 /* Flush the tape buffer. The tape will be positioned correctly unless
3187 seek_next is true. */
3188 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next)
3190 struct st_partstat * STps;
3191 int backspace = 0, result = 0;
3193 char * name = tape_name(STp);
3197 * If there was a bus reset, block further access
3200 if( STp->pos_unknown)
3203 if (STp->ready != ST_READY)
3206 STps = &(STp->ps[STp->partition]);
3207 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
3208 STp->write_type = OS_WRITE_DATA;
3209 return osst_flush_write_buffer(STp, aSRpnt);
3211 if (STp->block_size == 0)
3215 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3218 if (!STp->can_bsr) {
3219 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3220 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3221 (STp->buffer)->buffer_bytes = 0;
3222 (STp->buffer)->read_pointer = 0;
3223 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3227 if (STps->eof == ST_FM_HIT) {
3228 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3230 STps->eof = ST_NOEOF;
3232 if (STps->drv_file >= 0)
3234 STps->drv_block = 0;
3237 if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3238 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3240 else if (STps->eof == ST_FM_HIT) {
3241 if (STps->drv_file >= 0)
3243 STps->drv_block = 0;
3244 STps->eof = ST_NOEOF;
3250 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous)
3252 unsigned char cmd[MAX_COMMAND_SIZE];
3253 struct osst_request * SRpnt;
3256 char * name = tape_name(STp);
3259 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3261 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3263 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3266 /* error recovery may have bumped us past the header partition */
3267 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3269 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3271 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3276 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3277 if (osst_recover_wait_frame(STp, aSRpnt, 1))
3280 // osst_build_stats(STp, &SRpnt);
3282 STp->ps[STp->partition].rw = ST_WRITING;
3283 STp->write_type = OS_WRITE_DATA;
3285 memset(cmd, 0, MAX_COMMAND_SIZE);
3288 cmd[4] = 1; /* one frame at a time... */
3289 blks = STp->buffer->buffer_bytes / STp->block_size;
3292 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3293 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3295 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3296 STp->logical_blk_num - blks, STp->block_size, blks);
3300 STp->write_pending = 1;
3302 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3303 MAX_RETRIES, synchronous);
3309 if (STp->buffer->syscall_result != 0) {
3312 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3314 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3315 (SRpnt->sense[2] & 0x40)) {
3316 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW)
3320 if (osst_write_error_recovery(STp, aSRpnt, 1))
3325 STp->first_frame_position++;
3333 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */
3334 static int do_door_lock(struct osst_tape * STp, int do_lock)
3339 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3342 retval = scsi_set_medium_removal(STp->device,
3343 do_lock ? SCSI_REMOVAL_PREVENT : SCSI_REMOVAL_ALLOW);
3345 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3347 STp->door_locked = ST_LOCK_FAILS;
3351 /* Set the internal state after reset */
3352 static void reset_state(struct osst_tape *STp)
3355 struct st_partstat *STps;
3357 STp->pos_unknown = 0;
3358 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3359 STps = &(STp->ps[i]);
3361 STps->eof = ST_NOEOF;
3363 STps->last_block_valid = 0;
3364 STps->drv_block = -1;
3365 STps->drv_file = -1;
3370 /* Entry points to osst */
3373 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3375 ssize_t total, retval = 0;
3376 ssize_t i, do_count, blks, transfer;
3377 int write_threshold;
3378 int doing_write = 0;
3379 const char __user * b_point;
3380 struct osst_request * SRpnt = NULL;
3381 struct st_modedef * STm;
3382 struct st_partstat * STps;
3383 struct osst_tape * STp = filp->private_data;
3384 char * name = tape_name(STp);
3387 if (mutex_lock_interruptible(&STp->lock))
3388 return (-ERESTARTSYS);
3391 * If we are in the middle of error recovery, don't let anyone
3392 * else try and use this device. Also, if error recovery fails, it
3393 * may try and take the device offline, in which case all further
3394 * access to the device is prohibited.
3396 if( !scsi_block_when_processing_errors(STp->device) ) {
3401 if (STp->ready != ST_READY) {
3402 if (STp->ready == ST_NO_TAPE)
3403 retval = (-ENOMEDIUM);
3408 STm = &(STp->modes[STp->current_mode]);
3409 if (!STm->defined) {
3417 * If there was a bus reset, block further access
3420 if (STp->pos_unknown) {
3427 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3433 if (STp->write_prot) {
3438 /* Write must be integral number of blocks */
3439 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3440 printk(KERN_ERR "%s:E: Write (%zd bytes) not multiple of tape block size (%d%c).\n",
3441 name, count, STp->block_size<1024?
3442 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3447 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3448 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3449 name, STp->first_frame_position);
3454 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3455 STp->door_locked = ST_LOCKED_AUTO;
3457 STps = &(STp->ps[STp->partition]);
3459 if (STps->rw == ST_READING) {
3461 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3462 STps->drv_file, STps->drv_block);
3464 retval = osst_flush_buffer(STp, &SRpnt, 0);
3469 if (STps->rw != ST_WRITING) {
3470 /* Are we totally rewriting this tape? */
3471 if (!STp->header_ok ||
3472 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3473 (STps->drv_file == 0 && STps->drv_block == 0)) {
3474 STp->wrt_pass_cntr++;
3476 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3477 name, STp->wrt_pass_cntr);
3479 osst_reset_header(STp, &SRpnt);
3480 STps->drv_file = STps->drv_block = 0;
3482 /* Do we know where we'll be writing on the tape? */
3484 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3485 STps->drv_file < 0 || STps->drv_block < 0) {
3486 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3487 STps->drv_file = STp->filemark_cnt;
3488 STps->drv_block = 0;
3491 /* We have no idea where the tape is positioned - give up */
3494 "%s:D: Cannot write at indeterminate position.\n", name);
3500 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3501 STp->filemark_cnt = STps->drv_file;
3502 STp->last_mark_ppos =
3503 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3505 "%s:W: Overwriting file %d with old write pass counter %d\n",
3506 name, STps->drv_file, STp->wrt_pass_cntr);
3508 "%s:W: may lead to stale data being accepted on reading back!\n",
3512 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3513 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3519 if (!STp->header_ok) {
3521 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3527 if ((STp->buffer)->writing) {
3528 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3529 osst_write_behind_check(STp);
3530 if ((STp->buffer)->syscall_result) {
3533 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3534 (STp->buffer)->midlevel_result);
3536 if ((STp->buffer)->midlevel_result == INT_MAX)
3537 STps->eof = ST_EOM_OK;
3539 STps->eof = ST_EOM_ERROR;
3542 if (STps->eof == ST_EOM_OK) {
3546 else if (STps->eof == ST_EOM_ERROR) {
3551 /* Check the buffer readability in cases where copy_user might catch
3552 the problems after some tape movement. */
3553 if ((copy_from_user(&i, buf, 1) != 0 ||
3554 copy_from_user(&i, buf + count - 1, 1) != 0)) {
3559 if (!STm->do_buffer_writes) {
3560 write_threshold = 1;
3563 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3564 if (!STm->do_async_writes)
3570 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3571 name, (int) count, STps->drv_file, STps->drv_block,
3572 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3575 while ((STp->buffer)->buffer_bytes + count > write_threshold)
3578 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3579 (STp->buffer)->buffer_bytes;
3580 if (do_count > count)
3583 i = append_to_buffer(b_point, STp->buffer, do_count);
3589 blks = do_count / STp->block_size;
3590 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3592 i = osst_write_frame(STp, &SRpnt, 1);
3594 if (i == (-ENOSPC)) {
3595 transfer = STp->buffer->writing; /* FIXME -- check this logic */
3596 if (transfer <= do_count) {
3597 *ppos += do_count - transfer;
3598 count -= do_count - transfer;
3599 if (STps->drv_block >= 0) {
3600 STps->drv_block += (do_count - transfer) / STp->block_size;
3602 STps->eof = ST_EOM_OK;
3603 retval = (-ENOSPC); /* EOM within current request */
3606 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3607 name, (int) transfer);
3611 STps->eof = ST_EOM_ERROR;
3612 STps->drv_block = (-1); /* Too cautious? */
3613 retval = (-EIO); /* EOM for old data */
3616 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3624 if (SRpnt != NULL) {
3625 osst_release_request(SRpnt);
3628 STp->buffer->buffer_bytes = 0;
3631 retval = total - count;
3636 b_point += do_count;
3638 if (STps->drv_block >= 0) {
3639 STps->drv_block += blks;
3641 STp->buffer->buffer_bytes = 0;
3643 } /* end while write threshold exceeded */
3647 i = append_to_buffer(b_point, STp->buffer, count);
3652 blks = count / STp->block_size;
3653 STp->logical_blk_num += blks;
3654 if (STps->drv_block >= 0) {
3655 STps->drv_block += blks;
3661 if (doing_write && (STp->buffer)->syscall_result != 0) {
3662 retval = (STp->buffer)->syscall_result;
3666 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3667 /* Schedule an asynchronous write */
3668 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3669 STp->block_size) * STp->block_size;
3670 STp->dirty = !((STp->buffer)->writing ==
3671 (STp->buffer)->buffer_bytes);
3673 i = osst_write_frame(STp, &SRpnt, 0);
3678 SRpnt = NULL; /* Prevent releasing this request! */
3680 STps->at_sm &= (total == 0);
3682 STps->eof = ST_NOEOF;
3687 if (SRpnt != NULL) osst_release_request(SRpnt);
3689 mutex_unlock(&STp->lock);
3696 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3698 ssize_t total, retval = 0;
3699 ssize_t i, transfer;
3701 struct st_modedef * STm;
3702 struct st_partstat * STps;
3703 struct osst_request * SRpnt = NULL;
3704 struct osst_tape * STp = filp->private_data;
3705 char * name = tape_name(STp);
3708 if (mutex_lock_interruptible(&STp->lock))
3709 return (-ERESTARTSYS);
3712 * If we are in the middle of error recovery, don't let anyone
3713 * else try and use this device. Also, if error recovery fails, it
3714 * may try and take the device offline, in which case all further
3715 * access to the device is prohibited.
3717 if( !scsi_block_when_processing_errors(STp->device) ) {
3722 if (STp->ready != ST_READY) {
3723 if (STp->ready == ST_NO_TAPE)
3724 retval = (-ENOMEDIUM);
3729 STm = &(STp->modes[STp->current_mode]);
3730 if (!STm->defined) {
3736 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3741 /* Must have initialized medium */
3742 if (!STp->header_ok) {
3747 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3748 STp->door_locked = ST_LOCKED_AUTO;
3750 STps = &(STp->ps[STp->partition]);
3751 if (STps->rw == ST_WRITING) {
3752 retval = osst_flush_buffer(STp, &SRpnt, 0);
3756 /* FIXME -- this may leave the tape without EOD and up2date headers */
3759 if ((count % STp->block_size) != 0) {
3761 "%s:W: Read (%zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3762 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3766 if (debugging && STps->eof != ST_NOEOF)
3767 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3768 STps->eof, (STp->buffer)->buffer_bytes);
3770 if ((STp->buffer)->buffer_bytes == 0 &&
3771 STps->eof >= ST_EOD_1) {
3772 if (STps->eof < ST_EOD) {
3777 retval = (-EIO); /* EOM or Blank Check */
3781 /* Check the buffer writability before any tape movement. Don't alter
3783 if (copy_from_user(&i, buf, 1) != 0 ||
3784 copy_to_user (buf, &i, 1) != 0 ||
3785 copy_from_user(&i, buf + count - 1, 1) != 0 ||
3786 copy_to_user (buf + count - 1, &i, 1) != 0) {
3791 /* Loop until enough data in buffer or a special condition found */
3792 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3794 /* Get new data if the buffer is empty */
3795 if ((STp->buffer)->buffer_bytes == 0) {
3796 if (STps->eof == ST_FM_HIT)
3798 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3799 if (special < 0) { /* No need to continue read */
3800 STp->frame_in_buffer = 0;
3806 /* Move the data from driver buffer to user buffer */
3807 if ((STp->buffer)->buffer_bytes > 0) {
3809 if (debugging && STps->eof != ST_NOEOF)
3810 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3811 STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total));
3813 /* force multiple of block size, note block_size may have been adjusted */
3814 transfer = (((STp->buffer)->buffer_bytes < count - total ?
3815 (STp->buffer)->buffer_bytes : count - total)/
3816 STp->block_size) * STp->block_size;
3818 if (transfer == 0) {
3820 "%s:W: Nothing can be transferred, requested %zd, tape block size (%d%c).\n",
3821 name, count, STp->block_size < 1024?
3822 STp->block_size:STp->block_size/1024,
3823 STp->block_size<1024?'b':'k');
3826 i = from_buffer(STp->buffer, buf, transfer);
3831 STp->logical_blk_num += transfer / STp->block_size;
3832 STps->drv_block += transfer / STp->block_size;
3838 if ((STp->buffer)->buffer_bytes == 0) {
3841 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3842 name, STp->frame_seq_number);
3844 STp->frame_in_buffer = 0;
3845 STp->frame_seq_number++; /* frame to look for next time */
3847 } /* for (total = 0, special = 0; total < count && !special; ) */
3849 /* Change the eof state if no data from tape or buffer */
3851 if (STps->eof == ST_FM_HIT) {
3852 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3853 STps->drv_block = 0;
3854 if (STps->drv_file >= 0)
3857 else if (STps->eof == ST_EOD_1) {
3858 STps->eof = ST_EOD_2;
3859 if (STps->drv_block > 0 && STps->drv_file >= 0)
3861 STps->drv_block = 0;
3863 else if (STps->eof == ST_EOD_2)
3866 else if (STps->eof == ST_FM)
3867 STps->eof = ST_NOEOF;
3872 if (SRpnt != NULL) osst_release_request(SRpnt);
3874 mutex_unlock(&STp->lock);
3880 /* Set the driver options */
3881 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3884 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3885 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3886 STm->do_read_ahead);
3888 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3889 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3891 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3892 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3893 STp->scsi2_logical);
3895 "%s:I: sysv: %d\n", name, STm->sysv);
3898 "%s:D: debugging: %d\n",
3904 static int osst_set_options(struct osst_tape *STp, long options)
3908 struct st_modedef * STm;
3909 char * name = tape_name(STp);
3911 STm = &(STp->modes[STp->current_mode]);
3912 if (!STm->defined) {
3913 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3917 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3918 name, STp->current_mode);
3922 code = options & MT_ST_OPTIONS;
3923 if (code == MT_ST_BOOLEANS) {
3924 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3925 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3926 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3927 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3928 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3929 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3930 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3931 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3932 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3933 if ((STp->device)->scsi_level >= SCSI_2)
3934 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3935 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3936 STm->sysv = (options & MT_ST_SYSV) != 0;
3938 debugging = (options & MT_ST_DEBUGGING) != 0;
3940 osst_log_options(STp, STm, name);
3942 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3943 value = (code == MT_ST_SETBOOLEANS);
3944 if ((options & MT_ST_BUFFER_WRITES) != 0)
3945 STm->do_buffer_writes = value;
3946 if ((options & MT_ST_ASYNC_WRITES) != 0)
3947 STm->do_async_writes = value;
3948 if ((options & MT_ST_DEF_WRITES) != 0)
3949 STm->defaults_for_writes = value;
3950 if ((options & MT_ST_READ_AHEAD) != 0)
3951 STm->do_read_ahead = value;
3952 if ((options & MT_ST_TWO_FM) != 0)
3953 STp->two_fm = value;
3954 if ((options & MT_ST_FAST_MTEOM) != 0)
3955 STp->fast_mteom = value;
3956 if ((options & MT_ST_AUTO_LOCK) != 0)
3957 STp->do_auto_lock = value;
3958 if ((options & MT_ST_CAN_BSR) != 0)
3959 STp->can_bsr = value;
3960 if ((options & MT_ST_NO_BLKLIMS) != 0)
3961 STp->omit_blklims = value;
3962 if ((STp->device)->scsi_level >= SCSI_2 &&
3963 (options & MT_ST_CAN_PARTITIONS) != 0)
3964 STp->can_partitions = value;
3965 if ((options & MT_ST_SCSI2LOGICAL) != 0)
3966 STp->scsi2_logical = value;
3967 if ((options & MT_ST_SYSV) != 0)
3970 if ((options & MT_ST_DEBUGGING) != 0)
3973 osst_log_options(STp, STm, name);
3975 else if (code == MT_ST_WRITE_THRESHOLD) {
3976 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3977 if (value < 1 || value > osst_buffer_size) {
3978 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3982 STp->write_threshold = value;
3983 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3986 else if (code == MT_ST_DEF_BLKSIZE) {
3987 value = (options & ~MT_ST_OPTIONS);
3988 if (value == ~MT_ST_OPTIONS) {
3989 STm->default_blksize = (-1);
3990 printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3993 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3994 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3998 STm->default_blksize = value;
3999 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
4000 name, STm->default_blksize);
4003 else if (code == MT_ST_TIMEOUTS) {
4004 value = (options & ~MT_ST_OPTIONS);
4005 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
4006 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
4007 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
4008 (value & ~MT_ST_SET_LONG_TIMEOUT));
4011 STp->timeout = value * HZ;
4012 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
4015 else if (code == MT_ST_DEF_OPTIONS) {
4016 code = (options & ~MT_ST_CLEAR_DEFAULT);
4017 value = (options & MT_ST_CLEAR_DEFAULT);
4018 if (code == MT_ST_DEF_DENSITY) {
4019 if (value == MT_ST_CLEAR_DEFAULT) {
4020 STm->default_density = (-1);
4021 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
4024 STm->default_density = value & 0xff;
4025 printk(KERN_INFO "%s:I: Density default set to %x\n",
4026 name, STm->default_density);
4029 else if (code == MT_ST_DEF_DRVBUFFER) {
4030 if (value == MT_ST_CLEAR_DEFAULT) {
4031 STp->default_drvbuffer = 0xff;
4032 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
4035 STp->default_drvbuffer = value & 7;
4036 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
4037 name, STp->default_drvbuffer);
4040 else if (code == MT_ST_DEF_COMPRESSION) {
4041 if (value == MT_ST_CLEAR_DEFAULT) {
4042 STm->default_compression = ST_DONT_TOUCH;
4043 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
4046 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
4047 printk(KERN_INFO "%s:I: Compression default set to %x\n",
4059 /* Internal ioctl function */
4060 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt,
4061 unsigned int cmd_in, unsigned long arg)
4065 int i, ioctl_result;
4067 unsigned char cmd[MAX_COMMAND_SIZE];
4068 struct osst_request * SRpnt = * aSRpnt;
4069 struct st_partstat * STps;
4070 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
4071 int datalen = 0, direction = DMA_NONE;
4072 char * name = tape_name(STp);
4074 if (STp->ready != ST_READY && cmd_in != MTLOAD) {
4075 if (STp->ready == ST_NO_TAPE)
4076 return (-ENOMEDIUM);
4080 timeout = STp->long_timeout;
4081 STps = &(STp->ps[STp->partition]);
4082 fileno = STps->drv_file;
4083 blkno = STps->drv_block;
4084 at_sm = STps->at_sm;
4085 frame_seq_numbr = STp->frame_seq_number;
4086 logical_blk_num = STp->logical_blk_num;
4088 memset(cmd, 0, MAX_COMMAND_SIZE);
4091 chg_eof = 0; /* Changed from the FSF after this */
4096 if (STp->linux_media)
4097 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
4099 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
4103 at_sm &= (arg == 0);
4107 chg_eof = 0; /* Changed from the FSF after this */
4112 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
4115 blkno = (-1); /* We can't know the block number */
4116 at_sm &= (arg == 0);
4123 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
4124 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
4126 if (cmd_in == MTFSR) {
4127 logical_blk_num += arg;
4128 if (blkno >= 0) blkno += arg;
4131 logical_blk_num -= arg;
4132 if (blkno >= 0) blkno -= arg;
4134 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
4135 fileno = STps->drv_file;
4136 blkno = STps->drv_block;
4137 at_sm &= (arg == 0);
4142 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4143 cmd[2] = (arg >> 16);
4144 cmd[3] = (arg >> 8);
4148 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4149 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4152 blkno = fileno = (-1);
4158 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4160 cmd[2] = (ltmp >> 16);
4161 cmd[3] = (ltmp >> 8);
4167 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4168 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4173 blkno = fileno = (-1);
4178 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4179 STp->write_type = OS_WRITE_DATA;
4180 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4185 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4187 for (i=0; i<arg; i++)
4188 ioctl_result |= osst_write_filemark(STp, &SRpnt);
4189 if (fileno >= 0) fileno += arg;
4190 if (blkno >= 0) blkno = 0;
4194 if (STp->write_prot)
4198 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
4199 if (cmd_in == MTWSM)
4201 cmd[2] = (arg >> 16);
4202 cmd[3] = (arg >> 8);
4204 timeout = STp->timeout;
4207 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4208 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4213 at_sm = (cmd_in == MTWSM);
4219 cmd[0] = START_STOP;
4220 cmd[1] = 1; /* Don't wait for completion */
4221 if (cmd_in == MTLOAD) {
4222 if (STp->ready == ST_NO_TAPE)
4223 cmd[4] = 4; /* open tray */
4225 cmd[4] = 1; /* load */
4227 if (cmd_in == MTRETEN)
4228 cmd[4] = 3; /* retension then mount */
4229 if (cmd_in == MTOFFL)
4230 cmd[4] = 4; /* rewind then eject */
4231 timeout = STp->timeout;
4236 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4239 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4242 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4245 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4250 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4255 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4257 return 0; /* Should do something ? */
4262 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4264 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4265 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4266 ioctl_result = -EIO;
4269 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4271 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4273 ioctl_result = -EIO;
4276 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4277 fileno = STp->filemark_cnt;
4282 if (STp->write_prot)
4284 ioctl_result = osst_reset_header(STp, &SRpnt);
4285 i = osst_write_eod(STp, &SRpnt);
4286 if (i < ioctl_result) ioctl_result = i;
4287 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4288 if (i < ioctl_result) ioctl_result = i;
4289 fileno = blkno = at_sm = 0 ;
4293 cmd[0] = REZERO_UNIT; /* rewind */
4297 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4299 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4302 case MTSETBLK: /* Set block length */
4303 if ((STps->drv_block == 0 ) &&
4305 ((STp->buffer)->buffer_bytes == 0) &&
4306 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4307 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4308 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4310 * Only allowed to change the block size if you opened the
4311 * device at the beginning of a file before writing anything.
4312 * Note, that when reading, changing block_size is futile,
4313 * as the size used when writing overrides it.
4315 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4316 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4317 name, STp->block_size);
4321 case MTSETDENSITY: /* Set tape density */
4322 case MTSETDRVBUFFER: /* Set drive buffering */
4323 case SET_DENS_AND_BLK: /* Set density and block size */
4325 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4326 return (-EIO); /* Not allowed if data in buffer */
4327 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4328 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4329 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4330 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4331 name, (int)(arg & MT_ST_BLKSIZE_MASK),
4332 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4335 return 0; /* FIXME silently ignore if block size didn't change */
4341 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4343 ioctl_result = (STp->buffer)->syscall_result;
4347 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4349 return ioctl_result;
4352 if (!ioctl_result) { /* SCSI command successful */
4353 STp->frame_seq_number = frame_seq_numbr;
4354 STp->logical_blk_num = logical_blk_num;
4360 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4363 if (!ioctl_result) { /* success */
4365 if (cmd_in == MTFSFM) {
4369 if (cmd_in == MTBSFM) {
4373 STps->drv_block = blkno;
4374 STps->drv_file = fileno;
4375 STps->at_sm = at_sm;
4377 if (cmd_in == MTEOM)
4379 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4380 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4382 STp->logical_blk_num++;
4383 STp->frame_seq_number++;
4384 STp->frame_in_buffer = 0;
4385 STp->buffer->read_pointer = 0;
4387 else if (cmd_in == MTFSF)
4388 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4390 STps->eof = ST_NOEOF;
4392 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4393 STp->rew_at_close = 0;
4394 else if (cmd_in == MTLOAD) {
4395 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4396 STp->ps[i].rw = ST_IDLE;
4397 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4402 if (cmd_in == MTREW) {
4403 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4404 if (ioctl_result > 0)
4408 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4409 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4410 STps->drv_file = STps->drv_block = -1;
4412 STps->drv_file = STps->drv_block = 0;
4413 STps->eof = ST_NOEOF;
4414 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4415 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4416 STps->drv_file = STps->drv_block = -1;
4418 STps->drv_file = STp->filemark_cnt;
4419 STps->drv_block = 0;
4422 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4423 STps->drv_file = STps->drv_block = (-1);
4424 STps->eof = ST_NOEOF;
4426 } else if (cmd_in == MTERASE) {
4428 } else if (SRpnt) { /* SCSI command was not completely successful. */
4429 if (SRpnt->sense[2] & 0x40) {
4430 STps->eof = ST_EOM_OK;
4431 STps->drv_block = 0;
4434 STps->eof = ST_NOEOF;
4436 if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK)
4439 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4440 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4444 return ioctl_result;
4448 /* Open the device */
4449 static int __os_scsi_tape_open(struct inode * inode, struct file * filp)
4451 unsigned short flags;
4452 int i, b_size, new_session = 0, retval = 0;
4453 unsigned char cmd[MAX_COMMAND_SIZE];
4454 struct osst_request * SRpnt = NULL;
4455 struct osst_tape * STp;
4456 struct st_modedef * STm;
4457 struct st_partstat * STps;
4459 int dev = TAPE_NR(inode);
4460 int mode = TAPE_MODE(inode);
4463 * We really want to do nonseekable_open(inode, filp); here, but some
4464 * versions of tar incorrectly call lseek on tapes and bail out if that
4465 * fails. So we disallow pread() and pwrite(), but permit lseeks.
4467 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
4469 write_lock(&os_scsi_tapes_lock);
4470 if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4471 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4472 write_unlock(&os_scsi_tapes_lock);
4476 name = tape_name(STp);
4479 write_unlock(&os_scsi_tapes_lock);
4481 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4485 if (scsi_device_get(STp->device)) {
4486 write_unlock(&os_scsi_tapes_lock);
4488 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4492 filp->private_data = STp;
4494 write_unlock(&os_scsi_tapes_lock);
4495 STp->rew_at_close = TAPE_REWIND(inode);
4497 if( !scsi_block_when_processing_errors(STp->device) ) {
4501 if (mode != STp->current_mode) {
4504 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4505 name, STp->current_mode, mode);
4508 STp->current_mode = mode;
4510 STm = &(STp->modes[STp->current_mode]);
4512 flags = filp->f_flags;
4513 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4515 STp->raw = TAPE_IS_RAW(inode);
4519 /* Allocate data segments for this device's tape buffer */
4520 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4521 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4522 retval = (-EOVERFLOW);
4525 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4526 for (i = 0, b_size = 0;
4527 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4528 b_size += STp->buffer->sg[i++].length);
4529 STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
4531 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4532 STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4533 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4534 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4537 STp->buffer->aux = NULL; /* this had better never happen! */
4538 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4542 STp->buffer->writing = 0;
4543 STp->buffer->syscall_result = 0;
4545 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4546 STps = &(STp->ps[i]);
4549 STp->ready = ST_READY;
4551 STp->nbr_waits = STp->nbr_finished = 0;
4554 memset (cmd, 0, MAX_COMMAND_SIZE);
4555 cmd[0] = TEST_UNIT_READY;
4557 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4559 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
4562 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4563 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4564 SRpnt->sense[12] == 4 ) {
4566 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]);
4568 if (filp->f_flags & O_NONBLOCK) {
4572 if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */
4573 memset (cmd, 0, MAX_COMMAND_SIZE);
4574 cmd[0] = START_STOP;
4577 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4578 STp->timeout, MAX_RETRIES, 1);
4580 osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
4582 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4583 (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4585 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4589 for (i=0; i < 10; i++) {
4591 memset (cmd, 0, MAX_COMMAND_SIZE);
4592 cmd[0] = TEST_UNIT_READY;
4594 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4595 STp->timeout, MAX_RETRIES, 1);
4596 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4597 (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
4601 STp->pos_unknown = 0;
4602 STp->partition = STp->new_partition = 0;
4603 if (STp->can_partitions)
4604 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4605 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4606 STps = &(STp->ps[i]);
4607 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4608 STps->eof = ST_NOEOF;
4610 STps->last_block_valid = 0;
4611 STps->drv_block = 0;
4612 STps->drv_file = 0 ;
4615 STp->recover_count = 0;
4616 STp->abort_count = 0;
4619 * if we have valid headers from before, and the drive/tape seem untouched,
4620 * open without reconfiguring and re-reading the headers
4622 if (!STp->buffer->syscall_result && STp->header_ok &&
4623 !SRpnt->result && SRpnt->sense[0] == 0) {
4625 memset(cmd, 0, MAX_COMMAND_SIZE);
4626 cmd[0] = MODE_SENSE;
4628 cmd[2] = VENDOR_IDENT_PAGE;
4629 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4631 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4633 if (STp->buffer->syscall_result ||
4634 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4635 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4636 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4637 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4639 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4640 STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4641 STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4642 STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4643 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4647 i = STp->first_frame_position;
4648 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4649 if (STp->door_locked == ST_UNLOCKED) {
4650 if (do_door_lock(STp, 1))
4651 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4653 STp->door_locked = ST_LOCKED_AUTO;
4655 if (!STp->frame_in_buffer) {
4656 STp->block_size = (STm->default_blksize > 0) ?
4657 STm->default_blksize : OS_DATA_SIZE;
4658 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4660 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4662 osst_release_request(SRpnt);
4666 if (i != STp->first_frame_position)
4667 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4668 name, i, STp->first_frame_position);
4674 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4675 (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) {
4677 memset(cmd, 0, MAX_COMMAND_SIZE);
4678 cmd[0] = MODE_SELECT;
4680 cmd[4] = 4 + MODE_HEADER_LENGTH;
4682 (STp->buffer)->b_data[0] = cmd[4] - 1;
4683 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4684 (STp->buffer)->b_data[2] = 0; /* Reserved */
4685 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4686 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4687 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4688 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4689 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4692 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4694 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4698 for (i=0; i < 10; i++) {
4700 memset (cmd, 0, MAX_COMMAND_SIZE);
4701 cmd[0] = TEST_UNIT_READY;
4703 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4704 STp->timeout, MAX_RETRIES, 1);
4705 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4706 (SRpnt->sense[2] & 0x0f) == NOT_READY)
4709 if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
4712 STp->pos_unknown = 0;
4713 STp->partition = STp->new_partition = 0;
4714 if (STp->can_partitions)
4715 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4716 for (j = 0; j < ST_NBR_PARTITIONS; j++) {
4717 STps = &(STp->ps[j]);
4719 STps->eof = ST_NOEOF;
4721 STps->last_block_valid = 0;
4722 STps->drv_block = 0;
4723 STps->drv_file = 0 ;
4730 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4731 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4733 if ((STp->buffer)->syscall_result != 0) {
4734 if ((STp->device)->scsi_level >= SCSI_2 &&
4735 (SRpnt->sense[0] & 0x70) == 0x70 &&
4736 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4737 SRpnt->sense[12] == 0x3a) { /* Check ASC */
4738 STp->ready = ST_NO_TAPE;
4740 STp->ready = ST_NOT_READY;
4741 osst_release_request(SRpnt);
4743 STp->density = 0; /* Clear the erroneous "residue" */
4744 STp->write_prot = 0;
4745 STp->block_size = 0;
4746 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4747 STp->partition = STp->new_partition = 0;
4748 STp->door_locked = ST_UNLOCKED;
4752 osst_configure_onstream(STp, &SRpnt);
4754 STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4755 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4756 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4757 STp->buffer->buffer_bytes =
4758 STp->buffer->read_pointer =
4759 STp->frame_in_buffer = 0;
4763 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4764 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4765 (STp->buffer)->buffer_blocks);
4768 if (STp->drv_write_prot) {
4769 STp->write_prot = 1;
4772 printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4774 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4780 if (new_session) { /* Change the drive parameters for the new mode */
4783 printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4785 STp->density_changed = STp->blksize_changed = 0;
4786 STp->compression_changed = 0;
4790 * properly position the tape and check the ADR headers
4792 if (STp->door_locked == ST_UNLOCKED) {
4793 if (do_door_lock(STp, 1))
4794 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4796 STp->door_locked = ST_LOCKED_AUTO;
4799 osst_analyze_headers(STp, &SRpnt);
4801 osst_release_request(SRpnt);
4808 osst_release_request(SRpnt);
4809 normalize_buffer(STp->buffer);
4812 scsi_device_put(STp->device);
4817 /* BKL pushdown: spaghetti avoidance wrapper */
4818 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4822 mutex_lock(&osst_int_mutex);
4823 ret = __os_scsi_tape_open(inode, filp);
4824 mutex_unlock(&osst_int_mutex);
4830 /* Flush the tape buffer before close */
4831 static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
4833 int result = 0, result2;
4834 struct osst_tape * STp = filp->private_data;
4835 struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4836 struct st_partstat * STps = &(STp->ps[STp->partition]);
4837 struct osst_request * SRpnt = NULL;
4838 char * name = tape_name(STp);
4840 if (file_count(filp) > 1)
4843 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4844 STp->write_type = OS_WRITE_DATA;
4845 result = osst_flush_write_buffer(STp, &SRpnt);
4846 if (result != 0 && result != (-ENOSPC))
4849 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4853 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4854 name, (long)(filp->f_pos));
4855 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4856 name, STp->nbr_waits, STp->nbr_finished);
4859 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4862 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4863 name, 1+STp->two_fm);
4866 else if (!STp->rew_at_close) {
4867 STps = &(STp->ps[STp->partition]);
4868 if (!STm->sysv || STps->rw != ST_READING) {
4870 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4871 else if (STps->eof == ST_FM_HIT) {
4872 result = cross_eof(STp, &SRpnt, 0);
4874 if (STps->drv_file >= 0)
4876 STps->drv_block = 0;
4880 STps->eof = ST_NOEOF;
4883 else if ((STps->eof == ST_NOEOF &&
4884 !(result = cross_eof(STp, &SRpnt, 1))) ||
4885 STps->eof == ST_FM_HIT) {
4886 if (STps->drv_file >= 0)
4888 STps->drv_block = 0;
4894 if (STp->rew_at_close) {
4895 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4896 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4897 if (result == 0 && result2 < 0)
4900 if (SRpnt) osst_release_request(SRpnt);
4902 if (STp->abort_count || STp->recover_count) {
4903 printk(KERN_INFO "%s:I:", name);
4904 if (STp->abort_count)
4905 printk(" %d unrecovered errors", STp->abort_count);
4906 if (STp->recover_count)
4907 printk(" %d recovered errors", STp->recover_count);
4908 if (STp->write_count)
4909 printk(" in %d frames written", STp->write_count);
4910 if (STp->read_count)
4911 printk(" in %d frames read", STp->read_count);
4913 STp->recover_count = 0;
4914 STp->abort_count = 0;
4916 STp->write_count = 0;
4917 STp->read_count = 0;
4923 /* Close the device and release it */
4924 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4927 struct osst_tape * STp = filp->private_data;
4929 if (STp->door_locked == ST_LOCKED_AUTO)
4930 do_door_lock(STp, 0);
4935 normalize_buffer(STp->buffer);
4936 write_lock(&os_scsi_tapes_lock);
4938 write_unlock(&os_scsi_tapes_lock);
4940 scsi_device_put(STp->device);
4946 /* The ioctl command */
4947 static long osst_ioctl(struct file * file,
4948 unsigned int cmd_in, unsigned long arg)
4950 int i, cmd_nr, cmd_type, blk, retval = 0;
4951 struct st_modedef * STm;
4952 struct st_partstat * STps;
4953 struct osst_request * SRpnt = NULL;
4954 struct osst_tape * STp = file->private_data;
4955 char * name = tape_name(STp);
4956 void __user * p = (void __user *)arg;
4958 mutex_lock(&osst_int_mutex);
4959 if (mutex_lock_interruptible(&STp->lock)) {
4960 mutex_unlock(&osst_int_mutex);
4961 return -ERESTARTSYS;
4965 if (debugging && !STp->in_use) {
4966 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4971 STm = &(STp->modes[STp->current_mode]);
4972 STps = &(STp->ps[STp->partition]);
4975 * If we are in the middle of error recovery, don't let anyone
4976 * else try and use this device. Also, if error recovery fails, it
4977 * may try and take the device offline, in which case all further
4978 * access to the device is prohibited.
4980 retval = scsi_ioctl_block_when_processing_errors(STp->device, cmd_in,
4981 file->f_flags & O_NDELAY);
4985 cmd_type = _IOC_TYPE(cmd_in);
4986 cmd_nr = _IOC_NR(cmd_in);
4988 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4989 cmd_type, cmd_nr, STp->raw?"raw":"normal");
4991 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4995 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
5000 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
5006 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
5007 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
5012 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
5017 if (!STp->pos_unknown) {
5019 if (STps->eof == ST_FM_HIT) {
5020 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
5022 if (STps->drv_file >= 0)
5023 STps->drv_file += 1;
5025 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
5027 if (STps->drv_file >= 0)
5028 STps->drv_file += 1;
5032 if (mtc.mt_op == MTSEEK) {
5033 /* Old position must be restored if partition will be changed */
5034 i = !STp->can_partitions || (STp->new_partition != STp->partition);
5037 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
5038 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
5039 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
5040 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
5041 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
5042 mtc.mt_op == MTCOMPRESSION;
5044 i = osst_flush_buffer(STp, &SRpnt, i);
5052 * If there was a bus reset, block further access
5053 * to this device. If the user wants to rewind the tape,
5054 * then reset the flag and allow access again.
5056 if(mtc.mt_op != MTREW &&
5057 mtc.mt_op != MTOFFL &&
5058 mtc.mt_op != MTRETEN &&
5059 mtc.mt_op != MTERASE &&
5060 mtc.mt_op != MTSEEK &&
5061 mtc.mt_op != MTEOM) {
5066 /* remove this when the midlevel properly clears was_reset */
5067 STp->device->was_reset = 0;
5070 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK &&
5071 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
5072 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER &&
5073 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART &&
5074 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) {
5077 * The user tells us to move to another position on the tape.
5078 * If we were appending to the tape content, that would leave
5079 * the tape without proper end, in that case write EOD and
5080 * update the header to reflect its position.
5083 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
5084 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
5085 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
5086 STp->logical_blk_num, STps->drv_file, STps->drv_block );
5088 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
5089 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
5090 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
5091 i = osst_write_trailer(STp, &SRpnt,
5092 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
5094 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
5095 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
5096 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
5106 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
5107 do_door_lock(STp, 0); /* Ignore result! */
5109 if (mtc.mt_op == MTSETDRVBUFFER &&
5110 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
5111 retval = osst_set_options(STp, mtc.mt_count);
5115 if (mtc.mt_op == MTSETPART) {
5116 if (mtc.mt_count >= STp->nbr_partitions)
5119 STp->new_partition = mtc.mt_count;
5125 if (mtc.mt_op == MTMKPART) {
5126 if (!STp->can_partitions) {
5130 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
5131 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
5135 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5136 STp->ps[i].rw = ST_IDLE;
5137 STp->ps[i].at_sm = 0;
5138 STp->ps[i].last_block_valid = 0;
5140 STp->partition = STp->new_partition = 0;
5141 STp->nbr_partitions = 1; /* Bad guess ?-) */
5142 STps->drv_block = STps->drv_file = 0;
5147 if (mtc.mt_op == MTSEEK) {
5149 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
5151 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
5152 if (!STp->can_partitions)
5153 STp->ps[0].rw = ST_IDLE;
5158 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
5159 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
5164 cross_eof(STp, &SRpnt, 0);
5166 if (mtc.mt_op == MTCOMPRESSION)
5167 retval = -EINVAL; /* OnStream drives don't have compression hardware */
5169 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5170 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5171 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5175 if (!STm->defined) {
5180 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5185 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
5186 struct mtget mt_status;
5188 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
5193 mt_status.mt_type = MT_ISONSTREAM_SC;
5194 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
5195 mt_status.mt_dsreg =
5196 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
5197 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
5198 mt_status.mt_blkno = STps->drv_block;
5199 mt_status.mt_fileno = STps->drv_file;
5200 if (STp->block_size != 0) {
5201 if (STps->rw == ST_WRITING)
5202 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
5203 else if (STps->rw == ST_READING)
5204 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
5205 STp->block_size - 1) / STp->block_size;
5208 mt_status.mt_gstat = 0;
5209 if (STp->drv_write_prot)
5210 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
5211 if (mt_status.mt_blkno == 0) {
5212 if (mt_status.mt_fileno == 0)
5213 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
5215 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
5217 mt_status.mt_resid = STp->partition;
5218 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
5219 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
5220 else if (STps->eof >= ST_EOM_OK)
5221 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
5222 if (STp->density == 1)
5223 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
5224 else if (STp->density == 2)
5225 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
5226 else if (STp->density == 3)
5227 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
5228 if (STp->ready == ST_READY)
5229 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
5230 if (STp->ready == ST_NO_TAPE)
5231 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
5233 mt_status.mt_gstat |= GMT_SM(0xffffffff);
5234 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
5235 STp->drv_buffer != 0)
5236 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
5238 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
5244 STp->recover_erreg = 0; /* Clear after read */
5247 } /* End of MTIOCGET */
5249 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5250 struct mtpos mt_pos;
5252 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5257 blk = osst_get_frame_position(STp, &SRpnt);
5259 blk = osst_get_sector(STp, &SRpnt);
5264 mt_pos.mt_blkno = blk;
5265 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5270 if (SRpnt) osst_release_request(SRpnt);
5272 mutex_unlock(&STp->lock);
5274 retval = scsi_ioctl(STp->device, cmd_in, p);
5275 mutex_unlock(&osst_int_mutex);
5279 if (SRpnt) osst_release_request(SRpnt);
5281 mutex_unlock(&STp->lock);
5282 mutex_unlock(&osst_int_mutex);
5287 #ifdef CONFIG_COMPAT
5288 static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg)
5290 struct osst_tape *STp = file->private_data;
5291 struct scsi_device *sdev = STp->device;
5292 int ret = -ENOIOCTLCMD;
5293 if (sdev->host->hostt->compat_ioctl) {
5295 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
5304 /* Memory handling routines */
5306 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5307 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5311 struct osst_buffer *tb;
5313 if (from_initialization)
5314 priority = GFP_ATOMIC;
5316 priority = GFP_KERNEL;
5318 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5319 tb = kzalloc(i, priority);
5321 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5325 tb->sg_segs = tb->orig_sg_segs = 0;
5326 tb->use_sg = max_sg;
5329 tb->buffer_size = 0;
5333 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5334 i, max_sg, need_dma);
5339 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5340 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5342 int segs, nbr, max_segs, b_size, order, got;
5345 if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5348 if (STbuffer->sg_segs) {
5349 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5350 normalize_buffer(STbuffer);
5352 /* See how many segments we can use -- need at least two */
5353 nbr = max_segs = STbuffer->use_sg;
5357 priority = GFP_KERNEL /* | __GFP_NOWARN */;
5359 priority |= GFP_DMA;
5361 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5362 big enough to reach the goal (code assumes no segments in place) */
5363 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5364 struct page *page = alloc_pages(priority, order);
5366 STbuffer->sg[0].offset = 0;
5368 sg_set_page(&STbuffer->sg[0], page, b_size, 0);
5369 STbuffer->b_data = page_address(page);
5373 if (sg_page(&STbuffer->sg[0]) == NULL) {
5374 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5377 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5378 for (segs=STbuffer->sg_segs=1, got=b_size;
5379 segs < max_segs && got < OS_FRAME_SIZE; ) {
5380 struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5381 STbuffer->sg[segs].offset = 0;
5383 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5386 STbuffer->buffer_size = got;
5388 normalize_buffer(STbuffer);
5391 sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0);
5392 got += STbuffer->sg[segs].length;
5393 STbuffer->buffer_size = got;
5394 STbuffer->sg_segs = ++segs;
5399 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5400 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5402 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5403 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5404 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5412 /* Release the segments */
5413 static void normalize_buffer(struct osst_buffer *STbuffer)
5415 int i, order, b_size;
5417 for (i=0; i < STbuffer->sg_segs; i++) {
5419 for (b_size = PAGE_SIZE, order = 0;
5420 b_size < STbuffer->sg[i].length;
5421 b_size *= 2, order++);
5423 __free_pages(sg_page(&STbuffer->sg[i]), order);
5424 STbuffer->buffer_size -= STbuffer->sg[i].length;
5427 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5428 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5429 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5431 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5435 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5436 negative error code. */
5437 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
5439 int i, cnt, res, offset;
5441 for (i=0, offset=st_bp->buffer_bytes;
5442 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5443 offset -= st_bp->sg[i].length;
5444 if (i == st_bp->sg_segs) { /* Should never happen */
5445 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5448 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5449 cnt = st_bp->sg[i].length - offset < do_count ?
5450 st_bp->sg[i].length - offset : do_count;
5451 res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
5455 st_bp->buffer_bytes += cnt;
5459 if (do_count) { /* Should never happen */
5460 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5468 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5469 negative error code. */
5470 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
5472 int i, cnt, res, offset;
5474 for (i=0, offset=st_bp->read_pointer;
5475 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5476 offset -= st_bp->sg[i].length;
5477 if (i == st_bp->sg_segs) { /* Should never happen */
5478 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5481 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5482 cnt = st_bp->sg[i].length - offset < do_count ?
5483 st_bp->sg[i].length - offset : do_count;
5484 res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
5488 st_bp->buffer_bytes -= cnt;
5489 st_bp->read_pointer += cnt;
5493 if (do_count) { /* Should never happen */
5494 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5500 /* Sets the tail of the buffer after fill point to zero.
5501 Returns zero (success) or negative error code. */
5502 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
5504 int i, offset, do_count, cnt;
5506 for (i = 0, offset = st_bp->buffer_bytes;
5507 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5508 offset -= st_bp->sg[i].length;
5509 if (i == st_bp->sg_segs) { /* Should never happen */
5510 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5513 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5514 i < st_bp->sg_segs && do_count > 0; i++) {
5515 cnt = st_bp->sg[i].length - offset < do_count ?
5516 st_bp->sg[i].length - offset : do_count ;
5517 memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
5521 if (do_count) { /* Should never happen */
5522 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5528 /* Copy a osst 32K chunk of memory into the buffer.
5529 Returns zero (success) or negative error code. */
5530 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5532 int i, cnt, do_count = OS_DATA_SIZE;
5534 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5535 cnt = st_bp->sg[i].length < do_count ?
5536 st_bp->sg[i].length : do_count ;
5537 memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
5541 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5542 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5549 /* Copy a osst 32K chunk of memory from the buffer.
5550 Returns zero (success) or negative error code. */
5551 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5553 int i, cnt, do_count = OS_DATA_SIZE;
5555 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5556 cnt = st_bp->sg[i].length < do_count ?
5557 st_bp->sg[i].length : do_count ;
5558 memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
5562 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5563 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5571 /* Module housekeeping */
5573 static void validate_options (void)
5576 osst_max_dev = max_dev;
5577 if (write_threshold_kbs > 0)
5578 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5579 if (osst_write_threshold > osst_buffer_size)
5580 osst_write_threshold = osst_buffer_size;
5581 if (max_sg_segs >= OSST_FIRST_SG)
5582 osst_max_sg_segs = max_sg_segs;
5584 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5585 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5590 /* Set the boot options. Syntax: osst=xxx,yyy,...
5591 where xxx is write threshold in 1024 byte blocks,
5592 and yyy is number of s/g segments to use. */
5593 static int __init osst_setup (char *str)
5598 stp = get_options(str, ARRAY_SIZE(ints), ints);
5601 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5602 *parms[i].val = ints[i + 1];
5604 while (stp != NULL) {
5605 for (i = 0; i < ARRAY_SIZE(parms); i++) {
5606 int len = strlen(parms[i].name);
5607 if (!strncmp(stp, parms[i].name, len) &&
5608 (*(stp + len) == ':' || *(stp + len) == '=')) {
5610 simple_strtoul(stp + len + 1, NULL, 0);
5614 if (i >= ARRAY_SIZE(parms))
5615 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5617 stp = strchr(stp, ',');
5626 __setup("osst=", osst_setup);
5630 static const struct file_operations osst_fops = {
5631 .owner = THIS_MODULE,
5633 .write = osst_write,
5634 .unlocked_ioctl = osst_ioctl,
5635 #ifdef CONFIG_COMPAT
5636 .compat_ioctl = osst_compat_ioctl,
5638 .open = os_scsi_tape_open,
5639 .flush = os_scsi_tape_flush,
5640 .release = os_scsi_tape_close,
5641 .llseek = noop_llseek,
5644 static int osst_supports(struct scsi_device * SDp)
5646 struct osst_support_data {
5650 char *driver_hint; /* Name of the correct driver, NULL if unknown */
5653 static struct osst_support_data support_list[] = {
5654 /* {"XXX", "Yy-", "", NULL}, example */
5658 struct osst_support_data *rp;
5660 /* We are willing to drive OnStream SC-x0 as well as the
5661 * * IDE, ParPort, FireWire, USB variants, if accessible by
5662 * * emulation layer (ide-scsi, usb-storage, ...) */
5664 for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5665 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5666 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5667 !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5673 * sysfs support for osst driver parameter information
5676 static ssize_t version_show(struct device_driver *ddd, char *buf)
5678 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
5681 static DRIVER_ATTR_RO(version);
5683 static int osst_create_sysfs_files(struct device_driver *sysfs)
5685 return driver_create_file(sysfs, &driver_attr_version);
5688 static void osst_remove_sysfs_files(struct device_driver *sysfs)
5690 driver_remove_file(sysfs, &driver_attr_version);
5694 * sysfs support for accessing ADR header information
5697 static ssize_t osst_adr_rev_show(struct device *dev,
5698 struct device_attribute *attr, char *buf)
5700 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5703 if (STp && STp->header_ok && STp->linux_media)
5704 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
5708 DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
5710 static ssize_t osst_linux_media_version_show(struct device *dev,
5711 struct device_attribute *attr,
5714 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5717 if (STp && STp->header_ok && STp->linux_media)
5718 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
5722 DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
5724 static ssize_t osst_capacity_show(struct device *dev,
5725 struct device_attribute *attr, char *buf)
5727 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5730 if (STp && STp->header_ok && STp->linux_media)
5731 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
5735 DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
5737 static ssize_t osst_first_data_ppos_show(struct device *dev,
5738 struct device_attribute *attr,
5741 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5744 if (STp && STp->header_ok && STp->linux_media)
5745 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
5749 DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
5751 static ssize_t osst_eod_frame_ppos_show(struct device *dev,
5752 struct device_attribute *attr,
5755 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5758 if (STp && STp->header_ok && STp->linux_media)
5759 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
5763 DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
5765 static ssize_t osst_filemark_cnt_show(struct device *dev,
5766 struct device_attribute *attr, char *buf)
5768 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5771 if (STp && STp->header_ok && STp->linux_media)
5772 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
5776 DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5778 static struct class *osst_sysfs_class;
5780 static int osst_sysfs_init(void)
5782 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
5783 if (IS_ERR(osst_sysfs_class)) {
5784 printk(KERN_ERR "osst :W: Unable to register sysfs class\n");
5785 return PTR_ERR(osst_sysfs_class);
5791 static void osst_sysfs_destroy(dev_t dev)
5793 device_destroy(osst_sysfs_class, dev);
5796 static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5798 struct device *osst_member;
5801 osst_member = device_create(osst_sysfs_class, device, dev, STp,
5803 if (IS_ERR(osst_member)) {
5804 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5805 return PTR_ERR(osst_member);
5808 err = device_create_file(osst_member, &dev_attr_ADR_rev);
5811 err = device_create_file(osst_member, &dev_attr_media_version);
5814 err = device_create_file(osst_member, &dev_attr_capacity);
5817 err = device_create_file(osst_member, &dev_attr_BOT_frame);
5820 err = device_create_file(osst_member, &dev_attr_EOD_frame);
5823 err = device_create_file(osst_member, &dev_attr_file_count);
5830 osst_sysfs_destroy(dev);
5834 static void osst_sysfs_cleanup(void)
5836 class_destroy(osst_sysfs_class);
5840 * osst startup / cleanup code
5843 static int osst_probe(struct device *dev)
5845 struct scsi_device * SDp = to_scsi_device(dev);
5846 struct osst_tape * tpnt;
5847 struct st_modedef * STm;
5848 struct st_partstat * STps;
5849 struct osst_buffer * buffer;
5850 struct gendisk * drive;
5851 int i, dev_num, err = -ENODEV;
5853 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5856 drive = alloc_disk(1);
5858 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5862 /* if this is the first attach, build the infrastructure */
5863 write_lock(&os_scsi_tapes_lock);
5864 if (os_scsi_tapes == NULL) {
5865 os_scsi_tapes = kmalloc_array(osst_max_dev,
5866 sizeof(struct osst_tape *),
5868 if (os_scsi_tapes == NULL) {
5869 write_unlock(&os_scsi_tapes_lock);
5870 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5873 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5876 if (osst_nr_dev >= osst_max_dev) {
5877 write_unlock(&os_scsi_tapes_lock);
5878 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5882 /* find a free minor number */
5883 for (i = 0; i < osst_max_dev && os_scsi_tapes[i]; i++)
5885 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5888 /* allocate a struct osst_tape for this device */
5889 tpnt = kzalloc(sizeof(struct osst_tape), GFP_ATOMIC);
5891 write_unlock(&os_scsi_tapes_lock);
5892 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5896 /* allocate a buffer for this device */
5897 i = SDp->host->sg_tablesize;
5898 if (osst_max_sg_segs < i)
5899 i = osst_max_sg_segs;
5900 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
5901 if (buffer == NULL) {
5902 write_unlock(&os_scsi_tapes_lock);
5903 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5907 os_scsi_tapes[dev_num] = tpnt;
5908 tpnt->buffer = buffer;
5910 drive->private_data = &tpnt->driver;
5911 sprintf(drive->disk_name, "osst%d", dev_num);
5912 tpnt->driver = &osst_template;
5913 tpnt->drive = drive;
5915 tpnt->capacity = 0xfffff;
5917 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
5918 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5920 tpnt->do_auto_lock = OSST_AUTO_LOCK;
5921 tpnt->can_bsr = OSST_IN_FILE_POS;
5922 tpnt->can_partitions = 0;
5923 tpnt->two_fm = OSST_TWO_FM;
5924 tpnt->fast_mteom = OSST_FAST_MTEOM;
5925 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5926 tpnt->write_threshold = osst_write_threshold;
5927 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5928 tpnt->partition = 0;
5929 tpnt->new_partition = 0;
5930 tpnt->nbr_partitions = 0;
5931 tpnt->min_block = 512;
5932 tpnt->max_block = OS_DATA_SIZE;
5933 tpnt->timeout = OSST_TIMEOUT;
5934 tpnt->long_timeout = OSST_LONG_TIMEOUT;
5936 /* Recognize OnStream tapes */
5937 /* We don't need to test for OnStream, as this has been done in detect () */
5938 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5939 tpnt->omit_blklims = 1;
5941 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5942 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5943 tpnt->frame_in_buffer = 0;
5944 tpnt->header_ok = 0;
5945 tpnt->linux_media = 0;
5946 tpnt->header_cache = NULL;
5948 for (i=0; i < ST_NBR_MODES; i++) {
5949 STm = &(tpnt->modes[i]);
5951 STm->sysv = OSST_SYSV;
5952 STm->defaults_for_writes = 0;
5953 STm->do_async_writes = OSST_ASYNC_WRITES;
5954 STm->do_buffer_writes = OSST_BUFFER_WRITES;
5955 STm->do_read_ahead = OSST_READ_AHEAD;
5956 STm->default_compression = ST_DONT_TOUCH;
5957 STm->default_blksize = 512;
5958 STm->default_density = (-1); /* No forced density */
5961 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5962 STps = &(tpnt->ps[i]);
5964 STps->eof = ST_NOEOF;
5966 STps->last_block_valid = 0;
5967 STps->drv_block = (-1);
5968 STps->drv_file = (-1);
5971 tpnt->current_mode = 0;
5972 tpnt->modes[0].defined = 1;
5973 tpnt->modes[2].defined = 1;
5974 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
5976 mutex_init(&tpnt->lock);
5978 write_unlock(&os_scsi_tapes_lock);
5984 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5986 goto out_free_buffer;
5988 /* No-rewind entry */
5989 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5990 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5992 goto out_free_sysfs1;
5995 sdev_printk(KERN_INFO, SDp,
5996 "osst :I: Attached OnStream %.5s tape as %s\n",
5997 SDp->model, tape_name(tpnt));
6002 osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num));
6010 static int osst_remove(struct device *dev)
6012 struct scsi_device * SDp = to_scsi_device(dev);
6013 struct osst_tape * tpnt;
6016 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
6019 write_lock(&os_scsi_tapes_lock);
6020 for(i=0; i < osst_max_dev; i++) {
6021 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
6022 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
6023 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
6024 tpnt->device = NULL;
6025 put_disk(tpnt->drive);
6026 os_scsi_tapes[i] = NULL;
6028 write_unlock(&os_scsi_tapes_lock);
6029 vfree(tpnt->header_cache);
6031 normalize_buffer(tpnt->buffer);
6032 kfree(tpnt->buffer);
6038 write_unlock(&os_scsi_tapes_lock);
6042 static int __init init_osst(void)
6046 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
6050 err = osst_sysfs_init();
6054 err = register_chrdev(OSST_MAJOR, "osst", &osst_fops);
6056 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
6060 err = scsi_register_driver(&osst_template.gendrv);
6062 goto err_out_chrdev;
6064 err = osst_create_sysfs_files(&osst_template.gendrv);
6066 goto err_out_scsidrv;
6071 scsi_unregister_driver(&osst_template.gendrv);
6073 unregister_chrdev(OSST_MAJOR, "osst");
6075 osst_sysfs_cleanup();
6079 static void __exit exit_osst (void)
6082 struct osst_tape * STp;
6084 osst_remove_sysfs_files(&osst_template.gendrv);
6085 scsi_unregister_driver(&osst_template.gendrv);
6086 unregister_chrdev(OSST_MAJOR, "osst");
6087 osst_sysfs_cleanup();
6089 if (os_scsi_tapes) {
6090 for (i=0; i < osst_max_dev; ++i) {
6091 if (!(STp = os_scsi_tapes[i])) continue;
6092 /* This is defensive, supposed to happen during detach */
6093 vfree(STp->header_cache);
6095 normalize_buffer(STp->buffer);
6098 put_disk(STp->drive);
6101 kfree(os_scsi_tapes);
6103 printk(KERN_INFO "osst :I: Unloaded.\n");
6106 module_init(init_osst);
6107 module_exit(exit_osst);