1 // SPDX-License-Identifier: GPL-2.0-only
3 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
4 file Documentation/scsi/st.txt for more information.
8 OnStream SCSI Tape support (osst) cloned from st.c by
12 Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
13 Contribution and ideas from several people including (in alphabetical
14 order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
15 Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
17 Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede
20 $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
22 Microscopic alterations - Rik Ling, 2000/12/21
23 Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
24 Some small formal changes - aeb, 950809
27 static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $";
28 static const char * osst_version = "0.99.4";
30 /* The "failure to reconnect" firmware bug */
31 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
32 #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/
33 #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
35 #include <linux/module.h>
38 #include <linux/kernel.h>
39 #include <linux/sched/signal.h>
40 #include <linux/proc_fs.h>
42 #include <linux/slab.h>
43 #include <linux/init.h>
44 #include <linux/string.h>
45 #include <linux/errno.h>
46 #include <linux/mtio.h>
47 #include <linux/ioctl.h>
48 #include <linux/fcntl.h>
49 #include <linux/spinlock.h>
50 #include <linux/vmalloc.h>
51 #include <linux/blkdev.h>
52 #include <linux/moduleparam.h>
53 #include <linux/delay.h>
54 #include <linux/jiffies.h>
55 #include <linux/mutex.h>
56 #include <linux/uaccess.h>
59 /* The driver prints some debugging information on the console if DEBUG
60 is defined and non-zero. */
63 /* The message level for the debug messages is currently set to KERN_NOTICE
64 so that people can easily see the messages. Later when the debugging messages
65 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
66 #define OSST_DEB_MSG KERN_NOTICE
68 #include <scsi/scsi.h>
69 #include <scsi/scsi_dbg.h>
70 #include <scsi/scsi_device.h>
71 #include <scsi/scsi_driver.h>
72 #include <scsi/scsi_eh.h>
73 #include <scsi/scsi_host.h>
74 #include <scsi/scsi_ioctl.h>
76 #define ST_KILOBYTE 1024
80 #include "osst_options.h"
81 #include "osst_detect.h"
83 static DEFINE_MUTEX(osst_int_mutex);
84 static int max_dev = 0;
85 static int write_threshold_kbs = 0;
86 static int max_sg_segs = 0;
89 MODULE_AUTHOR("Willem Riede");
90 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
91 MODULE_LICENSE("GPL");
92 MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR);
93 MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
95 module_param(max_dev, int, 0444);
96 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
98 module_param(write_threshold_kbs, int, 0644);
99 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
101 module_param(max_sg_segs, int, 0644);
102 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
104 static struct osst_dev_parm {
107 } parms[] __initdata = {
108 { "max_dev", &max_dev },
109 { "write_threshold_kbs", &write_threshold_kbs },
110 { "max_sg_segs", &max_sg_segs }
114 /* Some default definitions have been moved to osst_options.h */
115 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
116 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
118 /* The buffer size should fit into the 24 bits for length in the
119 6-byte SCSI read and write commands. */
120 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
121 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
125 static int debugging = 1;
126 /* uncomment define below to test error recovery */
127 // #define OSST_INJECT_ERRORS 1
130 /* Do not retry! The drive firmware already retries when appropriate,
131 and when it tries to tell us something, we had better listen... */
132 #define MAX_RETRIES 0
134 #define NO_TAPE NOT_READY
136 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
137 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
138 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
140 #define OSST_TIMEOUT (200 * HZ)
141 #define OSST_LONG_TIMEOUT (1800 * HZ)
143 #define TAPE_NR(x) (iminor(x) & ((1 << ST_MODE_SHIFT)-1))
144 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
145 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
146 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
148 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
150 #define SET_DENS_AND_BLK 0x10001
152 static int osst_buffer_size = OSST_BUFFER_SIZE;
153 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
154 static int osst_max_sg_segs = OSST_MAX_SG;
155 static int osst_max_dev = OSST_MAX_TAPES;
156 static int osst_nr_dev;
158 static struct osst_tape **os_scsi_tapes = NULL;
159 static DEFINE_RWLOCK(os_scsi_tapes_lock);
161 static int modes_defined = 0;
163 static struct osst_buffer *new_tape_buffer(int, int, int);
164 static int enlarge_buffer(struct osst_buffer *, int);
165 static void normalize_buffer(struct osst_buffer *);
166 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
167 static int from_buffer(struct osst_buffer *, char __user *, int);
168 static int osst_zero_buffer_tail(struct osst_buffer *);
169 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
170 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
172 static int osst_probe(struct device *);
173 static int osst_remove(struct device *);
175 static struct scsi_driver osst_template = {
178 .owner = THIS_MODULE,
180 .remove = osst_remove,
184 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt,
185 unsigned int cmd_in, unsigned long arg);
187 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip);
189 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt);
191 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt);
193 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending);
195 static inline char *tape_name(struct osst_tape *tape)
197 return tape->drive->disk_name;
200 /* Routines that handle the interaction with mid-layer SCSI routines */
203 /* Normalize Sense */
204 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s)
207 const u8 *sense = SRpnt->sense;
209 s->have_sense = scsi_normalize_sense(SRpnt->sense,
210 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
216 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
217 switch (sense[0] & 0x7f) {
223 s->flags = sense[2] & 0xe0;
230 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
231 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
237 /* Convert the result to success code */
238 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
240 char *name = tape_name(STp);
241 int result = SRpnt->result;
242 u8 * sense = SRpnt->sense, scode;
246 struct st_cmdstatus *cmdstatp;
251 cmdstatp = &STp->buffer->cmdstat;
252 osst_analyze_sense(SRpnt, cmdstatp);
254 if (cmdstatp->have_sense)
255 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
260 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
262 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
263 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
264 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
265 name, scode, sense[12], sense[13]);
266 if (cmdstatp->have_sense)
267 __scsi_print_sense(STp->device, name,
268 SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
272 if (cmdstatp->have_sense && (
274 scode != RECOVERED_ERROR &&
275 /* scode != UNIT_ATTENTION && */
276 scode != BLANK_CHECK &&
277 scode != VOLUME_OVERFLOW &&
278 SRpnt->cmd[0] != MODE_SENSE &&
279 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
280 if (cmdstatp->have_sense) {
281 printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
282 __scsi_print_sense(STp->device, name,
283 SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
286 static int notyetprinted = 1;
289 "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n",
290 name, result, driver_byte(result),
295 "%s:I: This warning may be caused by your scsi controller,\n", name);
297 "%s:I: it has been reported with some Buslogic cards.\n", name);
301 STp->pos_unknown |= STp->device->was_reset;
303 if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
304 STp->recover_count++;
305 STp->recover_erreg++;
308 if (SRpnt->cmd[0] == READ_6)
310 else if (SRpnt->cmd[0] == WRITE_6)
314 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
318 if ((sense[2] & 0xe0) == 0)
325 /* Wakeup from interrupt */
326 static void osst_end_async(struct request *req, blk_status_t status)
328 struct scsi_request *rq = scsi_req(req);
329 struct osst_request *SRpnt = req->end_io_data;
330 struct osst_tape *STp = SRpnt->stp;
331 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
333 STp->buffer->cmdstat.midlevel_result = SRpnt->result = rq->result;
335 STp->write_pending = 0;
338 memcpy(SRpnt->sense, rq->sense, SCSI_SENSE_BUFFERSIZE);
340 complete(SRpnt->waiting);
344 blk_rq_unmap_user(SRpnt->bio);
347 blk_put_request(req);
350 /* osst_request memory management */
351 static struct osst_request *osst_allocate_request(void)
353 return kzalloc(sizeof(struct osst_request), GFP_KERNEL);
356 static void osst_release_request(struct osst_request *streq)
361 static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
362 int cmd_len, int data_direction, void *buffer, unsigned bufflen,
363 int use_sg, int timeout, int retries)
366 struct scsi_request *rq;
367 struct page **pages = NULL;
368 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
371 int write = (data_direction == DMA_TO_DEVICE);
373 req = blk_get_request(SRpnt->stp->device->request_queue,
374 write ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
376 return DRIVER_ERROR << 24;
379 req->rq_flags |= RQF_QUIET;
384 struct scatterlist *sg, *sgl = (struct scatterlist *)buffer;
387 pages = kcalloc(use_sg, sizeof(struct page *), GFP_KERNEL);
391 for_each_sg(sgl, sg, use_sg, i)
392 pages[i] = sg_page(sg);
394 mdata->null_mapped = 1;
396 mdata->page_order = get_order(sgl[0].length);
398 DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order);
401 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
406 SRpnt->bio = req->bio;
407 mdata->pages = pages;
409 } else if (bufflen) {
410 err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL);
415 rq->cmd_len = cmd_len;
416 memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
417 memcpy(rq->cmd, cmd, rq->cmd_len);
418 req->timeout = timeout;
419 rq->retries = retries;
420 req->end_io_data = SRpnt;
422 blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async);
425 blk_put_request(req);
426 return DRIVER_ERROR << 24;
429 /* Do the scsi command. Waits until command performed if do_wait is true.
430 Otherwise osst_write_behind_check() is used to check that the command
432 static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp,
433 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
436 unsigned short use_sg;
437 #ifdef OSST_INJECT_ERRORS
438 static int inject = 0;
439 static int repeat = 0;
441 struct completion *waiting;
443 /* if async, make sure there's no command outstanding */
444 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
445 printk(KERN_ERR "%s: Async command already active.\n",
447 if (signal_pending(current))
448 (STp->buffer)->syscall_result = (-EINTR);
450 (STp->buffer)->syscall_result = (-EBUSY);
455 SRpnt = osst_allocate_request();
457 printk(KERN_ERR "%s: Can't allocate SCSI request.\n",
459 if (signal_pending(current))
460 (STp->buffer)->syscall_result = (-EINTR);
462 (STp->buffer)->syscall_result = (-EBUSY);
468 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
469 which IO is outstanding. It's nulled out when the IO completes. */
471 (STp->buffer)->last_SRpnt = SRpnt;
473 waiting = &STp->wait;
474 init_completion(waiting);
475 SRpnt->waiting = waiting;
477 use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0;
479 bp = (char *)&(STp->buffer->sg[0]);
480 if (STp->buffer->sg_segs < use_sg)
481 use_sg = STp->buffer->sg_segs;
484 bp = (STp->buffer)->b_data;
486 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
487 STp->buffer->cmdstat.have_sense = 0;
488 STp->buffer->syscall_result = 0;
490 if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
491 use_sg, timeout, retries))
492 /* could not allocate the buffer or request was too large */
493 (STp->buffer)->syscall_result = (-EBUSY);
495 wait_for_completion(waiting);
496 SRpnt->waiting = NULL;
497 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
498 #ifdef OSST_INJECT_ERRORS
499 if (STp->buffer->syscall_result == 0 &&
502 ( (++ inject % 83) == 29 ||
503 (STp->first_frame_position == 240
504 /* or STp->read_error_frame to fail again on the block calculated above */ &&
506 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
507 STp->buffer->last_result_fatal = 1;
515 /* Handle the write-behind checking (downs the semaphore) */
516 static void osst_write_behind_check(struct osst_tape *STp)
518 struct osst_buffer * STbuffer;
520 STbuffer = STp->buffer;
523 if (STp->write_pending)
528 wait_for_completion(&(STp->wait));
529 STp->buffer->last_SRpnt->waiting = NULL;
531 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
533 if (STp->buffer->syscall_result)
534 STp->buffer->syscall_result =
535 osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1);
537 STp->first_frame_position++;
539 osst_release_request(STp->buffer->last_SRpnt);
541 if (STbuffer->writing < STbuffer->buffer_bytes)
542 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
544 STbuffer->last_SRpnt = NULL;
545 STbuffer->buffer_bytes -= STbuffer->writing;
546 STbuffer->writing = 0;
553 /* Onstream specific Routines */
555 * Initialize the OnStream AUX
557 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
558 int logical_blk_num, int blk_sz, int blk_cnt)
560 os_aux_t *aux = STp->buffer->aux;
561 os_partition_t *par = &aux->partition;
562 os_dat_t *dat = &aux->dat;
564 if (STp->raw) return;
566 memset(aux, 0, sizeof(*aux));
567 aux->format_id = htonl(0);
568 memcpy(aux->application_sig, "LIN4", 4);
569 aux->hdwr = htonl(0);
570 aux->frame_type = frame_type;
572 switch (frame_type) {
573 case OS_FRAME_TYPE_HEADER:
574 aux->update_frame_cntr = htonl(STp->update_frame_cntr);
575 par->partition_num = OS_CONFIG_PARTITION;
576 par->par_desc_ver = OS_PARTITION_VERSION;
577 par->wrt_pass_cntr = htons(0xffff);
578 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
579 par->first_frame_ppos = htonl(0);
580 par->last_frame_ppos = htonl(0xbb7);
581 aux->frame_seq_num = htonl(0);
582 aux->logical_blk_num_high = htonl(0);
583 aux->logical_blk_num = htonl(0);
584 aux->next_mark_ppos = htonl(STp->first_mark_ppos);
586 case OS_FRAME_TYPE_DATA:
587 case OS_FRAME_TYPE_MARKER:
592 dat->dat_list[0].blk_sz = htonl(blk_sz);
593 dat->dat_list[0].blk_cnt = htons(blk_cnt);
594 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
595 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
596 dat->dat_list[0].reserved = 0;
598 case OS_FRAME_TYPE_EOD:
599 aux->update_frame_cntr = htonl(0);
600 par->partition_num = OS_DATA_PARTITION;
601 par->par_desc_ver = OS_PARTITION_VERSION;
602 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
603 par->first_frame_ppos = htonl(STp->first_data_ppos);
604 par->last_frame_ppos = htonl(STp->capacity);
605 aux->frame_seq_num = htonl(frame_seq_number);
606 aux->logical_blk_num_high = htonl(0);
607 aux->logical_blk_num = htonl(logical_blk_num);
609 default: ; /* probably FILL */
611 aux->filemark_cnt = htonl(STp->filemark_cnt);
612 aux->phys_fm = htonl(0xffffffff);
613 aux->last_mark_ppos = htonl(STp->last_mark_ppos);
614 aux->last_mark_lbn = htonl(STp->last_mark_lbn);
618 * Verify that we have the correct tape frame
620 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
622 char * name = tape_name(STp);
623 os_aux_t * aux = STp->buffer->aux;
624 os_partition_t * par = &(aux->partition);
625 struct st_partstat * STps = &(STp->ps[STp->partition]);
626 unsigned int blk_cnt, blk_sz, i;
629 if (STp->buffer->syscall_result) {
630 for (i=0; i < STp->buffer->sg_segs; i++)
631 memset(page_address(sg_page(&STp->buffer->sg[i])),
632 0, STp->buffer->sg[i].length);
633 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
635 STp->buffer->buffer_bytes = OS_FRAME_SIZE;
638 if (STp->buffer->syscall_result) {
640 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
644 if (ntohl(aux->format_id) != 0) {
646 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
650 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
651 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
653 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
657 if (par->partition_num != OS_DATA_PARTITION) {
658 if (!STp->linux_media || STp->linux_media_version != 2) {
660 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
661 name, par->partition_num);
666 if (par->par_desc_ver != OS_PARTITION_VERSION) {
668 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
672 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
674 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
675 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
679 if (aux->frame_type != OS_FRAME_TYPE_DATA &&
680 aux->frame_type != OS_FRAME_TYPE_EOD &&
681 aux->frame_type != OS_FRAME_TYPE_MARKER) {
684 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
689 if (aux->frame_type == OS_FRAME_TYPE_EOD &&
690 STp->first_frame_position < STp->eod_frame_ppos) {
691 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
692 STp->first_frame_position);
695 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
698 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
699 name, ntohl(aux->frame_seq_num), frame_seq_number);
704 if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
705 STps->eof = ST_FM_HIT;
707 i = ntohl(aux->filemark_cnt);
708 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
709 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
711 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
712 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
713 i, STp->first_frame_position - 1);
715 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
716 if (i >= STp->filemark_cnt)
717 STp->filemark_cnt = i+1;
720 if (aux->frame_type == OS_FRAME_TYPE_EOD) {
721 STps->eof = ST_EOD_1;
722 STp->frame_in_buffer = 1;
724 if (aux->frame_type == OS_FRAME_TYPE_DATA) {
725 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
726 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
727 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
728 STp->buffer->read_pointer = 0;
729 STp->frame_in_buffer = 1;
731 /* See what block size was used to write file */
732 if (STp->block_size != blk_sz && blk_sz > 0) {
734 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
735 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
736 STp->block_size<1024?STp->block_size:STp->block_size/1024,
737 STp->block_size<1024?'b':'k');
738 STp->block_size = blk_sz;
739 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
741 STps->eof = ST_NOEOF;
743 STp->frame_seq_number = ntohl(aux->frame_seq_num);
744 STp->logical_blk_num = ntohl(aux->logical_blk_num);
748 if (STp->read_error_frame == 0)
749 STp->read_error_frame = STp->first_frame_position - 1;
754 * Wait for the unit to become Ready
756 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
757 unsigned timeout, int initial_delay)
759 unsigned char cmd[MAX_COMMAND_SIZE];
760 struct osst_request * SRpnt;
761 unsigned long startwait = jiffies;
764 char * name = tape_name(STp);
766 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
769 if (initial_delay > 0)
770 msleep(jiffies_to_msecs(initial_delay));
772 memset(cmd, 0, MAX_COMMAND_SIZE);
773 cmd[0] = TEST_UNIT_READY;
775 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
777 if (!SRpnt) return (-EBUSY);
779 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
780 (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
781 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) ||
782 ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 &&
783 SRpnt->sense[13] == 0 ) )) {
786 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
787 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
793 memset(cmd, 0, MAX_COMMAND_SIZE);
794 cmd[0] = TEST_UNIT_READY;
796 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
802 if ( STp->buffer->syscall_result &&
803 osst_write_error_recovery(STp, aSRpnt, 0) ) {
805 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
806 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
807 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
808 SRpnt->sense[12], SRpnt->sense[13]);
813 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
819 * Wait for a tape to be inserted in the unit
821 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
823 unsigned char cmd[MAX_COMMAND_SIZE];
824 struct osst_request * SRpnt;
825 unsigned long startwait = jiffies;
828 char * name = tape_name(STp);
830 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
833 memset(cmd, 0, MAX_COMMAND_SIZE);
834 cmd[0] = TEST_UNIT_READY;
836 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
838 if (!SRpnt) return (-EBUSY);
840 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
841 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) {
844 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
845 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
851 memset(cmd, 0, MAX_COMMAND_SIZE);
852 cmd[0] = TEST_UNIT_READY;
854 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
860 if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 &&
861 SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) {
863 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
864 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
865 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
866 SRpnt->sense[12], SRpnt->sense[13]);
871 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
876 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame)
880 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
881 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
882 if (retval) return (retval);
883 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
884 return (osst_get_frame_position(STp, aSRpnt));
888 * Wait for write(s) to complete
890 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
892 unsigned char cmd[MAX_COMMAND_SIZE];
893 struct osst_request * SRpnt;
895 int delay = OSST_WAIT_WRITE_COMPLETE;
897 char * name = tape_name(STp);
899 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
902 memset(cmd, 0, MAX_COMMAND_SIZE);
903 cmd[0] = WRITE_FILEMARKS;
906 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
908 if (!SRpnt) return (-EBUSY);
909 if (STp->buffer->syscall_result) {
910 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) {
911 if (SRpnt->sense[13] == 8) {
912 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
915 result = osst_write_error_recovery(STp, aSRpnt, 0);
917 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
918 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
923 #define OSST_POLL_PER_SEC 10
924 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to)
926 unsigned long startwait = jiffies;
927 char * name = tape_name(STp);
929 char notyetprinted = 1;
931 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
932 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
934 while (time_before (jiffies, startwait + to*HZ))
937 result = osst_get_frame_position(STp, aSRpnt);
939 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
940 return 0; /* successful recovery leaves drive ready for frame */
941 if (result < 0) break;
942 if (STp->first_frame_position == curr &&
944 (signed)STp->last_frame_position > (signed)curr + minlast) ||
945 (minlast >= 0 && STp->cur_frames > minlast)
949 if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC))
951 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
952 name, curr, curr+minlast, STp->first_frame_position,
953 STp->last_frame_position, STp->cur_frames,
954 result, (jiffies-startwait)/HZ,
955 (((jiffies-startwait)%HZ)*10)/HZ);
960 if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted)
962 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
963 name, curr, curr+minlast, STp->first_frame_position,
964 STp->last_frame_position, STp->cur_frames, result);
968 msleep(1000 / OSST_POLL_PER_SEC);
971 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
972 name, curr, curr+minlast, STp->first_frame_position,
973 STp->last_frame_position, STp->cur_frames,
974 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
979 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
981 struct osst_request * SRpnt;
982 unsigned char cmd[MAX_COMMAND_SIZE];
983 unsigned long startwait = jiffies;
985 char * name = tape_name(STp);
989 char * olddata = STp->buffer->b_data;
990 int oldsize = STp->buffer->buffer_size;
992 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
994 memset(cmd, 0, MAX_COMMAND_SIZE);
995 cmd[0] = WRITE_FILEMARKS;
997 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1000 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
1002 if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) {
1004 /* some failure - not just not-ready */
1005 retval = osst_write_error_recovery(STp, aSRpnt, 0);
1008 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
1010 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
1011 memset(cmd, 0, MAX_COMMAND_SIZE);
1012 cmd[0] = READ_POSITION;
1014 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
1017 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
1018 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
1021 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
1023 /* TODO - figure out which error conditions can be handled */
1024 if (STp->buffer->syscall_result)
1026 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
1027 (*aSRpnt)->sense[ 2] & 0x0f,
1028 (*aSRpnt)->sense[12],
1029 (*aSRpnt)->sense[13]);
1035 * Read the next OnStream tape frame at the current location
1037 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
1039 unsigned char cmd[MAX_COMMAND_SIZE];
1040 struct osst_request * SRpnt;
1043 os_aux_t * aux = STp->buffer->aux;
1044 char * name = tape_name(STp);
1048 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
1049 retval = osst_recover_wait_frame(STp, aSRpnt, 0);
1051 memset(cmd, 0, MAX_COMMAND_SIZE);
1058 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
1060 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1061 STp->timeout, MAX_RETRIES, 1);
1066 if ((STp->buffer)->syscall_result) {
1068 if (STp->read_error_frame == 0) {
1069 STp->read_error_frame = STp->first_frame_position;
1071 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
1076 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1078 SRpnt->sense[0], SRpnt->sense[1],
1079 SRpnt->sense[2], SRpnt->sense[3],
1080 SRpnt->sense[4], SRpnt->sense[5],
1081 SRpnt->sense[6], SRpnt->sense[7]);
1085 STp->first_frame_position++;
1090 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
1093 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
1094 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
1095 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
1096 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
1097 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
1098 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
1099 if (aux->frame_type==2)
1100 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
1101 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
1102 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
1108 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
1110 struct st_partstat * STps = &(STp->ps[STp->partition]);
1111 struct osst_request * SRpnt ;
1112 unsigned char cmd[MAX_COMMAND_SIZE];
1114 char * name = tape_name(STp);
1116 if (STps->rw != ST_READING) { /* Initialize read operation */
1117 if (STps->rw == ST_WRITING || STp->dirty) {
1118 STp->write_type = OS_WRITE_DATA;
1119 osst_flush_write_buffer(STp, aSRpnt);
1120 osst_flush_drive_buffer(STp, aSRpnt);
1122 STps->rw = ST_READING;
1123 STp->frame_in_buffer = 0;
1126 * Issue a read 0 command to get the OnStream drive
1127 * read frames into its buffer.
1129 memset(cmd, 0, MAX_COMMAND_SIZE);
1134 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
1136 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
1138 if ((retval = STp->buffer->syscall_result))
1139 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
1145 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt,
1146 int frame_seq_number, int quiet)
1148 struct st_partstat * STps = &(STp->ps[STp->partition]);
1149 char * name = tape_name(STp);
1157 * If we want just any frame (-1) and there is a frame in the buffer, return it
1159 if (frame_seq_number == -1 && STp->frame_in_buffer) {
1161 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1166 * Search and wait for the next logical tape frame
1170 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1171 name, frame_seq_number);
1172 if (STp->read_error_frame) {
1173 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1175 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1176 name, STp->read_error_frame);
1178 STp->read_error_frame = 0;
1185 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1186 name, frame_seq_number, cnt);
1188 if ( osst_initiate_read(STp, aSRpnt)
1189 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1192 position = osst_get_frame_position(STp, aSRpnt);
1193 if (position >= 0xbae && position < 0xbb8)
1195 else if (position > STp->eod_frame_ppos || ++bad == 10) {
1196 position = STp->read_error_frame - 1;
1204 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1207 osst_set_frame_position(STp, aSRpnt, position, 0);
1210 if (osst_verify_frame(STp, frame_seq_number, quiet))
1212 if (osst_verify_frame(STp, -1, quiet)) {
1213 x = ntohl(STp->buffer->aux->frame_seq_num);
1214 if (STp->fast_open) {
1216 "%s:W: Found logical frame %d instead of %d after fast open\n",
1217 name, x, frame_seq_number);
1219 STp->read_error_frame = 0;
1222 if (x > frame_seq_number) {
1224 /* positioning backwards did not bring us to the desired frame */
1225 position = STp->read_error_frame - 1;
1228 position = osst_get_frame_position(STp, aSRpnt)
1229 + frame_seq_number - x - 1;
1231 if (STp->first_frame_position >= 3000 && position < 3000)
1236 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1237 name, x, frame_seq_number,
1238 STp->first_frame_position - position);
1240 osst_set_frame_position(STp, aSRpnt, position, 0);
1246 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1248 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1250 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1253 STp->frame_in_buffer = 0;
1256 STp->recover_count++;
1257 STp->recover_erreg++;
1258 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1259 name, STp->read_error_frame);
1264 if (debugging || STps->eof)
1266 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1267 name, frame_seq_number, STp->frame_seq_number, STps->eof);
1270 STp->read_error_frame = 0;
1274 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num)
1276 struct st_partstat * STps = &(STp->ps[STp->partition]);
1277 char * name = tape_name(STp);
1279 int frame_seq_estimate, ppos_estimate, move;
1281 if (logical_blk_num < 0) logical_blk_num = 0;
1283 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1284 name, logical_blk_num, STp->logical_blk_num,
1285 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1286 STp->block_size<1024?'b':'k');
1288 /* Do we know where we are? */
1289 if (STps->drv_block >= 0) {
1290 move = logical_blk_num - STp->logical_blk_num;
1291 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1292 move /= (OS_DATA_SIZE / STp->block_size);
1293 frame_seq_estimate = STp->frame_seq_number + move;
1295 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1297 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1298 else ppos_estimate = frame_seq_estimate + 20;
1299 while (++retries < 10) {
1300 if (ppos_estimate > STp->eod_frame_ppos-2) {
1301 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1302 ppos_estimate = STp->eod_frame_ppos - 2;
1304 if (frame_seq_estimate < 0) {
1305 frame_seq_estimate = 0;
1308 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1309 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1310 /* we've located the estimated frame, now does it have our block? */
1311 if (logical_blk_num < STp->logical_blk_num ||
1312 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1313 if (STps->eof == ST_FM_HIT)
1314 move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1316 move = logical_blk_num - STp->logical_blk_num;
1317 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1318 move /= (OS_DATA_SIZE / STp->block_size);
1320 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1323 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1324 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1325 STp->logical_blk_num, logical_blk_num, move);
1327 frame_seq_estimate += move;
1328 ppos_estimate += move;
1331 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1332 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1333 STp->logical_blk_num = logical_blk_num;
1336 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1337 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1338 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1341 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1342 if (STps->eof == ST_FM_HIT) {
1344 STps->drv_block = 0;
1346 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1347 STp->logical_blk_num -
1348 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1351 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1355 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1357 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1359 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1360 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1361 STp->logical_blk_num, logical_blk_num);
1363 if (frame_seq_estimate != STp->frame_seq_number)
1364 ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1369 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1370 name, logical_blk_num, STp->logical_blk_num, retries);
1374 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1375 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1376 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1377 * inside each frame. Finally, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1379 #define OSST_FRAME_SHIFT 6
1380 #define OSST_SECTOR_SHIFT 9
1381 #define OSST_SECTOR_MASK 0x03F
1383 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt)
1387 char * name = tape_name(STp);
1390 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1391 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1392 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1393 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1394 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1395 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1397 /* do we know where we are inside a file? */
1398 if (STp->ps[STp->partition].drv_block >= 0) {
1399 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1400 STp->first_frame_position) << OSST_FRAME_SHIFT;
1401 if (STp->ps[STp->partition].rw == ST_WRITING)
1402 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1404 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1406 sector = osst_get_frame_position(STp, aSRpnt);
1408 sector <<= OSST_FRAME_SHIFT;
1413 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector)
1415 struct st_partstat * STps = &(STp->ps[STp->partition]);
1416 int frame = sector >> OSST_FRAME_SHIFT,
1417 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1420 char * name = tape_name(STp);
1422 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1423 name, sector, frame, offset);
1425 if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1427 if (frame <= STp->first_data_ppos) {
1428 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1429 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1431 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1432 if (r < 0) return r;
1434 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1435 if (r < 0) return r;
1437 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1440 STp->logical_blk_num += offset / STp->block_size;
1441 STp->buffer->read_pointer = offset;
1442 STp->buffer->buffer_bytes -= offset;
1444 STp->frame_seq_number++;
1445 STp->frame_in_buffer = 0;
1446 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1447 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1449 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1450 if (STps->eof == ST_FM_HIT) {
1452 STps->drv_block = 0;
1454 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1455 STp->logical_blk_num -
1456 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1459 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1462 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1463 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1464 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1470 * Read back the drive's internal buffer contents, as a part
1471 * of the write error recovery mechanism for old OnStream
1472 * firmware revisions.
1473 * Precondition for this function to work: all frames in the
1474 * drive's buffer must be of one type (DATA, MARK or EOD)!
1476 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
1477 unsigned int frame, unsigned int skip, int pending)
1479 struct osst_request * SRpnt = * aSRpnt;
1480 unsigned char * buffer, * p;
1481 unsigned char cmd[MAX_COMMAND_SIZE];
1482 int flag, new_frame, i;
1483 int nframes = STp->cur_frames;
1484 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1485 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1486 - (nframes + pending - 1);
1487 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1488 - (nframes + pending - 1) * blks_per_frame;
1489 char * name = tape_name(STp);
1490 unsigned long startwait = jiffies;
1492 int dbg = debugging;
1495 if ((buffer = vmalloc(array_size((nframes + 1), OS_DATA_SIZE))) == NULL)
1498 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1499 name, nframes, pending?" and one that was pending":"");
1501 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1503 if (pending && debugging)
1504 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1505 name, frame_seq_number + nframes,
1506 logical_blk_num + nframes * blks_per_frame,
1507 p[0], p[1], p[2], p[3]);
1509 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1511 memset(cmd, 0, MAX_COMMAND_SIZE);
1512 cmd[0] = 0x3C; /* Buffer Read */
1513 cmd[1] = 6; /* Retrieve Faulty Block */
1514 cmd[7] = 32768 >> 8;
1515 cmd[8] = 32768 & 0xff;
1517 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1518 STp->timeout, MAX_RETRIES, 1);
1520 if ((STp->buffer)->syscall_result || !SRpnt) {
1521 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1526 osst_copy_from_buffer(STp->buffer, p);
1529 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1530 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1534 osst_get_frame_position(STp, aSRpnt);
1537 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1539 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1540 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1542 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1545 if (STp->write_type == OS_WRITE_HEADER) {
1547 p += skip * OS_DATA_SIZE;
1549 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1554 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1555 name, new_frame+i, frame_seq_number+i);
1557 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1558 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1559 osst_get_frame_position(STp, aSRpnt);
1562 if (new_frame > frame + 1000) {
1563 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1567 if ( i >= nframes + pending ) break;
1570 osst_copy_to_buffer(STp->buffer, p);
1572 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1574 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1575 logical_blk_num + i*blks_per_frame,
1576 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1577 memset(cmd, 0, MAX_COMMAND_SIZE);
1585 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1586 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1587 p[0], p[1], p[2], p[3]);
1589 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1590 STp->timeout, MAX_RETRIES, 1);
1592 if (STp->buffer->syscall_result)
1595 p += OS_DATA_SIZE; i++;
1597 /* if we just sent the last frame, wait till all successfully written */
1598 if ( i == nframes + pending ) {
1600 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1602 memset(cmd, 0, MAX_COMMAND_SIZE);
1603 cmd[0] = WRITE_FILEMARKS;
1605 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1606 STp->timeout, MAX_RETRIES, 1);
1609 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1610 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1614 flag = STp->buffer->syscall_result;
1615 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1617 memset(cmd, 0, MAX_COMMAND_SIZE);
1618 cmd[0] = TEST_UNIT_READY;
1620 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1623 if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
1624 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
1625 /* in the process of becoming ready */
1629 if (STp->buffer->syscall_result)
1635 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1641 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1642 SRpnt->sense[12] == 0 &&
1643 SRpnt->sense[13] == 2) {
1644 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1646 return (-EIO); /* hit end of tape = fail */
1648 i = ((SRpnt->sense[3] << 24) |
1649 (SRpnt->sense[4] << 16) |
1650 (SRpnt->sense[5] << 8) |
1651 SRpnt->sense[6] ) - new_frame;
1652 p = &buffer[i * OS_DATA_SIZE];
1654 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1656 osst_get_frame_position(STp, aSRpnt);
1658 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1659 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1664 /* error recovery did not successfully complete */
1665 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1666 STp->write_type == OS_WRITE_HEADER?"header":"body");
1669 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1674 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
1675 unsigned int frame, unsigned int skip, int pending)
1677 unsigned char cmd[MAX_COMMAND_SIZE];
1678 struct osst_request * SRpnt;
1679 char * name = tape_name(STp);
1681 int attempts = 1000 / skip;
1683 unsigned long startwait = jiffies;
1685 int dbg = debugging;
1688 while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1693 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1695 expected = frame+skip+STp->cur_frames+pending;
1697 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1698 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1700 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1703 schedule_timeout_interruptible(msecs_to_jiffies(100));
1705 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1707 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1708 name, STp->first_frame_position,
1709 STp->last_frame_position, STp->cur_frames);
1711 frame = STp->last_frame_position;
1715 if (pending && STp->cur_frames < 50) {
1717 memset(cmd, 0, MAX_COMMAND_SIZE);
1722 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1723 name, STp->frame_seq_number-1, STp->first_frame_position);
1725 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1726 STp->timeout, MAX_RETRIES, 1);
1729 if (STp->buffer->syscall_result) { /* additional write error */
1730 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1731 SRpnt->sense[12] == 0 &&
1732 SRpnt->sense[13] == 2) {
1734 "%s:E: Volume overflow in write error recovery\n",
1736 break; /* hit end of tape = fail */
1745 if (STp->cur_frames == 0) {
1748 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1750 if (STp->first_frame_position != expected) {
1751 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1752 name, STp->first_frame_position, expected);
1759 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1760 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1764 schedule_timeout_interruptible(msecs_to_jiffies(100));
1766 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1774 * Error recovery algorithm for the OnStream tape.
1777 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending)
1779 struct osst_request * SRpnt = * aSRpnt;
1780 struct st_partstat * STps = & STp->ps[STp->partition];
1781 char * name = tape_name(STp);
1784 unsigned int frame, skip;
1786 rw_state = STps->rw;
1788 if ((SRpnt->sense[ 2] & 0x0f) != 3
1789 || SRpnt->sense[12] != 12
1790 || SRpnt->sense[13] != 0) {
1792 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1793 SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]);
1797 frame = (SRpnt->sense[3] << 24) |
1798 (SRpnt->sense[4] << 16) |
1799 (SRpnt->sense[5] << 8) |
1801 skip = SRpnt->sense[9];
1804 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1806 osst_get_frame_position(STp, aSRpnt);
1808 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1809 name, STp->first_frame_position, STp->last_frame_position);
1811 switch (STp->write_type) {
1814 case OS_WRITE_NEW_MARK:
1816 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1817 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1818 if (STp->os_fw_rev >= 10600)
1819 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1821 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1822 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1824 retval?"" :"Don't worry, ",
1825 retval?" not ":" ");
1827 case OS_WRITE_LAST_MARK:
1828 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1829 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1832 case OS_WRITE_HEADER:
1833 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1834 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1837 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1838 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1840 osst_get_frame_position(STp, aSRpnt);
1842 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1843 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1844 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1847 STp->recover_count++;
1848 STp->recover_erreg++;
1852 STps->rw = rw_state;
1856 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt,
1857 int mt_op, int mt_count)
1859 char * name = tape_name(STp);
1861 int last_mark_ppos = -1;
1864 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1866 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1868 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1872 if (STp->linux_media_version >= 4) {
1874 * direct lookup in header filemark list
1876 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1877 if (STp->header_ok &&
1878 STp->header_cache != NULL &&
1879 (cnt - mt_count) >= 0 &&
1880 (cnt - mt_count) < OS_FM_TAB_MAX &&
1881 (cnt - mt_count) < STp->filemark_cnt &&
1882 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1884 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1886 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1887 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1888 STp->header_cache == NULL?"lack of header cache":"count out of range");
1890 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1892 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1893 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1894 STp->buffer->aux->last_mark_ppos))?"match":"error",
1895 mt_count, last_mark_ppos);
1897 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1898 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1899 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1902 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1906 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1907 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1908 name, last_mark_ppos);
1914 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1918 while (cnt != mt_count) {
1919 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1920 if (last_mark_ppos == -1)
1923 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1925 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1927 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1929 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1933 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1934 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1935 name, last_mark_ppos);
1940 if (mt_op == MTBSFM) {
1941 STp->frame_seq_number++;
1942 STp->frame_in_buffer = 0;
1943 STp->buffer->buffer_bytes = 0;
1944 STp->buffer->read_pointer = 0;
1945 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1951 * ADRL 1.1 compatible "slow" space filemarks fwd version
1953 * Just scans for the filemark sequentially.
1955 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt,
1956 int mt_op, int mt_count)
1960 char * name = tape_name(STp);
1962 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1964 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1966 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1971 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1973 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1977 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1979 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1981 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1983 if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1985 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1986 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1988 STp->eod_frame_ppos = STp->first_frame_position-1;
1992 if (cnt == mt_count)
1994 STp->frame_in_buffer = 0;
1996 if (mt_op == MTFSF) {
1997 STp->frame_seq_number++;
1998 STp->frame_in_buffer = 0;
1999 STp->buffer->buffer_bytes = 0;
2000 STp->buffer->read_pointer = 0;
2001 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2007 * Fast linux specific version of OnStream FSF
2009 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt,
2010 int mt_op, int mt_count)
2012 char * name = tape_name(STp);
2014 next_mark_ppos = -1;
2017 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
2019 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2021 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
2026 if (STp->linux_media_version >= 4) {
2028 * direct lookup in header filemark list
2030 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
2031 if (STp->header_ok &&
2032 STp->header_cache != NULL &&
2033 (cnt + mt_count) < OS_FM_TAB_MAX &&
2034 (cnt + mt_count) < STp->filemark_cnt &&
2035 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2036 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
2038 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
2040 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
2041 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
2042 STp->header_cache == NULL?"lack of header cache":"count out of range");
2044 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
2046 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2047 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
2048 STp->buffer->aux->last_mark_ppos))?"match":"error",
2049 mt_count, next_mark_ppos);
2051 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
2053 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2055 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2057 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2058 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2060 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2065 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2066 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2067 name, next_mark_ppos);
2070 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
2071 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
2072 name, cnt+mt_count, next_mark_ppos,
2073 ntohl(STp->buffer->aux->filemark_cnt));
2079 * Find nearest (usually previous) marker, then jump from marker to marker
2082 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
2084 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
2086 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
2090 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
2091 if (STp->first_mark_ppos == -1) {
2093 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2095 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2097 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
2098 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2101 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2106 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2107 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
2108 name, STp->first_mark_ppos);
2112 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
2118 while (cnt != mt_count) {
2119 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
2120 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
2122 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2124 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
2127 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
2129 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2131 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2133 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2138 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2139 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2140 name, next_mark_ppos);
2145 if (mt_op == MTFSF) {
2146 STp->frame_seq_number++;
2147 STp->frame_in_buffer = 0;
2148 STp->buffer->buffer_bytes = 0;
2149 STp->buffer->read_pointer = 0;
2150 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2156 * In debug mode, we want to see as many errors as possible
2157 * to test the error recovery mechanism.
2160 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries)
2162 unsigned char cmd[MAX_COMMAND_SIZE];
2163 struct osst_request * SRpnt = * aSRpnt;
2164 char * name = tape_name(STp);
2166 memset(cmd, 0, MAX_COMMAND_SIZE);
2167 cmd[0] = MODE_SELECT;
2169 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2171 (STp->buffer)->b_data[0] = cmd[4] - 1;
2172 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
2173 (STp->buffer)->b_data[2] = 0; /* Reserved */
2174 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
2175 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2176 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2177 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2178 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2181 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2183 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2186 if ((STp->buffer)->syscall_result)
2187 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2192 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt)
2195 int this_mark_ppos = STp->first_frame_position;
2196 int this_mark_lbn = STp->logical_blk_num;
2198 char * name = tape_name(STp);
2201 if (STp->raw) return 0;
2203 STp->write_type = OS_WRITE_NEW_MARK;
2205 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2206 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2209 result = osst_flush_write_buffer(STp, aSRpnt);
2210 result |= osst_flush_drive_buffer(STp, aSRpnt);
2211 STp->last_mark_ppos = this_mark_ppos;
2212 STp->last_mark_lbn = this_mark_lbn;
2213 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2214 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2215 if (STp->filemark_cnt++ == 0)
2216 STp->first_mark_ppos = this_mark_ppos;
2220 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt)
2224 char * name = tape_name(STp);
2227 if (STp->raw) return 0;
2229 STp->write_type = OS_WRITE_EOD;
2230 STp->eod_frame_ppos = STp->first_frame_position;
2232 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2233 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2237 result = osst_flush_write_buffer(STp, aSRpnt);
2238 result |= osst_flush_drive_buffer(STp, aSRpnt);
2239 STp->eod_frame_lfa = --(STp->frame_seq_number);
2243 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2245 char * name = tape_name(STp);
2248 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2250 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2251 osst_set_frame_position(STp, aSRpnt, where, 0);
2252 STp->write_type = OS_WRITE_FILLER;
2254 memcpy(STp->buffer->b_data, "Filler", 6);
2255 STp->buffer->buffer_bytes = 6;
2257 if (osst_flush_write_buffer(STp, aSRpnt)) {
2258 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2263 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2265 return osst_flush_drive_buffer(STp, aSRpnt);
2268 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2270 char * name = tape_name(STp);
2274 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2276 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2277 osst_set_frame_position(STp, aSRpnt, where, 0);
2278 STp->write_type = OS_WRITE_HEADER;
2280 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2281 STp->buffer->buffer_bytes = sizeof(os_header_t);
2283 if (osst_flush_write_buffer(STp, aSRpnt)) {
2284 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2288 result = osst_flush_drive_buffer(STp, aSRpnt);
2290 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2295 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod)
2297 os_header_t * header;
2299 char * name = tape_name(STp);
2302 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2304 if (STp->raw) return 0;
2306 if (STp->header_cache == NULL) {
2307 if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
2308 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2311 memset(STp->header_cache, 0, sizeof(os_header_t));
2313 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2316 if (STp->header_ok) STp->update_frame_cntr++;
2317 else STp->update_frame_cntr = 0;
2319 header = STp->header_cache;
2320 strcpy(header->ident_str, "ADR_SEQ");
2321 header->major_rev = 1;
2322 header->minor_rev = 4;
2323 header->ext_trk_tb_off = htons(17192);
2324 header->pt_par_num = 1;
2325 header->partition[0].partition_num = OS_DATA_PARTITION;
2326 header->partition[0].par_desc_ver = OS_PARTITION_VERSION;
2327 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2328 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2329 header->partition[0].last_frame_ppos = htonl(STp->capacity);
2330 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2331 header->cfg_col_width = htonl(20);
2332 header->dat_col_width = htonl(1500);
2333 header->qfa_col_width = htonl(0);
2334 header->ext_track_tb.nr_stream_part = 1;
2335 header->ext_track_tb.et_ent_sz = 32;
2336 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2337 header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2338 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2339 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2340 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa);
2341 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
2342 header->dat_fm_tab.fm_part_num = 0;
2343 header->dat_fm_tab.fm_tab_ent_sz = 4;
2344 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2345 STp->filemark_cnt:OS_FM_TAB_MAX);
2347 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2348 if (STp->update_frame_cntr == 0)
2349 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2350 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2354 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2356 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2359 printk(KERN_ERR "%s:E: Write header failed\n", name);
2361 memcpy(STp->application_sig, "LIN4", 4);
2362 STp->linux_media = 1;
2363 STp->linux_media_version = 4;
2369 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt)
2371 if (STp->header_cache != NULL)
2372 memset(STp->header_cache, 0, sizeof(os_header_t));
2374 STp->logical_blk_num = STp->frame_seq_number = 0;
2375 STp->frame_in_buffer = 0;
2376 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2377 STp->filemark_cnt = 0;
2378 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2379 return osst_write_header(STp, aSRpnt, 1);
2382 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos)
2384 char * name = tape_name(STp);
2385 os_header_t * header;
2388 int linux_media_version,
2394 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2395 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2396 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2397 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2398 if (osst_initiate_read (STp, aSRpnt)) {
2399 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2403 if (osst_read_frame(STp, aSRpnt, 180)) {
2405 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2409 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2410 aux = STp->buffer->aux;
2411 if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2413 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2417 if (ntohl(aux->frame_seq_num) != 0 ||
2418 ntohl(aux->logical_blk_num) != 0 ||
2419 aux->partition.partition_num != OS_CONFIG_PARTITION ||
2420 ntohl(aux->partition.first_frame_ppos) != 0 ||
2421 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2423 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2424 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2425 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2426 ntohl(aux->partition.last_frame_ppos));
2430 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2431 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2432 strlcpy(id_string, header->ident_str, 8);
2434 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2438 update_frame_cntr = ntohl(aux->update_frame_cntr);
2439 if (update_frame_cntr < STp->update_frame_cntr) {
2441 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2442 name, ppos, update_frame_cntr, STp->update_frame_cntr);
2446 if (header->major_rev != 1 || header->minor_rev != 4 ) {
2448 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2449 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2450 header->minor_rev > 4 )? "Invalid" : "Warning:",
2451 header->major_rev, header->minor_rev);
2453 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2457 if (header->pt_par_num != 1)
2458 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2459 name, header->pt_par_num);
2461 memcpy(id_string, aux->application_sig, 4);
2463 if (memcmp(id_string, "LIN", 3) == 0) {
2464 STp->linux_media = 1;
2465 linux_media_version = id_string[3] - '0';
2466 if (linux_media_version != 4)
2467 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2468 name, linux_media_version);
2470 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2473 if (linux_media_version < STp->linux_media_version) {
2475 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2476 name, ppos, linux_media_version);
2480 if (linux_media_version > STp->linux_media_version) {
2482 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2483 name, ppos, linux_media_version);
2485 memcpy(STp->application_sig, id_string, 5);
2486 STp->linux_media_version = linux_media_version;
2487 STp->update_frame_cntr = -1;
2489 if (update_frame_cntr > STp->update_frame_cntr) {
2491 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2492 name, ppos, update_frame_cntr);
2494 if (STp->header_cache == NULL) {
2495 if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
2496 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2500 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2503 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2504 header = STp->header_cache; /* further accesses from cached (full) copy */
2506 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2507 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2508 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2509 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2510 STp->filemark_cnt = ntohl(aux->filemark_cnt);
2511 STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2512 STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2513 STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2514 STp->update_frame_cntr = update_frame_cntr;
2516 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2517 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2518 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2519 STp->first_data_ppos,
2520 ntohl(header->partition[0].last_frame_ppos),
2521 ntohl(header->partition[0].eod_frame_ppos));
2522 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2523 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2525 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2527 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2529 memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2530 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2531 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2533 if (header->minor_rev == 4 &&
2534 (header->ext_trk_tb_off != htons(17192) ||
2535 header->partition[0].partition_num != OS_DATA_PARTITION ||
2536 header->partition[0].par_desc_ver != OS_PARTITION_VERSION ||
2537 header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2538 header->cfg_col_width != htonl(20) ||
2539 header->dat_col_width != htonl(1500) ||
2540 header->qfa_col_width != htonl(0) ||
2541 header->ext_track_tb.nr_stream_part != 1 ||
2542 header->ext_track_tb.et_ent_sz != 32 ||
2543 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION ||
2544 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2545 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2546 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2547 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) ||
2548 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION ||
2549 header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2550 header->dat_fm_tab.fm_tab_ent_cnt !=
2551 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2552 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2559 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt)
2564 char * name = tape_name(STp);
2566 position = osst_get_frame_position(STp, aSRpnt);
2569 STp->header_ok = STp->linux_media = 1;
2570 STp->linux_media_version = 0;
2573 STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2574 STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2575 STp->eod_frame_ppos = STp->first_data_ppos = -1;
2576 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2578 printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2581 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2582 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2584 first = position==10?0xbae: 5;
2585 last = position==10?0xbb3:10;
2587 for (ppos = first; ppos < last; ppos++)
2588 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2591 first = position==10? 5:0xbae;
2592 last = position==10?10:0xbb3;
2594 for (ppos = first; ppos < last; ppos++)
2595 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2599 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2600 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2601 osst_set_frame_position(STp, aSRpnt, 10, 0);
2604 if (position <= STp->first_data_ppos) {
2605 position = STp->first_data_ppos;
2606 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2608 osst_set_frame_position(STp, aSRpnt, position, 0);
2614 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt)
2616 int frame_position = STp->first_frame_position;
2617 int frame_seq_numbr = STp->frame_seq_number;
2618 int logical_blk_num = STp->logical_blk_num;
2619 int halfway_frame = STp->frame_in_buffer;
2620 int read_pointer = STp->buffer->read_pointer;
2621 int prev_mark_ppos = -1;
2622 int actual_mark_ppos, i, n;
2624 char * name = tape_name(STp);
2626 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2628 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2629 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2631 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2635 if (STp->linux_media_version >= 4) {
2636 for (i=0; i<STp->filemark_cnt; i++)
2637 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2640 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2641 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2642 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2643 if (frame_position != STp->first_frame_position ||
2644 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2645 prev_mark_ppos != actual_mark_ppos ) {
2647 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2648 STp->first_frame_position, frame_position,
2649 STp->frame_seq_number + (halfway_frame?0:1),
2650 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2654 if (halfway_frame) {
2655 /* prepare buffer for append and rewrite on top of original */
2656 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2657 STp->buffer->buffer_bytes = read_pointer;
2658 STp->ps[STp->partition].rw = ST_WRITING;
2661 STp->frame_in_buffer = halfway_frame;
2662 STp->frame_seq_number = frame_seq_numbr;
2663 STp->logical_blk_num = logical_blk_num;
2667 /* Acc. to OnStream, the vers. numbering is the following:
2668 * X.XX for released versions (X=digit),
2669 * XXXY for unreleased versions (Y=letter)
2670 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2671 * This fn makes monoton numbers out of this scheme ...
2673 static unsigned int osst_parse_firmware_rev (const char * str)
2675 if (str[1] == '.') {
2676 return (str[0]-'0')*10000
2680 return (str[0]-'0')*10000
2682 +(str[2]-'0')*100 - 100
2688 * Configure the OnStream SCII tape drive for default operation
2690 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
2692 unsigned char cmd[MAX_COMMAND_SIZE];
2693 char * name = tape_name(STp);
2694 struct osst_request * SRpnt = * aSRpnt;
2695 osst_mode_parameter_header_t * header;
2696 osst_block_size_page_t * bs;
2697 osst_capabilities_page_t * cp;
2698 osst_tape_paramtr_page_t * prm;
2699 int drive_buffer_size;
2701 if (STp->ready != ST_READY) {
2703 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2708 if (STp->os_fw_rev < 10600) {
2709 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2710 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2714 * Configure 32.5KB (data+aux) frame size.
2715 * Get the current frame size from the block size mode page
2717 memset(cmd, 0, MAX_COMMAND_SIZE);
2718 cmd[0] = MODE_SENSE;
2720 cmd[2] = BLOCK_SIZE_PAGE;
2721 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2723 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2724 if (SRpnt == NULL) {
2726 printk(OSST_DEB_MSG "osst :D: Busy\n");
2731 if ((STp->buffer)->syscall_result != 0) {
2732 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2736 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2737 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2740 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2741 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No");
2742 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2743 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2747 * Configure default auto columns mode, 32.5KB transfer mode
2755 memset(cmd, 0, MAX_COMMAND_SIZE);
2756 cmd[0] = MODE_SELECT;
2758 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2760 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2762 if ((STp->buffer)->syscall_result != 0) {
2763 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2768 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2770 * In debug mode, we want to see as many errors as possible
2771 * to test the error recovery mechanism.
2773 osst_set_retries(STp, aSRpnt, 0);
2778 * Set vendor name to 'LIN4' for "Linux support version 4".
2781 memset(cmd, 0, MAX_COMMAND_SIZE);
2782 cmd[0] = MODE_SELECT;
2784 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2786 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2787 header->medium_type = 0; /* Medium Type - ignoring */
2788 header->dsp = 0; /* Reserved */
2789 header->bdl = 0; /* Block Descriptor Length */
2791 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2792 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2793 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2794 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2795 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2796 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2797 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2798 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2800 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2803 if ((STp->buffer)->syscall_result != 0) {
2804 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2805 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2809 memset(cmd, 0, MAX_COMMAND_SIZE);
2810 cmd[0] = MODE_SENSE;
2812 cmd[2] = CAPABILITIES_PAGE;
2813 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2815 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2818 if ((STp->buffer)->syscall_result != 0) {
2819 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2823 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2824 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2825 sizeof(osst_mode_parameter_header_t) + header->bdl);
2827 drive_buffer_size = ntohs(cp->buffer_size) / 2;
2829 memset(cmd, 0, MAX_COMMAND_SIZE);
2830 cmd[0] = MODE_SENSE;
2832 cmd[2] = TAPE_PARAMTR_PAGE;
2833 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2835 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2838 if ((STp->buffer)->syscall_result != 0) {
2839 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2843 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2844 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2845 sizeof(osst_mode_parameter_header_t) + header->bdl);
2847 STp->density = prm->density;
2848 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2850 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2851 name, STp->density, STp->capacity / 32, drive_buffer_size);
2859 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2860 it messes up the block number). */
2861 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward)
2864 char * name = tape_name(STp);
2868 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2869 name, forward ? "forward" : "backward");
2873 /* assumes that the filemark is already read by the drive, so this is low cost */
2874 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2877 /* assumes this is only called if we just read the filemark! */
2878 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2881 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2882 name, forward ? "forward" : "backward");
2888 /* Get the tape position. */
2890 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
2892 unsigned char scmd[MAX_COMMAND_SIZE];
2893 struct osst_request * SRpnt;
2895 char * name = tape_name(STp);
2897 /* KG: We want to be able to use it for checking Write Buffer availability
2898 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2900 char * olddata = STp->buffer->b_data;
2901 int oldsize = STp->buffer->buffer_size;
2903 if (STp->ready != ST_READY) return (-EIO);
2905 memset (scmd, 0, MAX_COMMAND_SIZE);
2906 scmd[0] = READ_POSITION;
2908 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2909 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2910 STp->timeout, MAX_RETRIES, 1);
2912 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2917 if (STp->buffer->syscall_result)
2918 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */
2920 if (result == -EINVAL)
2921 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2923 if (result == -EIO) { /* re-read position - this needs to preserve media errors */
2924 unsigned char mysense[16];
2925 memcpy (mysense, SRpnt->sense, 16);
2926 memset (scmd, 0, MAX_COMMAND_SIZE);
2927 scmd[0] = READ_POSITION;
2928 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2929 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2930 STp->timeout, MAX_RETRIES, 1);
2932 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2933 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2934 SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]);
2936 if (!STp->buffer->syscall_result)
2937 memcpy (SRpnt->sense, mysense, 16);
2939 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2941 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2942 + ((STp->buffer)->b_data[5] << 16)
2943 + ((STp->buffer)->b_data[6] << 8)
2944 + (STp->buffer)->b_data[7];
2945 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2946 + ((STp->buffer)->b_data[ 9] << 16)
2947 + ((STp->buffer)->b_data[10] << 8)
2948 + (STp->buffer)->b_data[11];
2949 STp->cur_frames = (STp->buffer)->b_data[15];
2952 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2953 STp->first_frame_position, STp->last_frame_position,
2954 ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2955 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2959 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2961 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2962 STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2964 STp->first_frame_position = STp->last_frame_position;
2967 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2969 return (result == 0 ? STp->first_frame_position : result);
2973 /* Set the tape block */
2974 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip)
2976 unsigned char scmd[MAX_COMMAND_SIZE];
2977 struct osst_request * SRpnt;
2978 struct st_partstat * STps;
2980 int pp = (ppos == 3000 && !skip)? 0 : ppos;
2981 char * name = tape_name(STp);
2983 if (STp->ready != ST_READY) return (-EIO);
2985 STps = &(STp->ps[STp->partition]);
2987 if (ppos < 0 || ppos > STp->capacity) {
2988 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2989 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2996 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2998 memset (scmd, 0, MAX_COMMAND_SIZE);
3001 scmd[3] = (pp >> 24);
3002 scmd[4] = (pp >> 16);
3003 scmd[5] = (pp >> 8);
3008 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
3014 if ((STp->buffer)->syscall_result != 0) {
3016 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
3017 name, STp->first_frame_position, pp);
3022 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
3023 } while ((pp != ppos) && (pp = ppos));
3024 STp->first_frame_position = STp->last_frame_position = ppos;
3025 STps->eof = ST_NOEOF;
3028 STp->frame_in_buffer = 0;
3032 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT)
3034 struct st_partstat * STps = &(STp->ps[STp->partition]);
3037 if (STp->write_type != OS_WRITE_NEW_MARK) {
3038 /* true unless the user wrote the filemark for us */
3039 result = osst_flush_drive_buffer(STp, aSRpnt);
3040 if (result < 0) goto out;
3041 result = osst_write_filemark(STp, aSRpnt);
3042 if (result < 0) goto out;
3044 if (STps->drv_file >= 0)
3046 STps->drv_block = 0;
3048 result = osst_write_eod(STp, aSRpnt);
3049 osst_write_header(STp, aSRpnt, leave_at_EOT);
3056 /* osst versions of st functions - augmented and stripped to suit OnStream only */
3058 /* Flush the write buffer (never need to write if variable blocksize). */
3059 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt)
3061 int offset, transfer, blks = 0;
3063 unsigned char cmd[MAX_COMMAND_SIZE];
3064 struct osst_request * SRpnt = *aSRpnt;
3065 struct st_partstat * STps;
3066 char * name = tape_name(STp);
3068 if ((STp->buffer)->writing) {
3069 if (SRpnt == (STp->buffer)->last_SRpnt)
3071 { printk(OSST_DEB_MSG
3072 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name);
3074 *aSRpnt = SRpnt = NULL;
3078 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name);
3080 osst_write_behind_check(STp);
3081 if ((STp->buffer)->syscall_result) {
3084 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
3085 name, (STp->buffer)->midlevel_result);
3087 if ((STp->buffer)->midlevel_result == INT_MAX)
3094 if (STp->dirty == 1) {
3097 STps = &(STp->ps[STp->partition]);
3098 STps->rw = ST_WRITING;
3099 offset = STp->buffer->buffer_bytes;
3100 blks = (offset + STp->block_size - 1) / STp->block_size;
3101 transfer = OS_FRAME_SIZE;
3103 if (offset < OS_DATA_SIZE)
3104 osst_zero_buffer_tail(STp->buffer);
3107 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
3108 result = osst_recover_wait_frame(STp, aSRpnt, 1);
3110 memset(cmd, 0, MAX_COMMAND_SIZE);
3115 switch (STp->write_type) {
3119 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
3120 name, blks, STp->frame_seq_number,
3121 STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3123 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3124 STp->logical_blk_num - blks, STp->block_size, blks);
3127 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
3128 STp->logical_blk_num, 0, 0);
3130 case OS_WRITE_NEW_MARK:
3131 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
3132 STp->logical_blk_num++, 0, blks=1);
3134 case OS_WRITE_HEADER:
3135 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
3137 default: /* probably FILLER */
3138 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
3142 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transferring %d bytes in %d lblocks.\n",
3143 name, offset, transfer, blks);
3146 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3147 STp->timeout, MAX_RETRIES, 1);
3152 if ((STp->buffer)->syscall_result != 0) {
3155 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3156 name, SRpnt->sense[0], SRpnt->sense[2],
3157 SRpnt->sense[12], SRpnt->sense[13]);
3159 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3160 (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3161 (SRpnt->sense[2] & 0x0f) == NO_SENSE) {
3163 (STp->buffer)->buffer_bytes = 0;
3167 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3168 printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3172 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
3175 STp->first_frame_position++;
3177 (STp->buffer)->buffer_bytes = 0;
3181 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3187 /* Flush the tape buffer. The tape will be positioned correctly unless
3188 seek_next is true. */
3189 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next)
3191 struct st_partstat * STps;
3192 int backspace = 0, result = 0;
3194 char * name = tape_name(STp);
3198 * If there was a bus reset, block further access
3201 if( STp->pos_unknown)
3204 if (STp->ready != ST_READY)
3207 STps = &(STp->ps[STp->partition]);
3208 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
3209 STp->write_type = OS_WRITE_DATA;
3210 return osst_flush_write_buffer(STp, aSRpnt);
3212 if (STp->block_size == 0)
3216 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3219 if (!STp->can_bsr) {
3220 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3221 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3222 (STp->buffer)->buffer_bytes = 0;
3223 (STp->buffer)->read_pointer = 0;
3224 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3228 if (STps->eof == ST_FM_HIT) {
3229 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3231 STps->eof = ST_NOEOF;
3233 if (STps->drv_file >= 0)
3235 STps->drv_block = 0;
3238 if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3239 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3241 else if (STps->eof == ST_FM_HIT) {
3242 if (STps->drv_file >= 0)
3244 STps->drv_block = 0;
3245 STps->eof = ST_NOEOF;
3251 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous)
3253 unsigned char cmd[MAX_COMMAND_SIZE];
3254 struct osst_request * SRpnt;
3257 char * name = tape_name(STp);
3260 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3262 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3264 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3267 /* error recovery may have bumped us past the header partition */
3268 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3270 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3272 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3277 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3278 if (osst_recover_wait_frame(STp, aSRpnt, 1))
3281 // osst_build_stats(STp, &SRpnt);
3283 STp->ps[STp->partition].rw = ST_WRITING;
3284 STp->write_type = OS_WRITE_DATA;
3286 memset(cmd, 0, MAX_COMMAND_SIZE);
3289 cmd[4] = 1; /* one frame at a time... */
3290 blks = STp->buffer->buffer_bytes / STp->block_size;
3293 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3294 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3296 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3297 STp->logical_blk_num - blks, STp->block_size, blks);
3301 STp->write_pending = 1;
3303 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3304 MAX_RETRIES, synchronous);
3310 if (STp->buffer->syscall_result != 0) {
3313 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3315 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3316 (SRpnt->sense[2] & 0x40)) {
3317 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW)
3321 if (osst_write_error_recovery(STp, aSRpnt, 1))
3326 STp->first_frame_position++;
3334 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */
3335 static int do_door_lock(struct osst_tape * STp, int do_lock)
3340 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3343 retval = scsi_set_medium_removal(STp->device,
3344 do_lock ? SCSI_REMOVAL_PREVENT : SCSI_REMOVAL_ALLOW);
3346 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3348 STp->door_locked = ST_LOCK_FAILS;
3352 /* Set the internal state after reset */
3353 static void reset_state(struct osst_tape *STp)
3356 struct st_partstat *STps;
3358 STp->pos_unknown = 0;
3359 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3360 STps = &(STp->ps[i]);
3362 STps->eof = ST_NOEOF;
3364 STps->last_block_valid = 0;
3365 STps->drv_block = -1;
3366 STps->drv_file = -1;
3371 /* Entry points to osst */
3374 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3376 ssize_t total, retval = 0;
3377 ssize_t i, do_count, blks, transfer;
3378 int write_threshold;
3379 int doing_write = 0;
3380 const char __user * b_point;
3381 struct osst_request * SRpnt = NULL;
3382 struct st_modedef * STm;
3383 struct st_partstat * STps;
3384 struct osst_tape * STp = filp->private_data;
3385 char * name = tape_name(STp);
3388 if (mutex_lock_interruptible(&STp->lock))
3389 return (-ERESTARTSYS);
3392 * If we are in the middle of error recovery, don't let anyone
3393 * else try and use this device. Also, if error recovery fails, it
3394 * may try and take the device offline, in which case all further
3395 * access to the device is prohibited.
3397 if( !scsi_block_when_processing_errors(STp->device) ) {
3402 if (STp->ready != ST_READY) {
3403 if (STp->ready == ST_NO_TAPE)
3404 retval = (-ENOMEDIUM);
3409 STm = &(STp->modes[STp->current_mode]);
3410 if (!STm->defined) {
3418 * If there was a bus reset, block further access
3421 if (STp->pos_unknown) {
3428 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3434 if (STp->write_prot) {
3439 /* Write must be integral number of blocks */
3440 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3441 printk(KERN_ERR "%s:E: Write (%zd bytes) not multiple of tape block size (%d%c).\n",
3442 name, count, STp->block_size<1024?
3443 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3448 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3449 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3450 name, STp->first_frame_position);
3455 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3456 STp->door_locked = ST_LOCKED_AUTO;
3458 STps = &(STp->ps[STp->partition]);
3460 if (STps->rw == ST_READING) {
3462 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3463 STps->drv_file, STps->drv_block);
3465 retval = osst_flush_buffer(STp, &SRpnt, 0);
3470 if (STps->rw != ST_WRITING) {
3471 /* Are we totally rewriting this tape? */
3472 if (!STp->header_ok ||
3473 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3474 (STps->drv_file == 0 && STps->drv_block == 0)) {
3475 STp->wrt_pass_cntr++;
3477 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3478 name, STp->wrt_pass_cntr);
3480 osst_reset_header(STp, &SRpnt);
3481 STps->drv_file = STps->drv_block = 0;
3483 /* Do we know where we'll be writing on the tape? */
3485 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3486 STps->drv_file < 0 || STps->drv_block < 0) {
3487 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3488 STps->drv_file = STp->filemark_cnt;
3489 STps->drv_block = 0;
3492 /* We have no idea where the tape is positioned - give up */
3495 "%s:D: Cannot write at indeterminate position.\n", name);
3501 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3502 STp->filemark_cnt = STps->drv_file;
3503 STp->last_mark_ppos =
3504 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3506 "%s:W: Overwriting file %d with old write pass counter %d\n",
3507 name, STps->drv_file, STp->wrt_pass_cntr);
3509 "%s:W: may lead to stale data being accepted on reading back!\n",
3513 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3514 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3520 if (!STp->header_ok) {
3522 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3528 if ((STp->buffer)->writing) {
3529 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3530 osst_write_behind_check(STp);
3531 if ((STp->buffer)->syscall_result) {
3534 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3535 (STp->buffer)->midlevel_result);
3537 if ((STp->buffer)->midlevel_result == INT_MAX)
3538 STps->eof = ST_EOM_OK;
3540 STps->eof = ST_EOM_ERROR;
3543 if (STps->eof == ST_EOM_OK) {
3547 else if (STps->eof == ST_EOM_ERROR) {
3552 /* Check the buffer readability in cases where copy_user might catch
3553 the problems after some tape movement. */
3554 if ((copy_from_user(&i, buf, 1) != 0 ||
3555 copy_from_user(&i, buf + count - 1, 1) != 0)) {
3560 if (!STm->do_buffer_writes) {
3561 write_threshold = 1;
3564 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3565 if (!STm->do_async_writes)
3571 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3572 name, (int) count, STps->drv_file, STps->drv_block,
3573 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3576 while ((STp->buffer)->buffer_bytes + count > write_threshold)
3579 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3580 (STp->buffer)->buffer_bytes;
3581 if (do_count > count)
3584 i = append_to_buffer(b_point, STp->buffer, do_count);
3590 blks = do_count / STp->block_size;
3591 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3593 i = osst_write_frame(STp, &SRpnt, 1);
3595 if (i == (-ENOSPC)) {
3596 transfer = STp->buffer->writing; /* FIXME -- check this logic */
3597 if (transfer <= do_count) {
3598 *ppos += do_count - transfer;
3599 count -= do_count - transfer;
3600 if (STps->drv_block >= 0) {
3601 STps->drv_block += (do_count - transfer) / STp->block_size;
3603 STps->eof = ST_EOM_OK;
3604 retval = (-ENOSPC); /* EOM within current request */
3607 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3608 name, (int) transfer);
3612 STps->eof = ST_EOM_ERROR;
3613 STps->drv_block = (-1); /* Too cautious? */
3614 retval = (-EIO); /* EOM for old data */
3617 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3625 if (SRpnt != NULL) {
3626 osst_release_request(SRpnt);
3629 STp->buffer->buffer_bytes = 0;
3632 retval = total - count;
3637 b_point += do_count;
3639 if (STps->drv_block >= 0) {
3640 STps->drv_block += blks;
3642 STp->buffer->buffer_bytes = 0;
3644 } /* end while write threshold exceeded */
3648 i = append_to_buffer(b_point, STp->buffer, count);
3653 blks = count / STp->block_size;
3654 STp->logical_blk_num += blks;
3655 if (STps->drv_block >= 0) {
3656 STps->drv_block += blks;
3662 if (doing_write && (STp->buffer)->syscall_result != 0) {
3663 retval = (STp->buffer)->syscall_result;
3667 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3668 /* Schedule an asynchronous write */
3669 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3670 STp->block_size) * STp->block_size;
3671 STp->dirty = !((STp->buffer)->writing ==
3672 (STp->buffer)->buffer_bytes);
3674 i = osst_write_frame(STp, &SRpnt, 0);
3679 SRpnt = NULL; /* Prevent releasing this request! */
3681 STps->at_sm &= (total == 0);
3683 STps->eof = ST_NOEOF;
3688 if (SRpnt != NULL) osst_release_request(SRpnt);
3690 mutex_unlock(&STp->lock);
3697 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3699 ssize_t total, retval = 0;
3700 ssize_t i, transfer;
3702 struct st_modedef * STm;
3703 struct st_partstat * STps;
3704 struct osst_request * SRpnt = NULL;
3705 struct osst_tape * STp = filp->private_data;
3706 char * name = tape_name(STp);
3709 if (mutex_lock_interruptible(&STp->lock))
3710 return (-ERESTARTSYS);
3713 * If we are in the middle of error recovery, don't let anyone
3714 * else try and use this device. Also, if error recovery fails, it
3715 * may try and take the device offline, in which case all further
3716 * access to the device is prohibited.
3718 if( !scsi_block_when_processing_errors(STp->device) ) {
3723 if (STp->ready != ST_READY) {
3724 if (STp->ready == ST_NO_TAPE)
3725 retval = (-ENOMEDIUM);
3730 STm = &(STp->modes[STp->current_mode]);
3731 if (!STm->defined) {
3737 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3742 /* Must have initialized medium */
3743 if (!STp->header_ok) {
3748 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3749 STp->door_locked = ST_LOCKED_AUTO;
3751 STps = &(STp->ps[STp->partition]);
3752 if (STps->rw == ST_WRITING) {
3753 retval = osst_flush_buffer(STp, &SRpnt, 0);
3757 /* FIXME -- this may leave the tape without EOD and up2date headers */
3760 if ((count % STp->block_size) != 0) {
3762 "%s:W: Read (%zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3763 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3767 if (debugging && STps->eof != ST_NOEOF)
3768 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3769 STps->eof, (STp->buffer)->buffer_bytes);
3771 if ((STp->buffer)->buffer_bytes == 0 &&
3772 STps->eof >= ST_EOD_1) {
3773 if (STps->eof < ST_EOD) {
3778 retval = (-EIO); /* EOM or Blank Check */
3782 /* Check the buffer writability before any tape movement. Don't alter
3784 if (copy_from_user(&i, buf, 1) != 0 ||
3785 copy_to_user (buf, &i, 1) != 0 ||
3786 copy_from_user(&i, buf + count - 1, 1) != 0 ||
3787 copy_to_user (buf + count - 1, &i, 1) != 0) {
3792 /* Loop until enough data in buffer or a special condition found */
3793 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3795 /* Get new data if the buffer is empty */
3796 if ((STp->buffer)->buffer_bytes == 0) {
3797 if (STps->eof == ST_FM_HIT)
3799 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3800 if (special < 0) { /* No need to continue read */
3801 STp->frame_in_buffer = 0;
3807 /* Move the data from driver buffer to user buffer */
3808 if ((STp->buffer)->buffer_bytes > 0) {
3810 if (debugging && STps->eof != ST_NOEOF)
3811 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3812 STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total));
3814 /* force multiple of block size, note block_size may have been adjusted */
3815 transfer = (((STp->buffer)->buffer_bytes < count - total ?
3816 (STp->buffer)->buffer_bytes : count - total)/
3817 STp->block_size) * STp->block_size;
3819 if (transfer == 0) {
3821 "%s:W: Nothing can be transferred, requested %zd, tape block size (%d%c).\n",
3822 name, count, STp->block_size < 1024?
3823 STp->block_size:STp->block_size/1024,
3824 STp->block_size<1024?'b':'k');
3827 i = from_buffer(STp->buffer, buf, transfer);
3832 STp->logical_blk_num += transfer / STp->block_size;
3833 STps->drv_block += transfer / STp->block_size;
3839 if ((STp->buffer)->buffer_bytes == 0) {
3842 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3843 name, STp->frame_seq_number);
3845 STp->frame_in_buffer = 0;
3846 STp->frame_seq_number++; /* frame to look for next time */
3848 } /* for (total = 0, special = 0; total < count && !special; ) */
3850 /* Change the eof state if no data from tape or buffer */
3852 if (STps->eof == ST_FM_HIT) {
3853 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3854 STps->drv_block = 0;
3855 if (STps->drv_file >= 0)
3858 else if (STps->eof == ST_EOD_1) {
3859 STps->eof = ST_EOD_2;
3860 if (STps->drv_block > 0 && STps->drv_file >= 0)
3862 STps->drv_block = 0;
3864 else if (STps->eof == ST_EOD_2)
3867 else if (STps->eof == ST_FM)
3868 STps->eof = ST_NOEOF;
3873 if (SRpnt != NULL) osst_release_request(SRpnt);
3875 mutex_unlock(&STp->lock);
3881 /* Set the driver options */
3882 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3885 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3886 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3887 STm->do_read_ahead);
3889 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3890 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3892 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3893 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3894 STp->scsi2_logical);
3896 "%s:I: sysv: %d\n", name, STm->sysv);
3899 "%s:D: debugging: %d\n",
3905 static int osst_set_options(struct osst_tape *STp, long options)
3909 struct st_modedef * STm;
3910 char * name = tape_name(STp);
3912 STm = &(STp->modes[STp->current_mode]);
3913 if (!STm->defined) {
3914 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3918 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3919 name, STp->current_mode);
3923 code = options & MT_ST_OPTIONS;
3924 if (code == MT_ST_BOOLEANS) {
3925 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3926 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3927 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3928 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3929 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3930 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3931 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3932 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3933 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3934 if ((STp->device)->scsi_level >= SCSI_2)
3935 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3936 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3937 STm->sysv = (options & MT_ST_SYSV) != 0;
3939 debugging = (options & MT_ST_DEBUGGING) != 0;
3941 osst_log_options(STp, STm, name);
3943 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3944 value = (code == MT_ST_SETBOOLEANS);
3945 if ((options & MT_ST_BUFFER_WRITES) != 0)
3946 STm->do_buffer_writes = value;
3947 if ((options & MT_ST_ASYNC_WRITES) != 0)
3948 STm->do_async_writes = value;
3949 if ((options & MT_ST_DEF_WRITES) != 0)
3950 STm->defaults_for_writes = value;
3951 if ((options & MT_ST_READ_AHEAD) != 0)
3952 STm->do_read_ahead = value;
3953 if ((options & MT_ST_TWO_FM) != 0)
3954 STp->two_fm = value;
3955 if ((options & MT_ST_FAST_MTEOM) != 0)
3956 STp->fast_mteom = value;
3957 if ((options & MT_ST_AUTO_LOCK) != 0)
3958 STp->do_auto_lock = value;
3959 if ((options & MT_ST_CAN_BSR) != 0)
3960 STp->can_bsr = value;
3961 if ((options & MT_ST_NO_BLKLIMS) != 0)
3962 STp->omit_blklims = value;
3963 if ((STp->device)->scsi_level >= SCSI_2 &&
3964 (options & MT_ST_CAN_PARTITIONS) != 0)
3965 STp->can_partitions = value;
3966 if ((options & MT_ST_SCSI2LOGICAL) != 0)
3967 STp->scsi2_logical = value;
3968 if ((options & MT_ST_SYSV) != 0)
3971 if ((options & MT_ST_DEBUGGING) != 0)
3974 osst_log_options(STp, STm, name);
3976 else if (code == MT_ST_WRITE_THRESHOLD) {
3977 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3978 if (value < 1 || value > osst_buffer_size) {
3979 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3983 STp->write_threshold = value;
3984 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3987 else if (code == MT_ST_DEF_BLKSIZE) {
3988 value = (options & ~MT_ST_OPTIONS);
3989 if (value == ~MT_ST_OPTIONS) {
3990 STm->default_blksize = (-1);
3991 printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3994 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3995 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3999 STm->default_blksize = value;
4000 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
4001 name, STm->default_blksize);
4004 else if (code == MT_ST_TIMEOUTS) {
4005 value = (options & ~MT_ST_OPTIONS);
4006 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
4007 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
4008 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
4009 (value & ~MT_ST_SET_LONG_TIMEOUT));
4012 STp->timeout = value * HZ;
4013 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
4016 else if (code == MT_ST_DEF_OPTIONS) {
4017 code = (options & ~MT_ST_CLEAR_DEFAULT);
4018 value = (options & MT_ST_CLEAR_DEFAULT);
4019 if (code == MT_ST_DEF_DENSITY) {
4020 if (value == MT_ST_CLEAR_DEFAULT) {
4021 STm->default_density = (-1);
4022 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
4025 STm->default_density = value & 0xff;
4026 printk(KERN_INFO "%s:I: Density default set to %x\n",
4027 name, STm->default_density);
4030 else if (code == MT_ST_DEF_DRVBUFFER) {
4031 if (value == MT_ST_CLEAR_DEFAULT) {
4032 STp->default_drvbuffer = 0xff;
4033 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
4036 STp->default_drvbuffer = value & 7;
4037 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
4038 name, STp->default_drvbuffer);
4041 else if (code == MT_ST_DEF_COMPRESSION) {
4042 if (value == MT_ST_CLEAR_DEFAULT) {
4043 STm->default_compression = ST_DONT_TOUCH;
4044 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
4047 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
4048 printk(KERN_INFO "%s:I: Compression default set to %x\n",
4060 /* Internal ioctl function */
4061 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt,
4062 unsigned int cmd_in, unsigned long arg)
4066 int i, ioctl_result;
4068 unsigned char cmd[MAX_COMMAND_SIZE];
4069 struct osst_request * SRpnt = * aSRpnt;
4070 struct st_partstat * STps;
4071 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
4072 int datalen = 0, direction = DMA_NONE;
4073 char * name = tape_name(STp);
4075 if (STp->ready != ST_READY && cmd_in != MTLOAD) {
4076 if (STp->ready == ST_NO_TAPE)
4077 return (-ENOMEDIUM);
4081 timeout = STp->long_timeout;
4082 STps = &(STp->ps[STp->partition]);
4083 fileno = STps->drv_file;
4084 blkno = STps->drv_block;
4085 at_sm = STps->at_sm;
4086 frame_seq_numbr = STp->frame_seq_number;
4087 logical_blk_num = STp->logical_blk_num;
4089 memset(cmd, 0, MAX_COMMAND_SIZE);
4092 chg_eof = 0; /* Changed from the FSF after this */
4097 if (STp->linux_media)
4098 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
4100 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
4104 at_sm &= (arg == 0);
4108 chg_eof = 0; /* Changed from the FSF after this */
4113 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
4116 blkno = (-1); /* We can't know the block number */
4117 at_sm &= (arg == 0);
4124 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
4125 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
4127 if (cmd_in == MTFSR) {
4128 logical_blk_num += arg;
4129 if (blkno >= 0) blkno += arg;
4132 logical_blk_num -= arg;
4133 if (blkno >= 0) blkno -= arg;
4135 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
4136 fileno = STps->drv_file;
4137 blkno = STps->drv_block;
4138 at_sm &= (arg == 0);
4143 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4144 cmd[2] = (arg >> 16);
4145 cmd[3] = (arg >> 8);
4149 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4150 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4153 blkno = fileno = (-1);
4159 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4161 cmd[2] = (ltmp >> 16);
4162 cmd[3] = (ltmp >> 8);
4168 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4169 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4174 blkno = fileno = (-1);
4179 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4180 STp->write_type = OS_WRITE_DATA;
4181 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4186 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4188 for (i=0; i<arg; i++)
4189 ioctl_result |= osst_write_filemark(STp, &SRpnt);
4190 if (fileno >= 0) fileno += arg;
4191 if (blkno >= 0) blkno = 0;
4195 if (STp->write_prot)
4199 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
4200 if (cmd_in == MTWSM)
4202 cmd[2] = (arg >> 16);
4203 cmd[3] = (arg >> 8);
4205 timeout = STp->timeout;
4208 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4209 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4214 at_sm = (cmd_in == MTWSM);
4220 cmd[0] = START_STOP;
4221 cmd[1] = 1; /* Don't wait for completion */
4222 if (cmd_in == MTLOAD) {
4223 if (STp->ready == ST_NO_TAPE)
4224 cmd[4] = 4; /* open tray */
4226 cmd[4] = 1; /* load */
4228 if (cmd_in == MTRETEN)
4229 cmd[4] = 3; /* retension then mount */
4230 if (cmd_in == MTOFFL)
4231 cmd[4] = 4; /* rewind then eject */
4232 timeout = STp->timeout;
4237 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4240 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4243 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4246 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4251 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4256 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4258 return 0; /* Should do something ? */
4263 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4265 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4266 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4267 ioctl_result = -EIO;
4270 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4272 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4274 ioctl_result = -EIO;
4277 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4278 fileno = STp->filemark_cnt;
4283 if (STp->write_prot)
4285 ioctl_result = osst_reset_header(STp, &SRpnt);
4286 i = osst_write_eod(STp, &SRpnt);
4287 if (i < ioctl_result) ioctl_result = i;
4288 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4289 if (i < ioctl_result) ioctl_result = i;
4290 fileno = blkno = at_sm = 0 ;
4294 cmd[0] = REZERO_UNIT; /* rewind */
4298 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4300 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4303 case MTSETBLK: /* Set block length */
4304 if ((STps->drv_block == 0 ) &&
4306 ((STp->buffer)->buffer_bytes == 0) &&
4307 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4308 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4309 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4311 * Only allowed to change the block size if you opened the
4312 * device at the beginning of a file before writing anything.
4313 * Note, that when reading, changing block_size is futile,
4314 * as the size used when writing overrides it.
4316 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4317 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4318 name, STp->block_size);
4322 case MTSETDENSITY: /* Set tape density */
4323 case MTSETDRVBUFFER: /* Set drive buffering */
4324 case SET_DENS_AND_BLK: /* Set density and block size */
4326 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4327 return (-EIO); /* Not allowed if data in buffer */
4328 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4329 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4330 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4331 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4332 name, (int)(arg & MT_ST_BLKSIZE_MASK),
4333 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4336 return 0; /* FIXME silently ignore if block size didn't change */
4342 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4344 ioctl_result = (STp->buffer)->syscall_result;
4348 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4350 return ioctl_result;
4353 if (!ioctl_result) { /* SCSI command successful */
4354 STp->frame_seq_number = frame_seq_numbr;
4355 STp->logical_blk_num = logical_blk_num;
4361 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4364 if (!ioctl_result) { /* success */
4366 if (cmd_in == MTFSFM) {
4370 if (cmd_in == MTBSFM) {
4374 STps->drv_block = blkno;
4375 STps->drv_file = fileno;
4376 STps->at_sm = at_sm;
4378 if (cmd_in == MTEOM)
4380 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4381 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4383 STp->logical_blk_num++;
4384 STp->frame_seq_number++;
4385 STp->frame_in_buffer = 0;
4386 STp->buffer->read_pointer = 0;
4388 else if (cmd_in == MTFSF)
4389 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4391 STps->eof = ST_NOEOF;
4393 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4394 STp->rew_at_close = 0;
4395 else if (cmd_in == MTLOAD) {
4396 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4397 STp->ps[i].rw = ST_IDLE;
4398 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4403 if (cmd_in == MTREW) {
4404 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4405 if (ioctl_result > 0)
4409 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4410 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4411 STps->drv_file = STps->drv_block = -1;
4413 STps->drv_file = STps->drv_block = 0;
4414 STps->eof = ST_NOEOF;
4415 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4416 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4417 STps->drv_file = STps->drv_block = -1;
4419 STps->drv_file = STp->filemark_cnt;
4420 STps->drv_block = 0;
4423 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4424 STps->drv_file = STps->drv_block = (-1);
4425 STps->eof = ST_NOEOF;
4427 } else if (cmd_in == MTERASE) {
4429 } else if (SRpnt) { /* SCSI command was not completely successful. */
4430 if (SRpnt->sense[2] & 0x40) {
4431 STps->eof = ST_EOM_OK;
4432 STps->drv_block = 0;
4435 STps->eof = ST_NOEOF;
4437 if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK)
4440 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4441 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4445 return ioctl_result;
4449 /* Open the device */
4450 static int __os_scsi_tape_open(struct inode * inode, struct file * filp)
4452 unsigned short flags;
4453 int i, b_size, new_session = 0, retval = 0;
4454 unsigned char cmd[MAX_COMMAND_SIZE];
4455 struct osst_request * SRpnt = NULL;
4456 struct osst_tape * STp;
4457 struct st_modedef * STm;
4458 struct st_partstat * STps;
4460 int dev = TAPE_NR(inode);
4461 int mode = TAPE_MODE(inode);
4464 * We really want to do nonseekable_open(inode, filp); here, but some
4465 * versions of tar incorrectly call lseek on tapes and bail out if that
4466 * fails. So we disallow pread() and pwrite(), but permit lseeks.
4468 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
4470 write_lock(&os_scsi_tapes_lock);
4471 if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4472 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4473 write_unlock(&os_scsi_tapes_lock);
4477 name = tape_name(STp);
4480 write_unlock(&os_scsi_tapes_lock);
4482 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4486 if (scsi_device_get(STp->device)) {
4487 write_unlock(&os_scsi_tapes_lock);
4489 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4493 filp->private_data = STp;
4495 write_unlock(&os_scsi_tapes_lock);
4496 STp->rew_at_close = TAPE_REWIND(inode);
4498 if( !scsi_block_when_processing_errors(STp->device) ) {
4502 if (mode != STp->current_mode) {
4505 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4506 name, STp->current_mode, mode);
4509 STp->current_mode = mode;
4511 STm = &(STp->modes[STp->current_mode]);
4513 flags = filp->f_flags;
4514 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4516 STp->raw = TAPE_IS_RAW(inode);
4520 /* Allocate data segments for this device's tape buffer */
4521 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4522 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4523 retval = (-EOVERFLOW);
4526 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4527 for (i = 0, b_size = 0;
4528 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4529 b_size += STp->buffer->sg[i++].length);
4530 STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
4532 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4533 STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4534 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4535 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4538 STp->buffer->aux = NULL; /* this had better never happen! */
4539 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4543 STp->buffer->writing = 0;
4544 STp->buffer->syscall_result = 0;
4546 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4547 STps = &(STp->ps[i]);
4550 STp->ready = ST_READY;
4552 STp->nbr_waits = STp->nbr_finished = 0;
4555 memset (cmd, 0, MAX_COMMAND_SIZE);
4556 cmd[0] = TEST_UNIT_READY;
4558 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4560 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
4563 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4564 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4565 SRpnt->sense[12] == 4 ) {
4567 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]);
4569 if (filp->f_flags & O_NONBLOCK) {
4573 if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */
4574 memset (cmd, 0, MAX_COMMAND_SIZE);
4575 cmd[0] = START_STOP;
4578 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4579 STp->timeout, MAX_RETRIES, 1);
4581 osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
4583 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4584 (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4586 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4590 for (i=0; i < 10; i++) {
4592 memset (cmd, 0, MAX_COMMAND_SIZE);
4593 cmd[0] = TEST_UNIT_READY;
4595 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4596 STp->timeout, MAX_RETRIES, 1);
4597 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4598 (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
4602 STp->pos_unknown = 0;
4603 STp->partition = STp->new_partition = 0;
4604 if (STp->can_partitions)
4605 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4606 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4607 STps = &(STp->ps[i]);
4608 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4609 STps->eof = ST_NOEOF;
4611 STps->last_block_valid = 0;
4612 STps->drv_block = 0;
4613 STps->drv_file = 0 ;
4616 STp->recover_count = 0;
4617 STp->abort_count = 0;
4620 * if we have valid headers from before, and the drive/tape seem untouched,
4621 * open without reconfiguring and re-reading the headers
4623 if (!STp->buffer->syscall_result && STp->header_ok &&
4624 !SRpnt->result && SRpnt->sense[0] == 0) {
4626 memset(cmd, 0, MAX_COMMAND_SIZE);
4627 cmd[0] = MODE_SENSE;
4629 cmd[2] = VENDOR_IDENT_PAGE;
4630 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4632 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4634 if (STp->buffer->syscall_result ||
4635 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4636 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4637 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4638 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4640 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4641 STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4642 STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4643 STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4644 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4648 i = STp->first_frame_position;
4649 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4650 if (STp->door_locked == ST_UNLOCKED) {
4651 if (do_door_lock(STp, 1))
4652 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4654 STp->door_locked = ST_LOCKED_AUTO;
4656 if (!STp->frame_in_buffer) {
4657 STp->block_size = (STm->default_blksize > 0) ?
4658 STm->default_blksize : OS_DATA_SIZE;
4659 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4661 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4663 osst_release_request(SRpnt);
4667 if (i != STp->first_frame_position)
4668 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4669 name, i, STp->first_frame_position);
4675 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4676 (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) {
4678 memset(cmd, 0, MAX_COMMAND_SIZE);
4679 cmd[0] = MODE_SELECT;
4681 cmd[4] = 4 + MODE_HEADER_LENGTH;
4683 (STp->buffer)->b_data[0] = cmd[4] - 1;
4684 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4685 (STp->buffer)->b_data[2] = 0; /* Reserved */
4686 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4687 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4688 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4689 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4690 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4693 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4695 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4699 for (i=0; i < 10; i++) {
4701 memset (cmd, 0, MAX_COMMAND_SIZE);
4702 cmd[0] = TEST_UNIT_READY;
4704 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4705 STp->timeout, MAX_RETRIES, 1);
4706 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4707 (SRpnt->sense[2] & 0x0f) == NOT_READY)
4710 if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
4713 STp->pos_unknown = 0;
4714 STp->partition = STp->new_partition = 0;
4715 if (STp->can_partitions)
4716 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4717 for (j = 0; j < ST_NBR_PARTITIONS; j++) {
4718 STps = &(STp->ps[j]);
4720 STps->eof = ST_NOEOF;
4722 STps->last_block_valid = 0;
4723 STps->drv_block = 0;
4724 STps->drv_file = 0 ;
4731 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4732 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4734 if ((STp->buffer)->syscall_result != 0) {
4735 if ((STp->device)->scsi_level >= SCSI_2 &&
4736 (SRpnt->sense[0] & 0x70) == 0x70 &&
4737 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4738 SRpnt->sense[12] == 0x3a) { /* Check ASC */
4739 STp->ready = ST_NO_TAPE;
4741 STp->ready = ST_NOT_READY;
4742 osst_release_request(SRpnt);
4744 STp->density = 0; /* Clear the erroneous "residue" */
4745 STp->write_prot = 0;
4746 STp->block_size = 0;
4747 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4748 STp->partition = STp->new_partition = 0;
4749 STp->door_locked = ST_UNLOCKED;
4753 osst_configure_onstream(STp, &SRpnt);
4755 STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4756 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4757 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4758 STp->buffer->buffer_bytes =
4759 STp->buffer->read_pointer =
4760 STp->frame_in_buffer = 0;
4764 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4765 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4766 (STp->buffer)->buffer_blocks);
4769 if (STp->drv_write_prot) {
4770 STp->write_prot = 1;
4773 printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4775 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4781 if (new_session) { /* Change the drive parameters for the new mode */
4784 printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4786 STp->density_changed = STp->blksize_changed = 0;
4787 STp->compression_changed = 0;
4791 * properly position the tape and check the ADR headers
4793 if (STp->door_locked == ST_UNLOCKED) {
4794 if (do_door_lock(STp, 1))
4795 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4797 STp->door_locked = ST_LOCKED_AUTO;
4800 osst_analyze_headers(STp, &SRpnt);
4802 osst_release_request(SRpnt);
4809 osst_release_request(SRpnt);
4810 normalize_buffer(STp->buffer);
4813 scsi_device_put(STp->device);
4818 /* BKL pushdown: spaghetti avoidance wrapper */
4819 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4823 mutex_lock(&osst_int_mutex);
4824 ret = __os_scsi_tape_open(inode, filp);
4825 mutex_unlock(&osst_int_mutex);
4831 /* Flush the tape buffer before close */
4832 static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
4834 int result = 0, result2;
4835 struct osst_tape * STp = filp->private_data;
4836 struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4837 struct st_partstat * STps = &(STp->ps[STp->partition]);
4838 struct osst_request * SRpnt = NULL;
4839 char * name = tape_name(STp);
4841 if (file_count(filp) > 1)
4844 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4845 STp->write_type = OS_WRITE_DATA;
4846 result = osst_flush_write_buffer(STp, &SRpnt);
4847 if (result != 0 && result != (-ENOSPC))
4850 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4854 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4855 name, (long)(filp->f_pos));
4856 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4857 name, STp->nbr_waits, STp->nbr_finished);
4860 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4863 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4864 name, 1+STp->two_fm);
4867 else if (!STp->rew_at_close) {
4868 STps = &(STp->ps[STp->partition]);
4869 if (!STm->sysv || STps->rw != ST_READING) {
4871 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4872 else if (STps->eof == ST_FM_HIT) {
4873 result = cross_eof(STp, &SRpnt, 0);
4875 if (STps->drv_file >= 0)
4877 STps->drv_block = 0;
4881 STps->eof = ST_NOEOF;
4884 else if ((STps->eof == ST_NOEOF &&
4885 !(result = cross_eof(STp, &SRpnt, 1))) ||
4886 STps->eof == ST_FM_HIT) {
4887 if (STps->drv_file >= 0)
4889 STps->drv_block = 0;
4895 if (STp->rew_at_close) {
4896 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4897 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4898 if (result == 0 && result2 < 0)
4901 if (SRpnt) osst_release_request(SRpnt);
4903 if (STp->abort_count || STp->recover_count) {
4904 printk(KERN_INFO "%s:I:", name);
4905 if (STp->abort_count)
4906 printk(" %d unrecovered errors", STp->abort_count);
4907 if (STp->recover_count)
4908 printk(" %d recovered errors", STp->recover_count);
4909 if (STp->write_count)
4910 printk(" in %d frames written", STp->write_count);
4911 if (STp->read_count)
4912 printk(" in %d frames read", STp->read_count);
4914 STp->recover_count = 0;
4915 STp->abort_count = 0;
4917 STp->write_count = 0;
4918 STp->read_count = 0;
4924 /* Close the device and release it */
4925 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4928 struct osst_tape * STp = filp->private_data;
4930 if (STp->door_locked == ST_LOCKED_AUTO)
4931 do_door_lock(STp, 0);
4936 normalize_buffer(STp->buffer);
4937 write_lock(&os_scsi_tapes_lock);
4939 write_unlock(&os_scsi_tapes_lock);
4941 scsi_device_put(STp->device);
4947 /* The ioctl command */
4948 static long osst_ioctl(struct file * file,
4949 unsigned int cmd_in, unsigned long arg)
4951 int i, cmd_nr, cmd_type, blk, retval = 0;
4952 struct st_modedef * STm;
4953 struct st_partstat * STps;
4954 struct osst_request * SRpnt = NULL;
4955 struct osst_tape * STp = file->private_data;
4956 char * name = tape_name(STp);
4957 void __user * p = (void __user *)arg;
4959 mutex_lock(&osst_int_mutex);
4960 if (mutex_lock_interruptible(&STp->lock)) {
4961 mutex_unlock(&osst_int_mutex);
4962 return -ERESTARTSYS;
4966 if (debugging && !STp->in_use) {
4967 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4972 STm = &(STp->modes[STp->current_mode]);
4973 STps = &(STp->ps[STp->partition]);
4976 * If we are in the middle of error recovery, don't let anyone
4977 * else try and use this device. Also, if error recovery fails, it
4978 * may try and take the device offline, in which case all further
4979 * access to the device is prohibited.
4981 retval = scsi_ioctl_block_when_processing_errors(STp->device, cmd_in,
4982 file->f_flags & O_NDELAY);
4986 cmd_type = _IOC_TYPE(cmd_in);
4987 cmd_nr = _IOC_NR(cmd_in);
4989 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4990 cmd_type, cmd_nr, STp->raw?"raw":"normal");
4992 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4996 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
5001 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
5007 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
5008 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
5013 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
5018 if (!STp->pos_unknown) {
5020 if (STps->eof == ST_FM_HIT) {
5021 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
5023 if (STps->drv_file >= 0)
5024 STps->drv_file += 1;
5026 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
5028 if (STps->drv_file >= 0)
5029 STps->drv_file += 1;
5033 if (mtc.mt_op == MTSEEK) {
5034 /* Old position must be restored if partition will be changed */
5035 i = !STp->can_partitions || (STp->new_partition != STp->partition);
5038 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
5039 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
5040 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
5041 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
5042 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
5043 mtc.mt_op == MTCOMPRESSION;
5045 i = osst_flush_buffer(STp, &SRpnt, i);
5053 * If there was a bus reset, block further access
5054 * to this device. If the user wants to rewind the tape,
5055 * then reset the flag and allow access again.
5057 if(mtc.mt_op != MTREW &&
5058 mtc.mt_op != MTOFFL &&
5059 mtc.mt_op != MTRETEN &&
5060 mtc.mt_op != MTERASE &&
5061 mtc.mt_op != MTSEEK &&
5062 mtc.mt_op != MTEOM) {
5067 /* remove this when the midlevel properly clears was_reset */
5068 STp->device->was_reset = 0;
5071 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK &&
5072 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
5073 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER &&
5074 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART &&
5075 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) {
5078 * The user tells us to move to another position on the tape.
5079 * If we were appending to the tape content, that would leave
5080 * the tape without proper end, in that case write EOD and
5081 * update the header to reflect its position.
5084 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
5085 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
5086 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
5087 STp->logical_blk_num, STps->drv_file, STps->drv_block );
5089 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
5090 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
5091 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
5092 i = osst_write_trailer(STp, &SRpnt,
5093 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
5095 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
5096 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
5097 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
5107 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
5108 do_door_lock(STp, 0); /* Ignore result! */
5110 if (mtc.mt_op == MTSETDRVBUFFER &&
5111 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
5112 retval = osst_set_options(STp, mtc.mt_count);
5116 if (mtc.mt_op == MTSETPART) {
5117 if (mtc.mt_count >= STp->nbr_partitions)
5120 STp->new_partition = mtc.mt_count;
5126 if (mtc.mt_op == MTMKPART) {
5127 if (!STp->can_partitions) {
5131 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
5132 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
5136 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5137 STp->ps[i].rw = ST_IDLE;
5138 STp->ps[i].at_sm = 0;
5139 STp->ps[i].last_block_valid = 0;
5141 STp->partition = STp->new_partition = 0;
5142 STp->nbr_partitions = 1; /* Bad guess ?-) */
5143 STps->drv_block = STps->drv_file = 0;
5148 if (mtc.mt_op == MTSEEK) {
5150 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
5152 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
5153 if (!STp->can_partitions)
5154 STp->ps[0].rw = ST_IDLE;
5159 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
5160 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
5165 cross_eof(STp, &SRpnt, 0);
5167 if (mtc.mt_op == MTCOMPRESSION)
5168 retval = -EINVAL; /* OnStream drives don't have compression hardware */
5170 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5171 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5172 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5176 if (!STm->defined) {
5181 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5186 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
5187 struct mtget mt_status;
5189 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
5194 mt_status.mt_type = MT_ISONSTREAM_SC;
5195 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
5196 mt_status.mt_dsreg =
5197 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
5198 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
5199 mt_status.mt_blkno = STps->drv_block;
5200 mt_status.mt_fileno = STps->drv_file;
5201 if (STp->block_size != 0) {
5202 if (STps->rw == ST_WRITING)
5203 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
5204 else if (STps->rw == ST_READING)
5205 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
5206 STp->block_size - 1) / STp->block_size;
5209 mt_status.mt_gstat = 0;
5210 if (STp->drv_write_prot)
5211 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
5212 if (mt_status.mt_blkno == 0) {
5213 if (mt_status.mt_fileno == 0)
5214 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
5216 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
5218 mt_status.mt_resid = STp->partition;
5219 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
5220 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
5221 else if (STps->eof >= ST_EOM_OK)
5222 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
5223 if (STp->density == 1)
5224 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
5225 else if (STp->density == 2)
5226 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
5227 else if (STp->density == 3)
5228 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
5229 if (STp->ready == ST_READY)
5230 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
5231 if (STp->ready == ST_NO_TAPE)
5232 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
5234 mt_status.mt_gstat |= GMT_SM(0xffffffff);
5235 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
5236 STp->drv_buffer != 0)
5237 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
5239 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
5245 STp->recover_erreg = 0; /* Clear after read */
5248 } /* End of MTIOCGET */
5250 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5251 struct mtpos mt_pos;
5253 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5258 blk = osst_get_frame_position(STp, &SRpnt);
5260 blk = osst_get_sector(STp, &SRpnt);
5265 mt_pos.mt_blkno = blk;
5266 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5271 if (SRpnt) osst_release_request(SRpnt);
5273 mutex_unlock(&STp->lock);
5275 retval = scsi_ioctl(STp->device, cmd_in, p);
5276 mutex_unlock(&osst_int_mutex);
5280 if (SRpnt) osst_release_request(SRpnt);
5282 mutex_unlock(&STp->lock);
5283 mutex_unlock(&osst_int_mutex);
5288 #ifdef CONFIG_COMPAT
5289 static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg)
5291 struct osst_tape *STp = file->private_data;
5292 struct scsi_device *sdev = STp->device;
5293 int ret = -ENOIOCTLCMD;
5294 if (sdev->host->hostt->compat_ioctl) {
5296 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
5305 /* Memory handling routines */
5307 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5308 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5312 struct osst_buffer *tb;
5314 if (from_initialization)
5315 priority = GFP_ATOMIC;
5317 priority = GFP_KERNEL;
5319 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5320 tb = kzalloc(i, priority);
5322 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5326 tb->sg_segs = tb->orig_sg_segs = 0;
5327 tb->use_sg = max_sg;
5330 tb->buffer_size = 0;
5334 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5335 i, max_sg, need_dma);
5340 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5341 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5343 int segs, nbr, max_segs, b_size, order, got;
5346 if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5349 if (STbuffer->sg_segs) {
5350 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5351 normalize_buffer(STbuffer);
5353 /* See how many segments we can use -- need at least two */
5354 nbr = max_segs = STbuffer->use_sg;
5358 priority = GFP_KERNEL /* | __GFP_NOWARN */;
5360 priority |= GFP_DMA;
5362 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5363 big enough to reach the goal (code assumes no segments in place) */
5364 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5365 struct page *page = alloc_pages(priority, order);
5367 STbuffer->sg[0].offset = 0;
5369 sg_set_page(&STbuffer->sg[0], page, b_size, 0);
5370 STbuffer->b_data = page_address(page);
5374 if (sg_page(&STbuffer->sg[0]) == NULL) {
5375 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5378 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5379 for (segs=STbuffer->sg_segs=1, got=b_size;
5380 segs < max_segs && got < OS_FRAME_SIZE; ) {
5381 struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5382 STbuffer->sg[segs].offset = 0;
5384 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5387 STbuffer->buffer_size = got;
5389 normalize_buffer(STbuffer);
5392 sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0);
5393 got += STbuffer->sg[segs].length;
5394 STbuffer->buffer_size = got;
5395 STbuffer->sg_segs = ++segs;
5400 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5401 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5403 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5404 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5405 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5413 /* Release the segments */
5414 static void normalize_buffer(struct osst_buffer *STbuffer)
5416 int i, order, b_size;
5418 for (i=0; i < STbuffer->sg_segs; i++) {
5420 for (b_size = PAGE_SIZE, order = 0;
5421 b_size < STbuffer->sg[i].length;
5422 b_size *= 2, order++);
5424 __free_pages(sg_page(&STbuffer->sg[i]), order);
5425 STbuffer->buffer_size -= STbuffer->sg[i].length;
5428 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5429 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5430 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5432 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5436 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5437 negative error code. */
5438 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
5440 int i, cnt, res, offset;
5442 for (i=0, offset=st_bp->buffer_bytes;
5443 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5444 offset -= st_bp->sg[i].length;
5445 if (i == st_bp->sg_segs) { /* Should never happen */
5446 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5449 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5450 cnt = st_bp->sg[i].length - offset < do_count ?
5451 st_bp->sg[i].length - offset : do_count;
5452 res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
5456 st_bp->buffer_bytes += cnt;
5460 if (do_count) { /* Should never happen */
5461 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5469 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5470 negative error code. */
5471 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
5473 int i, cnt, res, offset;
5475 for (i=0, offset=st_bp->read_pointer;
5476 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5477 offset -= st_bp->sg[i].length;
5478 if (i == st_bp->sg_segs) { /* Should never happen */
5479 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5482 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5483 cnt = st_bp->sg[i].length - offset < do_count ?
5484 st_bp->sg[i].length - offset : do_count;
5485 res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
5489 st_bp->buffer_bytes -= cnt;
5490 st_bp->read_pointer += cnt;
5494 if (do_count) { /* Should never happen */
5495 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5501 /* Sets the tail of the buffer after fill point to zero.
5502 Returns zero (success) or negative error code. */
5503 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
5505 int i, offset, do_count, cnt;
5507 for (i = 0, offset = st_bp->buffer_bytes;
5508 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5509 offset -= st_bp->sg[i].length;
5510 if (i == st_bp->sg_segs) { /* Should never happen */
5511 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5514 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5515 i < st_bp->sg_segs && do_count > 0; i++) {
5516 cnt = st_bp->sg[i].length - offset < do_count ?
5517 st_bp->sg[i].length - offset : do_count ;
5518 memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
5522 if (do_count) { /* Should never happen */
5523 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5529 /* Copy a osst 32K chunk of memory into the buffer.
5530 Returns zero (success) or negative error code. */
5531 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5533 int i, cnt, do_count = OS_DATA_SIZE;
5535 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5536 cnt = st_bp->sg[i].length < do_count ?
5537 st_bp->sg[i].length : do_count ;
5538 memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
5542 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5543 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5550 /* Copy a osst 32K chunk of memory from the buffer.
5551 Returns zero (success) or negative error code. */
5552 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5554 int i, cnt, do_count = OS_DATA_SIZE;
5556 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5557 cnt = st_bp->sg[i].length < do_count ?
5558 st_bp->sg[i].length : do_count ;
5559 memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
5563 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5564 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5572 /* Module housekeeping */
5574 static void validate_options (void)
5577 osst_max_dev = max_dev;
5578 if (write_threshold_kbs > 0)
5579 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5580 if (osst_write_threshold > osst_buffer_size)
5581 osst_write_threshold = osst_buffer_size;
5582 if (max_sg_segs >= OSST_FIRST_SG)
5583 osst_max_sg_segs = max_sg_segs;
5585 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5586 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5591 /* Set the boot options. Syntax: osst=xxx,yyy,...
5592 where xxx is write threshold in 1024 byte blocks,
5593 and yyy is number of s/g segments to use. */
5594 static int __init osst_setup (char *str)
5599 stp = get_options(str, ARRAY_SIZE(ints), ints);
5602 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5603 *parms[i].val = ints[i + 1];
5605 while (stp != NULL) {
5606 for (i = 0; i < ARRAY_SIZE(parms); i++) {
5607 int len = strlen(parms[i].name);
5608 if (!strncmp(stp, parms[i].name, len) &&
5609 (*(stp + len) == ':' || *(stp + len) == '=')) {
5611 simple_strtoul(stp + len + 1, NULL, 0);
5615 if (i >= ARRAY_SIZE(parms))
5616 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5618 stp = strchr(stp, ',');
5627 __setup("osst=", osst_setup);
5631 static const struct file_operations osst_fops = {
5632 .owner = THIS_MODULE,
5634 .write = osst_write,
5635 .unlocked_ioctl = osst_ioctl,
5636 #ifdef CONFIG_COMPAT
5637 .compat_ioctl = osst_compat_ioctl,
5639 .open = os_scsi_tape_open,
5640 .flush = os_scsi_tape_flush,
5641 .release = os_scsi_tape_close,
5642 .llseek = noop_llseek,
5645 static int osst_supports(struct scsi_device * SDp)
5647 struct osst_support_data {
5651 char *driver_hint; /* Name of the correct driver, NULL if unknown */
5654 static struct osst_support_data support_list[] = {
5655 /* {"XXX", "Yy-", "", NULL}, example */
5659 struct osst_support_data *rp;
5661 /* We are willing to drive OnStream SC-x0 as well as the
5662 * * IDE, ParPort, FireWire, USB variants, if accessible by
5663 * * emulation layer (ide-scsi, usb-storage, ...) */
5665 for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5666 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5667 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5668 !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5674 * sysfs support for osst driver parameter information
5677 static ssize_t version_show(struct device_driver *ddd, char *buf)
5679 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
5682 static DRIVER_ATTR_RO(version);
5684 static int osst_create_sysfs_files(struct device_driver *sysfs)
5686 return driver_create_file(sysfs, &driver_attr_version);
5689 static void osst_remove_sysfs_files(struct device_driver *sysfs)
5691 driver_remove_file(sysfs, &driver_attr_version);
5695 * sysfs support for accessing ADR header information
5698 static ssize_t osst_adr_rev_show(struct device *dev,
5699 struct device_attribute *attr, char *buf)
5701 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5704 if (STp && STp->header_ok && STp->linux_media)
5705 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
5709 DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
5711 static ssize_t osst_linux_media_version_show(struct device *dev,
5712 struct device_attribute *attr,
5715 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5718 if (STp && STp->header_ok && STp->linux_media)
5719 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
5723 DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
5725 static ssize_t osst_capacity_show(struct device *dev,
5726 struct device_attribute *attr, char *buf)
5728 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5731 if (STp && STp->header_ok && STp->linux_media)
5732 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
5736 DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
5738 static ssize_t osst_first_data_ppos_show(struct device *dev,
5739 struct device_attribute *attr,
5742 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5745 if (STp && STp->header_ok && STp->linux_media)
5746 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
5750 DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
5752 static ssize_t osst_eod_frame_ppos_show(struct device *dev,
5753 struct device_attribute *attr,
5756 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5759 if (STp && STp->header_ok && STp->linux_media)
5760 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
5764 DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
5766 static ssize_t osst_filemark_cnt_show(struct device *dev,
5767 struct device_attribute *attr, char *buf)
5769 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5772 if (STp && STp->header_ok && STp->linux_media)
5773 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
5777 DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5779 static struct class *osst_sysfs_class;
5781 static int osst_sysfs_init(void)
5783 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
5784 if (IS_ERR(osst_sysfs_class)) {
5785 printk(KERN_ERR "osst :W: Unable to register sysfs class\n");
5786 return PTR_ERR(osst_sysfs_class);
5792 static void osst_sysfs_destroy(dev_t dev)
5794 device_destroy(osst_sysfs_class, dev);
5797 static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5799 struct device *osst_member;
5802 osst_member = device_create(osst_sysfs_class, device, dev, STp,
5804 if (IS_ERR(osst_member)) {
5805 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5806 return PTR_ERR(osst_member);
5809 err = device_create_file(osst_member, &dev_attr_ADR_rev);
5812 err = device_create_file(osst_member, &dev_attr_media_version);
5815 err = device_create_file(osst_member, &dev_attr_capacity);
5818 err = device_create_file(osst_member, &dev_attr_BOT_frame);
5821 err = device_create_file(osst_member, &dev_attr_EOD_frame);
5824 err = device_create_file(osst_member, &dev_attr_file_count);
5831 osst_sysfs_destroy(dev);
5835 static void osst_sysfs_cleanup(void)
5837 class_destroy(osst_sysfs_class);
5841 * osst startup / cleanup code
5844 static int osst_probe(struct device *dev)
5846 struct scsi_device * SDp = to_scsi_device(dev);
5847 struct osst_tape * tpnt;
5848 struct st_modedef * STm;
5849 struct st_partstat * STps;
5850 struct osst_buffer * buffer;
5851 struct gendisk * drive;
5852 int i, dev_num, err = -ENODEV;
5854 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5857 drive = alloc_disk(1);
5859 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5863 /* if this is the first attach, build the infrastructure */
5864 write_lock(&os_scsi_tapes_lock);
5865 if (os_scsi_tapes == NULL) {
5866 os_scsi_tapes = kmalloc_array(osst_max_dev,
5867 sizeof(struct osst_tape *),
5869 if (os_scsi_tapes == NULL) {
5870 write_unlock(&os_scsi_tapes_lock);
5871 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5874 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5877 if (osst_nr_dev >= osst_max_dev) {
5878 write_unlock(&os_scsi_tapes_lock);
5879 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5883 /* find a free minor number */
5884 for (i = 0; i < osst_max_dev && os_scsi_tapes[i]; i++)
5886 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5889 /* allocate a struct osst_tape for this device */
5890 tpnt = kzalloc(sizeof(struct osst_tape), GFP_ATOMIC);
5892 write_unlock(&os_scsi_tapes_lock);
5893 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5897 /* allocate a buffer for this device */
5898 i = SDp->host->sg_tablesize;
5899 if (osst_max_sg_segs < i)
5900 i = osst_max_sg_segs;
5901 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
5902 if (buffer == NULL) {
5903 write_unlock(&os_scsi_tapes_lock);
5904 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5908 os_scsi_tapes[dev_num] = tpnt;
5909 tpnt->buffer = buffer;
5911 drive->private_data = &tpnt->driver;
5912 sprintf(drive->disk_name, "osst%d", dev_num);
5913 tpnt->driver = &osst_template;
5914 tpnt->drive = drive;
5916 tpnt->capacity = 0xfffff;
5918 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
5919 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5921 tpnt->do_auto_lock = OSST_AUTO_LOCK;
5922 tpnt->can_bsr = OSST_IN_FILE_POS;
5923 tpnt->can_partitions = 0;
5924 tpnt->two_fm = OSST_TWO_FM;
5925 tpnt->fast_mteom = OSST_FAST_MTEOM;
5926 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5927 tpnt->write_threshold = osst_write_threshold;
5928 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5929 tpnt->partition = 0;
5930 tpnt->new_partition = 0;
5931 tpnt->nbr_partitions = 0;
5932 tpnt->min_block = 512;
5933 tpnt->max_block = OS_DATA_SIZE;
5934 tpnt->timeout = OSST_TIMEOUT;
5935 tpnt->long_timeout = OSST_LONG_TIMEOUT;
5937 /* Recognize OnStream tapes */
5938 /* We don't need to test for OnStream, as this has been done in detect () */
5939 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5940 tpnt->omit_blklims = 1;
5942 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5943 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5944 tpnt->frame_in_buffer = 0;
5945 tpnt->header_ok = 0;
5946 tpnt->linux_media = 0;
5947 tpnt->header_cache = NULL;
5949 for (i=0; i < ST_NBR_MODES; i++) {
5950 STm = &(tpnt->modes[i]);
5952 STm->sysv = OSST_SYSV;
5953 STm->defaults_for_writes = 0;
5954 STm->do_async_writes = OSST_ASYNC_WRITES;
5955 STm->do_buffer_writes = OSST_BUFFER_WRITES;
5956 STm->do_read_ahead = OSST_READ_AHEAD;
5957 STm->default_compression = ST_DONT_TOUCH;
5958 STm->default_blksize = 512;
5959 STm->default_density = (-1); /* No forced density */
5962 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5963 STps = &(tpnt->ps[i]);
5965 STps->eof = ST_NOEOF;
5967 STps->last_block_valid = 0;
5968 STps->drv_block = (-1);
5969 STps->drv_file = (-1);
5972 tpnt->current_mode = 0;
5973 tpnt->modes[0].defined = 1;
5974 tpnt->modes[2].defined = 1;
5975 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
5977 mutex_init(&tpnt->lock);
5979 write_unlock(&os_scsi_tapes_lock);
5985 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5987 goto out_free_buffer;
5989 /* No-rewind entry */
5990 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5991 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5993 goto out_free_sysfs1;
5996 sdev_printk(KERN_INFO, SDp,
5997 "osst :I: Attached OnStream %.5s tape as %s\n",
5998 SDp->model, tape_name(tpnt));
6003 osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num));
6011 static int osst_remove(struct device *dev)
6013 struct scsi_device * SDp = to_scsi_device(dev);
6014 struct osst_tape * tpnt;
6017 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
6020 write_lock(&os_scsi_tapes_lock);
6021 for(i=0; i < osst_max_dev; i++) {
6022 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
6023 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
6024 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
6025 tpnt->device = NULL;
6026 put_disk(tpnt->drive);
6027 os_scsi_tapes[i] = NULL;
6029 write_unlock(&os_scsi_tapes_lock);
6030 vfree(tpnt->header_cache);
6032 normalize_buffer(tpnt->buffer);
6033 kfree(tpnt->buffer);
6039 write_unlock(&os_scsi_tapes_lock);
6043 static int __init init_osst(void)
6047 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
6051 err = osst_sysfs_init();
6055 err = register_chrdev(OSST_MAJOR, "osst", &osst_fops);
6057 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
6061 err = scsi_register_driver(&osst_template.gendrv);
6063 goto err_out_chrdev;
6065 err = osst_create_sysfs_files(&osst_template.gendrv);
6067 goto err_out_scsidrv;
6072 scsi_unregister_driver(&osst_template.gendrv);
6074 unregister_chrdev(OSST_MAJOR, "osst");
6076 osst_sysfs_cleanup();
6080 static void __exit exit_osst (void)
6083 struct osst_tape * STp;
6085 osst_remove_sysfs_files(&osst_template.gendrv);
6086 scsi_unregister_driver(&osst_template.gendrv);
6087 unregister_chrdev(OSST_MAJOR, "osst");
6088 osst_sysfs_cleanup();
6090 if (os_scsi_tapes) {
6091 for (i=0; i < osst_max_dev; ++i) {
6092 if (!(STp = os_scsi_tapes[i])) continue;
6093 /* This is defensive, supposed to happen during detach */
6094 vfree(STp->header_cache);
6096 normalize_buffer(STp->buffer);
6099 put_disk(STp->drive);
6102 kfree(os_scsi_tapes);
6104 printk(KERN_INFO "osst :I: Unloaded.\n");
6107 module_init(init_osst);
6108 module_exit(exit_osst);