2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
3 file Documentation/scsi/st.txt for more information.
7 OnStream SCSI Tape support (osst) cloned from st.c by
8 Willem Riede (osst@riede.org) Feb 2000
9 Fixes ... Kurt Garloff <garloff@suse.de> Mar 2000
11 Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
12 Contribution and ideas from several people including (in alphabetical
13 order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
14 Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
16 Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede
19 $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
21 Microscopic alterations - Rik Ling, 2000/12/21
22 Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
23 Some small formal changes - aeb, 950809
26 static const char * cvsid
= "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $";
27 static const char * osst_version
= "0.99.4";
29 /* The "failure to reconnect" firmware bug */
30 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
31 #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/
32 #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
34 #include <linux/module.h>
37 #include <linux/kernel.h>
38 #include <linux/sched.h>
39 #include <linux/proc_fs.h>
41 #include <linux/init.h>
42 #include <linux/string.h>
43 #include <linux/errno.h>
44 #include <linux/mtio.h>
45 #include <linux/ioctl.h>
46 #include <linux/fcntl.h>
47 #include <linux/spinlock.h>
48 #include <linux/vmalloc.h>
49 #include <linux/blkdev.h>
50 #include <linux/moduleparam.h>
51 #include <linux/delay.h>
52 #include <linux/jiffies.h>
53 #include <asm/uaccess.h>
55 #include <asm/system.h>
57 /* The driver prints some debugging information on the console if DEBUG
58 is defined and non-zero. */
61 /* The message level for the debug messages is currently set to KERN_NOTICE
62 so that people can easily see the messages. Later when the debugging messages
63 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
64 #define OSST_DEB_MSG KERN_NOTICE
66 #include <scsi/scsi.h>
67 #include <scsi/scsi_dbg.h>
68 #include <scsi/scsi_device.h>
69 #include <scsi/scsi_driver.h>
70 #include <scsi/scsi_eh.h>
71 #include <scsi/scsi_host.h>
72 #include <scsi/scsi_ioctl.h>
74 #define ST_KILOBYTE 1024
78 #include "osst_options.h"
79 #include "osst_detect.h"
81 static int max_dev
= 0;
82 static int write_threshold_kbs
= 0;
83 static int max_sg_segs
= 0;
86 MODULE_AUTHOR("Willem Riede");
87 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
88 MODULE_LICENSE("GPL");
89 MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR
);
90 MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE
);
92 module_param(max_dev
, int, 0444);
93 MODULE_PARM_DESC(max_dev
, "Maximum number of OnStream Tape Drives to attach (4)");
95 module_param(write_threshold_kbs
, int, 0644);
96 MODULE_PARM_DESC(write_threshold_kbs
, "Asynchronous write threshold (KB; 32)");
98 module_param(max_sg_segs
, int, 0644);
99 MODULE_PARM_DESC(max_sg_segs
, "Maximum number of scatter/gather segments to use (9)");
101 static struct osst_dev_parm
{
104 } parms
[] __initdata
= {
105 { "max_dev", &max_dev
},
106 { "write_threshold_kbs", &write_threshold_kbs
},
107 { "max_sg_segs", &max_sg_segs
}
111 /* Some default definitions have been moved to osst_options.h */
112 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
113 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
115 /* The buffer size should fit into the 24 bits for length in the
116 6-byte SCSI read and write commands. */
117 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
118 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
122 static int debugging
= 1;
123 /* uncomment define below to test error recovery */
124 // #define OSST_INJECT_ERRORS 1
127 /* Do not retry! The drive firmware already retries when appropriate,
128 and when it tries to tell us something, we had better listen... */
129 #define MAX_RETRIES 0
131 #define NO_TAPE NOT_READY
133 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
134 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
135 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
137 #define OSST_TIMEOUT (200 * HZ)
138 #define OSST_LONG_TIMEOUT (1800 * HZ)
140 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
141 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
142 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
143 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
145 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
147 #define SET_DENS_AND_BLK 0x10001
149 static int osst_buffer_size
= OSST_BUFFER_SIZE
;
150 static int osst_write_threshold
= OSST_WRITE_THRESHOLD
;
151 static int osst_max_sg_segs
= OSST_MAX_SG
;
152 static int osst_max_dev
= OSST_MAX_TAPES
;
153 static int osst_nr_dev
;
155 static struct osst_tape
**os_scsi_tapes
= NULL
;
156 static DEFINE_RWLOCK(os_scsi_tapes_lock
);
158 static int modes_defined
= 0;
160 static struct osst_buffer
*new_tape_buffer(int, int, int);
161 static int enlarge_buffer(struct osst_buffer
*, int);
162 static void normalize_buffer(struct osst_buffer
*);
163 static int append_to_buffer(const char __user
*, struct osst_buffer
*, int);
164 static int from_buffer(struct osst_buffer
*, char __user
*, int);
165 static int osst_zero_buffer_tail(struct osst_buffer
*);
166 static int osst_copy_to_buffer(struct osst_buffer
*, unsigned char *);
167 static int osst_copy_from_buffer(struct osst_buffer
*, unsigned char *);
169 static int osst_probe(struct device
*);
170 static int osst_remove(struct device
*);
172 static struct scsi_driver osst_template
= {
173 .owner
= THIS_MODULE
,
177 .remove
= osst_remove
,
181 static int osst_int_ioctl(struct osst_tape
*STp
, struct osst_request
** aSRpnt
,
182 unsigned int cmd_in
, unsigned long arg
);
184 static int osst_set_frame_position(struct osst_tape
*STp
, struct osst_request
** aSRpnt
, int frame
, int skip
);
186 static int osst_get_frame_position(struct osst_tape
*STp
, struct osst_request
** aSRpnt
);
188 static int osst_flush_write_buffer(struct osst_tape
*STp
, struct osst_request
** aSRpnt
);
190 static int osst_write_error_recovery(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int pending
);
192 static inline char *tape_name(struct osst_tape
*tape
)
194 return tape
->drive
->disk_name
;
197 /* Routines that handle the interaction with mid-layer SCSI routines */
200 /* Normalize Sense */
201 static void osst_analyze_sense(struct osst_request
*SRpnt
, struct st_cmdstatus
*s
)
204 const u8
*sense
= SRpnt
->sense
;
206 s
->have_sense
= scsi_normalize_sense(SRpnt
->sense
,
207 SCSI_SENSE_BUFFERSIZE
, &s
->sense_hdr
);
213 scsi_get_sense_info_fld(sense
, SCSI_SENSE_BUFFERSIZE
, &s
->uremainder64
);
214 switch (sense
[0] & 0x7f) {
219 s
->flags
= sense
[2] & 0xe0;
225 ucp
= scsi_sense_desc_find(sense
, SCSI_SENSE_BUFFERSIZE
, 4);
226 s
->flags
= ucp
? (ucp
[3] & 0xe0) : 0;
232 /* Convert the result to success code */
233 static int osst_chk_result(struct osst_tape
* STp
, struct osst_request
* SRpnt
)
235 char *name
= tape_name(STp
);
236 int result
= SRpnt
->result
;
237 u8
* sense
= SRpnt
->sense
, scode
;
241 struct st_cmdstatus
*cmdstatp
;
246 cmdstatp
= &STp
->buffer
->cmdstat
;
247 osst_analyze_sense(SRpnt
, cmdstatp
);
249 if (cmdstatp
->have_sense
)
250 scode
= STp
->buffer
->cmdstat
.sense_hdr
.sense_key
;
255 printk(OSST_DEB_MSG
"%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
257 SRpnt
->cmd
[0], SRpnt
->cmd
[1], SRpnt
->cmd
[2],
258 SRpnt
->cmd
[3], SRpnt
->cmd
[4], SRpnt
->cmd
[5]);
259 if (scode
) printk(OSST_DEB_MSG
"%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
260 name
, scode
, sense
[12], sense
[13]);
261 if (cmdstatp
->have_sense
)
262 __scsi_print_sense("osst ", SRpnt
->sense
, SCSI_SENSE_BUFFERSIZE
);
266 if (cmdstatp
->have_sense
&& (
268 scode
!= RECOVERED_ERROR
&&
269 /* scode != UNIT_ATTENTION && */
270 scode
!= BLANK_CHECK
&&
271 scode
!= VOLUME_OVERFLOW
&&
272 SRpnt
->cmd
[0] != MODE_SENSE
&&
273 SRpnt
->cmd
[0] != TEST_UNIT_READY
)) { /* Abnormal conditions for tape */
274 if (cmdstatp
->have_sense
) {
275 printk(KERN_WARNING
"%s:W: Command with sense data:\n", name
);
276 __scsi_print_sense("osst ", SRpnt
->sense
, SCSI_SENSE_BUFFERSIZE
);
279 static int notyetprinted
= 1;
282 "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
283 name
, result
, suggestion(result
), driver_byte(result
) & DRIVER_MASK
,
288 "%s:I: This warning may be caused by your scsi controller,\n", name
);
290 "%s:I: it has been reported with some Buslogic cards.\n", name
);
294 STp
->pos_unknown
|= STp
->device
->was_reset
;
296 if (cmdstatp
->have_sense
&& scode
== RECOVERED_ERROR
) {
297 STp
->recover_count
++;
298 STp
->recover_erreg
++;
301 if (SRpnt
->cmd
[0] == READ_6
)
303 else if (SRpnt
->cmd
[0] == WRITE_6
)
307 printk(OSST_DEB_MSG
"%s:D: Recovered %s error (%d).\n", name
, stp
,
311 if ((sense
[2] & 0xe0) == 0)
318 /* Wakeup from interrupt */
319 static void osst_sleep_done(void *data
, char *sense
, int result
, int resid
)
321 struct osst_request
*SRpnt
= data
;
322 struct osst_tape
*STp
= SRpnt
->stp
;
324 memcpy(SRpnt
->sense
, sense
, SCSI_SENSE_BUFFERSIZE
);
325 STp
->buffer
->cmdstat
.midlevel_result
= SRpnt
->result
= result
;
327 STp
->write_pending
= 0;
330 complete(SRpnt
->waiting
);
333 /* osst_request memory management */
334 static struct osst_request
*osst_allocate_request(void)
336 return kzalloc(sizeof(struct osst_request
), GFP_KERNEL
);
339 static void osst_release_request(struct osst_request
*streq
)
344 /* Do the scsi command. Waits until command performed if do_wait is true.
345 Otherwise osst_write_behind_check() is used to check that the command
347 static struct osst_request
* osst_do_scsi(struct osst_request
*SRpnt
, struct osst_tape
*STp
,
348 unsigned char *cmd
, int bytes
, int direction
, int timeout
, int retries
, int do_wait
)
351 unsigned short use_sg
;
352 #ifdef OSST_INJECT_ERRORS
353 static int inject
= 0;
354 static int repeat
= 0;
356 struct completion
*waiting
;
358 /* if async, make sure there's no command outstanding */
359 if (!do_wait
&& ((STp
->buffer
)->last_SRpnt
)) {
360 printk(KERN_ERR
"%s: Async command already active.\n",
362 if (signal_pending(current
))
363 (STp
->buffer
)->syscall_result
= (-EINTR
);
365 (STp
->buffer
)->syscall_result
= (-EBUSY
);
370 SRpnt
= osst_allocate_request();
372 printk(KERN_ERR
"%s: Can't allocate SCSI request.\n",
374 if (signal_pending(current
))
375 (STp
->buffer
)->syscall_result
= (-EINTR
);
377 (STp
->buffer
)->syscall_result
= (-EBUSY
);
383 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
384 which IO is outstanding. It's nulled out when the IO completes. */
386 (STp
->buffer
)->last_SRpnt
= SRpnt
;
388 waiting
= &STp
->wait
;
389 init_completion(waiting
);
390 SRpnt
->waiting
= waiting
;
392 use_sg
= (bytes
> STp
->buffer
->sg
[0].length
) ? STp
->buffer
->use_sg
: 0;
394 bp
= (char *)&(STp
->buffer
->sg
[0]);
395 if (STp
->buffer
->sg_segs
< use_sg
)
396 use_sg
= STp
->buffer
->sg_segs
;
399 bp
= (STp
->buffer
)->b_data
;
401 memcpy(SRpnt
->cmd
, cmd
, sizeof(SRpnt
->cmd
));
402 STp
->buffer
->cmdstat
.have_sense
= 0;
403 STp
->buffer
->syscall_result
= 0;
405 if (scsi_execute_async(STp
->device
, cmd
, COMMAND_SIZE(cmd
[0]), direction
, bp
, bytes
,
406 use_sg
, timeout
, retries
, SRpnt
, osst_sleep_done
, GFP_KERNEL
))
407 /* could not allocate the buffer or request was too large */
408 (STp
->buffer
)->syscall_result
= (-EBUSY
);
410 wait_for_completion(waiting
);
411 SRpnt
->waiting
= NULL
;
412 STp
->buffer
->syscall_result
= osst_chk_result(STp
, SRpnt
);
413 #ifdef OSST_INJECT_ERRORS
414 if (STp
->buffer
->syscall_result
== 0 &&
417 ( (++ inject
% 83) == 29 ||
418 (STp
->first_frame_position
== 240
419 /* or STp->read_error_frame to fail again on the block calculated above */ &&
421 printk(OSST_DEB_MSG
"%s:D: Injecting read error\n", tape_name(STp
));
422 STp
->buffer
->last_result_fatal
= 1;
430 /* Handle the write-behind checking (downs the semaphore) */
431 static void osst_write_behind_check(struct osst_tape
*STp
)
433 struct osst_buffer
* STbuffer
;
435 STbuffer
= STp
->buffer
;
438 if (STp
->write_pending
)
443 wait_for_completion(&(STp
->wait
));
444 STp
->buffer
->last_SRpnt
->waiting
= NULL
;
446 STp
->buffer
->syscall_result
= osst_chk_result(STp
, STp
->buffer
->last_SRpnt
);
448 if (STp
->buffer
->syscall_result
)
449 STp
->buffer
->syscall_result
=
450 osst_write_error_recovery(STp
, &(STp
->buffer
->last_SRpnt
), 1);
452 STp
->first_frame_position
++;
454 osst_release_request(STp
->buffer
->last_SRpnt
);
456 if (STbuffer
->writing
< STbuffer
->buffer_bytes
)
457 printk(KERN_WARNING
"osst :A: write_behind_check: something left in buffer!\n");
459 STbuffer
->last_SRpnt
= NULL
;
460 STbuffer
->buffer_bytes
-= STbuffer
->writing
;
461 STbuffer
->writing
= 0;
468 /* Onstream specific Routines */
470 * Initialize the OnStream AUX
472 static void osst_init_aux(struct osst_tape
* STp
, int frame_type
, int frame_seq_number
,
473 int logical_blk_num
, int blk_sz
, int blk_cnt
)
475 os_aux_t
*aux
= STp
->buffer
->aux
;
476 os_partition_t
*par
= &aux
->partition
;
477 os_dat_t
*dat
= &aux
->dat
;
479 if (STp
->raw
) return;
481 memset(aux
, 0, sizeof(*aux
));
482 aux
->format_id
= htonl(0);
483 memcpy(aux
->application_sig
, "LIN4", 4);
484 aux
->hdwr
= htonl(0);
485 aux
->frame_type
= frame_type
;
487 switch (frame_type
) {
488 case OS_FRAME_TYPE_HEADER
:
489 aux
->update_frame_cntr
= htonl(STp
->update_frame_cntr
);
490 par
->partition_num
= OS_CONFIG_PARTITION
;
491 par
->par_desc_ver
= OS_PARTITION_VERSION
;
492 par
->wrt_pass_cntr
= htons(0xffff);
493 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
494 par
->first_frame_ppos
= htonl(0);
495 par
->last_frame_ppos
= htonl(0xbb7);
496 aux
->frame_seq_num
= htonl(0);
497 aux
->logical_blk_num_high
= htonl(0);
498 aux
->logical_blk_num
= htonl(0);
499 aux
->next_mark_ppos
= htonl(STp
->first_mark_ppos
);
501 case OS_FRAME_TYPE_DATA
:
502 case OS_FRAME_TYPE_MARKER
:
507 dat
->dat_list
[0].blk_sz
= htonl(blk_sz
);
508 dat
->dat_list
[0].blk_cnt
= htons(blk_cnt
);
509 dat
->dat_list
[0].flags
= frame_type
==OS_FRAME_TYPE_MARKER
?
510 OS_DAT_FLAGS_MARK
:OS_DAT_FLAGS_DATA
;
511 dat
->dat_list
[0].reserved
= 0;
512 case OS_FRAME_TYPE_EOD
:
513 aux
->update_frame_cntr
= htonl(0);
514 par
->partition_num
= OS_DATA_PARTITION
;
515 par
->par_desc_ver
= OS_PARTITION_VERSION
;
516 par
->wrt_pass_cntr
= htons(STp
->wrt_pass_cntr
);
517 par
->first_frame_ppos
= htonl(STp
->first_data_ppos
);
518 par
->last_frame_ppos
= htonl(STp
->capacity
);
519 aux
->frame_seq_num
= htonl(frame_seq_number
);
520 aux
->logical_blk_num_high
= htonl(0);
521 aux
->logical_blk_num
= htonl(logical_blk_num
);
523 default: ; /* probably FILL */
525 aux
->filemark_cnt
= htonl(STp
->filemark_cnt
);
526 aux
->phys_fm
= htonl(0xffffffff);
527 aux
->last_mark_ppos
= htonl(STp
->last_mark_ppos
);
528 aux
->last_mark_lbn
= htonl(STp
->last_mark_lbn
);
532 * Verify that we have the correct tape frame
534 static int osst_verify_frame(struct osst_tape
* STp
, int frame_seq_number
, int quiet
)
536 char * name
= tape_name(STp
);
537 os_aux_t
* aux
= STp
->buffer
->aux
;
538 os_partition_t
* par
= &(aux
->partition
);
539 struct st_partstat
* STps
= &(STp
->ps
[STp
->partition
]);
540 int blk_cnt
, blk_sz
, i
;
543 if (STp
->buffer
->syscall_result
) {
544 for (i
=0; i
< STp
->buffer
->sg_segs
; i
++)
545 memset(page_address(STp
->buffer
->sg
[i
].page
),
546 0, STp
->buffer
->sg
[i
].length
);
547 strcpy(STp
->buffer
->b_data
, "READ ERROR ON FRAME");
549 STp
->buffer
->buffer_bytes
= OS_FRAME_SIZE
;
552 if (STp
->buffer
->syscall_result
) {
554 printk(OSST_DEB_MSG
"%s:D: Skipping frame, read error\n", name
);
558 if (ntohl(aux
->format_id
) != 0) {
560 printk(OSST_DEB_MSG
"%s:D: Skipping frame, format_id %u\n", name
, ntohl(aux
->format_id
));
564 if (memcmp(aux
->application_sig
, STp
->application_sig
, 4) != 0 &&
565 (memcmp(aux
->application_sig
, "LIN3", 4) != 0 || STp
->linux_media_version
!= 4)) {
567 printk(OSST_DEB_MSG
"%s:D: Skipping frame, incorrect application signature\n", name
);
571 if (par
->partition_num
!= OS_DATA_PARTITION
) {
572 if (!STp
->linux_media
|| STp
->linux_media_version
!= 2) {
574 printk(OSST_DEB_MSG
"%s:D: Skipping frame, partition num %d\n",
575 name
, par
->partition_num
);
580 if (par
->par_desc_ver
!= OS_PARTITION_VERSION
) {
582 printk(OSST_DEB_MSG
"%s:D: Skipping frame, partition version %d\n", name
, par
->par_desc_ver
);
586 if (ntohs(par
->wrt_pass_cntr
) != STp
->wrt_pass_cntr
) {
588 printk(OSST_DEB_MSG
"%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
589 name
, ntohs(par
->wrt_pass_cntr
), STp
->wrt_pass_cntr
);
593 if (aux
->frame_type
!= OS_FRAME_TYPE_DATA
&&
594 aux
->frame_type
!= OS_FRAME_TYPE_EOD
&&
595 aux
->frame_type
!= OS_FRAME_TYPE_MARKER
) {
598 printk(OSST_DEB_MSG
"%s:D: Skipping frame, frame type %x\n", name
, aux
->frame_type
);
602 if (aux
->frame_type
== OS_FRAME_TYPE_EOD
&&
603 STp
->first_frame_position
< STp
->eod_frame_ppos
) {
604 printk(KERN_INFO
"%s:I: Skipping premature EOD frame %d\n", name
,
605 STp
->first_frame_position
);
608 if (frame_seq_number
!= -1 && ntohl(aux
->frame_seq_num
) != frame_seq_number
) {
611 printk(OSST_DEB_MSG
"%s:D: Skipping frame, sequence number %u (expected %d)\n",
612 name
, ntohl(aux
->frame_seq_num
), frame_seq_number
);
616 if (aux
->frame_type
== OS_FRAME_TYPE_MARKER
) {
617 STps
->eof
= ST_FM_HIT
;
619 i
= ntohl(aux
->filemark_cnt
);
620 if (STp
->header_cache
!= NULL
&& i
< OS_FM_TAB_MAX
&& (i
> STp
->filemark_cnt
||
621 STp
->first_frame_position
- 1 != ntohl(STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[i
]))) {
623 printk(OSST_DEB_MSG
"%s:D: %s filemark %d at frame pos %d\n", name
,
624 STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[i
] == 0?"Learned":"Corrected",
625 i
, STp
->first_frame_position
- 1);
627 STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[i
] = htonl(STp
->first_frame_position
- 1);
628 if (i
>= STp
->filemark_cnt
)
629 STp
->filemark_cnt
= i
+1;
632 if (aux
->frame_type
== OS_FRAME_TYPE_EOD
) {
633 STps
->eof
= ST_EOD_1
;
634 STp
->frame_in_buffer
= 1;
636 if (aux
->frame_type
== OS_FRAME_TYPE_DATA
) {
637 blk_cnt
= ntohs(aux
->dat
.dat_list
[0].blk_cnt
);
638 blk_sz
= ntohl(aux
->dat
.dat_list
[0].blk_sz
);
639 STp
->buffer
->buffer_bytes
= blk_cnt
* blk_sz
;
640 STp
->buffer
->read_pointer
= 0;
641 STp
->frame_in_buffer
= 1;
643 /* See what block size was used to write file */
644 if (STp
->block_size
!= blk_sz
&& blk_sz
> 0) {
646 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
647 name
, blk_sz
<1024?blk_sz
:blk_sz
/1024,blk_sz
<1024?'b':'k',
648 STp
->block_size
<1024?STp
->block_size
:STp
->block_size
/1024,
649 STp
->block_size
<1024?'b':'k');
650 STp
->block_size
= blk_sz
;
651 STp
->buffer
->buffer_blocks
= OS_DATA_SIZE
/ blk_sz
;
653 STps
->eof
= ST_NOEOF
;
655 STp
->frame_seq_number
= ntohl(aux
->frame_seq_num
);
656 STp
->logical_blk_num
= ntohl(aux
->logical_blk_num
);
660 if (STp
->read_error_frame
== 0)
661 STp
->read_error_frame
= STp
->first_frame_position
- 1;
666 * Wait for the unit to become Ready
668 static int osst_wait_ready(struct osst_tape
* STp
, struct osst_request
** aSRpnt
,
669 unsigned timeout
, int initial_delay
)
671 unsigned char cmd
[MAX_COMMAND_SIZE
];
672 struct osst_request
* SRpnt
;
673 unsigned long startwait
= jiffies
;
676 char * name
= tape_name(STp
);
678 printk(OSST_DEB_MSG
"%s:D: Reached onstream wait ready\n", name
);
681 if (initial_delay
> 0)
682 msleep(jiffies_to_msecs(initial_delay
));
684 memset(cmd
, 0, MAX_COMMAND_SIZE
);
685 cmd
[0] = TEST_UNIT_READY
;
687 SRpnt
= osst_do_scsi(*aSRpnt
, STp
, cmd
, 0, DMA_NONE
, STp
->timeout
, MAX_RETRIES
, 1);
689 if (!SRpnt
) return (-EBUSY
);
691 while ( STp
->buffer
->syscall_result
&& time_before(jiffies
, startwait
+ timeout
*HZ
) &&
692 (( SRpnt
->sense
[2] == 2 && SRpnt
->sense
[12] == 4 &&
693 (SRpnt
->sense
[13] == 1 || SRpnt
->sense
[13] == 8) ) ||
694 ( SRpnt
->sense
[2] == 6 && SRpnt
->sense
[12] == 0x28 &&
695 SRpnt
->sense
[13] == 0 ) )) {
698 printk(OSST_DEB_MSG
"%s:D: Sleeping in onstream wait ready\n", name
);
699 printk(OSST_DEB_MSG
"%s:D: Turning off debugging for a while\n", name
);
705 memset(cmd
, 0, MAX_COMMAND_SIZE
);
706 cmd
[0] = TEST_UNIT_READY
;
708 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, 0, DMA_NONE
, STp
->timeout
, MAX_RETRIES
, 1);
714 if ( STp
->buffer
->syscall_result
&&
715 osst_write_error_recovery(STp
, aSRpnt
, 0) ) {
717 printk(OSST_DEB_MSG
"%s:D: Abnormal exit from onstream wait ready\n", name
);
718 printk(OSST_DEB_MSG
"%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name
,
719 STp
->buffer
->syscall_result
, SRpnt
->sense
[0], SRpnt
->sense
[2],
720 SRpnt
->sense
[12], SRpnt
->sense
[13]);
725 printk(OSST_DEB_MSG
"%s:D: Normal exit from onstream wait ready\n", name
);
731 * Wait for a tape to be inserted in the unit
733 static int osst_wait_for_medium(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, unsigned timeout
)
735 unsigned char cmd
[MAX_COMMAND_SIZE
];
736 struct osst_request
* SRpnt
;
737 unsigned long startwait
= jiffies
;
740 char * name
= tape_name(STp
);
742 printk(OSST_DEB_MSG
"%s:D: Reached onstream wait for medium\n", name
);
745 memset(cmd
, 0, MAX_COMMAND_SIZE
);
746 cmd
[0] = TEST_UNIT_READY
;
748 SRpnt
= osst_do_scsi(*aSRpnt
, STp
, cmd
, 0, DMA_NONE
, STp
->timeout
, MAX_RETRIES
, 1);
750 if (!SRpnt
) return (-EBUSY
);
752 while ( STp
->buffer
->syscall_result
&& time_before(jiffies
, startwait
+ timeout
*HZ
) &&
753 SRpnt
->sense
[2] == 2 && SRpnt
->sense
[12] == 0x3a && SRpnt
->sense
[13] == 0 ) {
756 printk(OSST_DEB_MSG
"%s:D: Sleeping in onstream wait medium\n", name
);
757 printk(OSST_DEB_MSG
"%s:D: Turning off debugging for a while\n", name
);
763 memset(cmd
, 0, MAX_COMMAND_SIZE
);
764 cmd
[0] = TEST_UNIT_READY
;
766 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, 0, DMA_NONE
, STp
->timeout
, MAX_RETRIES
, 1);
772 if ( STp
->buffer
->syscall_result
&& SRpnt
->sense
[2] != 2 &&
773 SRpnt
->sense
[12] != 4 && SRpnt
->sense
[13] == 1) {
775 printk(OSST_DEB_MSG
"%s:D: Abnormal exit from onstream wait medium\n", name
);
776 printk(OSST_DEB_MSG
"%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name
,
777 STp
->buffer
->syscall_result
, SRpnt
->sense
[0], SRpnt
->sense
[2],
778 SRpnt
->sense
[12], SRpnt
->sense
[13]);
783 printk(OSST_DEB_MSG
"%s:D: Normal exit from onstream wait medium\n", name
);
788 static int osst_position_tape_and_confirm(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int frame
)
792 osst_wait_ready(STp
, aSRpnt
, 15 * 60, 0); /* TODO - can this catch a write error? */
793 retval
= osst_set_frame_position(STp
, aSRpnt
, frame
, 0);
794 if (retval
) return (retval
);
795 osst_wait_ready(STp
, aSRpnt
, 15 * 60, OSST_WAIT_POSITION_COMPLETE
);
796 return (osst_get_frame_position(STp
, aSRpnt
));
800 * Wait for write(s) to complete
802 static int osst_flush_drive_buffer(struct osst_tape
* STp
, struct osst_request
** aSRpnt
)
804 unsigned char cmd
[MAX_COMMAND_SIZE
];
805 struct osst_request
* SRpnt
;
807 int delay
= OSST_WAIT_WRITE_COMPLETE
;
809 char * name
= tape_name(STp
);
811 printk(OSST_DEB_MSG
"%s:D: Reached onstream flush drive buffer (write filemark)\n", name
);
814 memset(cmd
, 0, MAX_COMMAND_SIZE
);
815 cmd
[0] = WRITE_FILEMARKS
;
818 SRpnt
= osst_do_scsi(*aSRpnt
, STp
, cmd
, 0, DMA_NONE
, STp
->timeout
, MAX_RETRIES
, 1);
820 if (!SRpnt
) return (-EBUSY
);
821 if (STp
->buffer
->syscall_result
) {
822 if ((SRpnt
->sense
[2] & 0x0f) == 2 && SRpnt
->sense
[12] == 4) {
823 if (SRpnt
->sense
[13] == 8) {
824 delay
= OSST_WAIT_LONG_WRITE_COMPLETE
;
827 result
= osst_write_error_recovery(STp
, aSRpnt
, 0);
829 result
|= osst_wait_ready(STp
, aSRpnt
, 5 * 60, delay
);
830 STp
->ps
[STp
->partition
].rw
= OS_WRITING_COMPLETE
;
835 #define OSST_POLL_PER_SEC 10
836 static int osst_wait_frame(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int curr
, int minlast
, int to
)
838 unsigned long startwait
= jiffies
;
839 char * name
= tape_name(STp
);
841 char notyetprinted
= 1;
843 if (minlast
>= 0 && STp
->ps
[STp
->partition
].rw
!= ST_READING
)
844 printk(KERN_ERR
"%s:A: Waiting for frame without having initialized read!\n", name
);
846 while (time_before (jiffies
, startwait
+ to
*HZ
))
849 result
= osst_get_frame_position(STp
, aSRpnt
);
851 if ((result
= osst_write_error_recovery(STp
, aSRpnt
, 0)) == 0)
852 return 0; /* successful recovery leaves drive ready for frame */
853 if (result
< 0) break;
854 if (STp
->first_frame_position
== curr
&&
856 (signed)STp
->last_frame_position
> (signed)curr
+ minlast
) ||
857 (minlast
>= 0 && STp
->cur_frames
> minlast
)
861 if (debugging
|| time_after_eq(jiffies
, startwait
+ 2*HZ
/OSST_POLL_PER_SEC
))
863 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
864 name
, curr
, curr
+minlast
, STp
->first_frame_position
,
865 STp
->last_frame_position
, STp
->cur_frames
,
866 result
, (jiffies
-startwait
)/HZ
,
867 (((jiffies
-startwait
)%HZ
)*10)/HZ
);
872 if (time_after_eq(jiffies
, startwait
+ 2*HZ
/OSST_POLL_PER_SEC
) && notyetprinted
)
874 printk (OSST_DEB_MSG
"%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
875 name
, curr
, curr
+minlast
, STp
->first_frame_position
,
876 STp
->last_frame_position
, STp
->cur_frames
, result
);
880 msleep(1000 / OSST_POLL_PER_SEC
);
883 printk (OSST_DEB_MSG
"%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
884 name
, curr
, curr
+minlast
, STp
->first_frame_position
,
885 STp
->last_frame_position
, STp
->cur_frames
,
886 (jiffies
-startwait
)/HZ
, (((jiffies
-startwait
)%HZ
)*10)/HZ
);
891 static int osst_recover_wait_frame(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int writing
)
893 struct osst_request
* SRpnt
;
894 unsigned char cmd
[MAX_COMMAND_SIZE
];
895 unsigned long startwait
= jiffies
;
897 char * name
= tape_name(STp
);
901 char * olddata
= STp
->buffer
->b_data
;
902 int oldsize
= STp
->buffer
->buffer_size
;
904 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
906 memset(cmd
, 0, MAX_COMMAND_SIZE
);
907 cmd
[0] = WRITE_FILEMARKS
;
909 SRpnt
= osst_do_scsi(*aSRpnt
, STp
, cmd
, 0, DMA_NONE
, STp
->timeout
,
912 while (retval
&& time_before (jiffies
, startwait
+ 5*60*HZ
)) {
914 if (STp
->buffer
->syscall_result
&& (SRpnt
->sense
[2] & 0x0f) != 2) {
916 /* some failure - not just not-ready */
917 retval
= osst_write_error_recovery(STp
, aSRpnt
, 0);
920 schedule_timeout_interruptible(HZ
/ OSST_POLL_PER_SEC
);
922 STp
->buffer
->b_data
= mybuf
; STp
->buffer
->buffer_size
= 24;
923 memset(cmd
, 0, MAX_COMMAND_SIZE
);
924 cmd
[0] = READ_POSITION
;
926 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, 20, DMA_FROM_DEVICE
, STp
->timeout
,
929 retval
= ( STp
->buffer
->syscall_result
|| (STp
->buffer
)->b_data
[15] > 25 );
930 STp
->buffer
->b_data
= olddata
; STp
->buffer
->buffer_size
= oldsize
;
933 printk(KERN_ERR
"%s:E: Device did not succeed to write buffered data\n", name
);
935 /* TODO - figure out which error conditions can be handled */
936 if (STp
->buffer
->syscall_result
)
938 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name
,
939 (*aSRpnt
)->sense
[ 2] & 0x0f,
940 (*aSRpnt
)->sense
[12],
941 (*aSRpnt
)->sense
[13]);
947 * Read the next OnStream tape frame at the current location
949 static int osst_read_frame(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int timeout
)
951 unsigned char cmd
[MAX_COMMAND_SIZE
];
952 struct osst_request
* SRpnt
;
955 os_aux_t
* aux
= STp
->buffer
->aux
;
956 char * name
= tape_name(STp
);
960 if (osst_wait_frame (STp
, aSRpnt
, STp
->first_frame_position
, 0, timeout
))
961 retval
= osst_recover_wait_frame(STp
, aSRpnt
, 0);
963 memset(cmd
, 0, MAX_COMMAND_SIZE
);
970 printk(OSST_DEB_MSG
"%s:D: Reading frame from OnStream tape\n", name
);
972 SRpnt
= osst_do_scsi(*aSRpnt
, STp
, cmd
, OS_FRAME_SIZE
, DMA_FROM_DEVICE
,
973 STp
->timeout
, MAX_RETRIES
, 1);
978 if ((STp
->buffer
)->syscall_result
) {
980 if (STp
->read_error_frame
== 0) {
981 STp
->read_error_frame
= STp
->first_frame_position
;
983 printk(OSST_DEB_MSG
"%s:D: Recording read error at %d\n", name
, STp
->read_error_frame
);
988 printk(OSST_DEB_MSG
"%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
990 SRpnt
->sense
[0], SRpnt
->sense
[1],
991 SRpnt
->sense
[2], SRpnt
->sense
[3],
992 SRpnt
->sense
[4], SRpnt
->sense
[5],
993 SRpnt
->sense
[6], SRpnt
->sense
[7]);
997 STp
->first_frame_position
++;
1002 sig
[i
] = aux
->application_sig
[i
]<32?'^':aux
->application_sig
[i
];
1005 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name
, sig
,
1006 ntohl(aux
->update_frame_cntr
), ntohs(aux
->partition
.wrt_pass_cntr
),
1007 aux
->frame_type
==1?"EOD":aux
->frame_type
==2?"MARK":
1008 aux
->frame_type
==8?"HEADR":aux
->frame_type
==0x80?"DATA":"FILL",
1009 ntohl(aux
->frame_seq_num
), ntohl(aux
->logical_blk_num
),
1010 ntohs(aux
->dat
.dat_list
[0].blk_cnt
), ntohl(aux
->dat
.dat_list
[0].blk_sz
) );
1011 if (aux
->frame_type
==2)
1012 printk(OSST_DEB_MSG
"%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name
,
1013 ntohl(aux
->filemark_cnt
), ntohl(aux
->last_mark_ppos
), ntohl(aux
->last_mark_lbn
));
1014 printk(OSST_DEB_MSG
"%s:D: Exit read frame from OnStream tape with code %d\n", name
, retval
);
1020 static int osst_initiate_read(struct osst_tape
* STp
, struct osst_request
** aSRpnt
)
1022 struct st_partstat
* STps
= &(STp
->ps
[STp
->partition
]);
1023 struct osst_request
* SRpnt
;
1024 unsigned char cmd
[MAX_COMMAND_SIZE
];
1026 char * name
= tape_name(STp
);
1028 if (STps
->rw
!= ST_READING
) { /* Initialize read operation */
1029 if (STps
->rw
== ST_WRITING
|| STp
->dirty
) {
1030 STp
->write_type
= OS_WRITE_DATA
;
1031 osst_flush_write_buffer(STp
, aSRpnt
);
1032 osst_flush_drive_buffer(STp
, aSRpnt
);
1034 STps
->rw
= ST_READING
;
1035 STp
->frame_in_buffer
= 0;
1038 * Issue a read 0 command to get the OnStream drive
1039 * read frames into its buffer.
1041 memset(cmd
, 0, MAX_COMMAND_SIZE
);
1046 printk(OSST_DEB_MSG
"%s:D: Start Read Ahead on OnStream tape\n", name
);
1048 SRpnt
= osst_do_scsi(*aSRpnt
, STp
, cmd
, 0, DMA_NONE
, STp
->timeout
, MAX_RETRIES
, 1);
1050 if ((retval
= STp
->buffer
->syscall_result
))
1051 printk(KERN_WARNING
"%s:W: Error starting read ahead\n", name
);
1057 static int osst_get_logical_frame(struct osst_tape
* STp
, struct osst_request
** aSRpnt
,
1058 int frame_seq_number
, int quiet
)
1060 struct st_partstat
* STps
= &(STp
->ps
[STp
->partition
]);
1061 char * name
= tape_name(STp
);
1069 * If we want just any frame (-1) and there is a frame in the buffer, return it
1071 if (frame_seq_number
== -1 && STp
->frame_in_buffer
) {
1073 printk(OSST_DEB_MSG
"%s:D: Frame %d still in buffer\n", name
, STp
->frame_seq_number
);
1078 * Search and wait for the next logical tape frame
1082 printk(KERN_ERR
"%s:E: Couldn't find logical frame %d, aborting\n",
1083 name
, frame_seq_number
);
1084 if (STp
->read_error_frame
) {
1085 osst_set_frame_position(STp
, aSRpnt
, STp
->read_error_frame
, 0);
1087 printk(OSST_DEB_MSG
"%s:D: Repositioning tape to bad frame %d\n",
1088 name
, STp
->read_error_frame
);
1090 STp
->read_error_frame
= 0;
1097 printk(OSST_DEB_MSG
"%s:D: Looking for frame %d, attempt %d\n",
1098 name
, frame_seq_number
, cnt
);
1100 if ( osst_initiate_read(STp
, aSRpnt
)
1101 || ( (!STp
->frame_in_buffer
) && osst_read_frame(STp
, aSRpnt
, 30) ) ) {
1104 position
= osst_get_frame_position(STp
, aSRpnt
);
1105 if (position
>= 0xbae && position
< 0xbb8)
1107 else if (position
> STp
->eod_frame_ppos
|| ++bad
== 10) {
1108 position
= STp
->read_error_frame
- 1;
1116 printk(OSST_DEB_MSG
"%s:D: Bad frame detected, positioning tape to block %d\n",
1119 osst_set_frame_position(STp
, aSRpnt
, position
, 0);
1122 if (osst_verify_frame(STp
, frame_seq_number
, quiet
))
1124 if (osst_verify_frame(STp
, -1, quiet
)) {
1125 x
= ntohl(STp
->buffer
->aux
->frame_seq_num
);
1126 if (STp
->fast_open
) {
1128 "%s:W: Found logical frame %d instead of %d after fast open\n",
1129 name
, x
, frame_seq_number
);
1131 STp
->read_error_frame
= 0;
1134 if (x
> frame_seq_number
) {
1136 /* positioning backwards did not bring us to the desired frame */
1137 position
= STp
->read_error_frame
- 1;
1140 position
= osst_get_frame_position(STp
, aSRpnt
)
1141 + frame_seq_number
- x
- 1;
1143 if (STp
->first_frame_position
>= 3000 && position
< 3000)
1148 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1149 name
, x
, frame_seq_number
,
1150 STp
->first_frame_position
- position
);
1152 osst_set_frame_position(STp
, aSRpnt
, position
, 0);
1158 if (osst_get_frame_position(STp
, aSRpnt
) == 0xbaf) {
1160 printk(OSST_DEB_MSG
"%s:D: Skipping config partition\n", name
);
1162 osst_set_frame_position(STp
, aSRpnt
, 0xbb8, 0);
1165 STp
->frame_in_buffer
= 0;
1168 STp
->recover_count
++;
1169 STp
->recover_erreg
++;
1170 printk(KERN_WARNING
"%s:I: Don't worry, Read error at position %d recovered\n",
1171 name
, STp
->read_error_frame
);
1176 if (debugging
|| STps
->eof
)
1178 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1179 name
, frame_seq_number
, STp
->frame_seq_number
, STps
->eof
);
1182 STp
->read_error_frame
= 0;
1186 static int osst_seek_logical_blk(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int logical_blk_num
)
1188 struct st_partstat
* STps
= &(STp
->ps
[STp
->partition
]);
1189 char * name
= tape_name(STp
);
1191 int frame_seq_estimate
, ppos_estimate
, move
;
1193 if (logical_blk_num
< 0) logical_blk_num
= 0;
1195 printk(OSST_DEB_MSG
"%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1196 name
, logical_blk_num
, STp
->logical_blk_num
,
1197 STp
->block_size
<1024?STp
->block_size
:STp
->block_size
/1024,
1198 STp
->block_size
<1024?'b':'k');
1200 /* Do we know where we are? */
1201 if (STps
->drv_block
>= 0) {
1202 move
= logical_blk_num
- STp
->logical_blk_num
;
1203 if (move
< 0) move
-= (OS_DATA_SIZE
/ STp
->block_size
) - 1;
1204 move
/= (OS_DATA_SIZE
/ STp
->block_size
);
1205 frame_seq_estimate
= STp
->frame_seq_number
+ move
;
1207 frame_seq_estimate
= logical_blk_num
* STp
->block_size
/ OS_DATA_SIZE
;
1209 if (frame_seq_estimate
< 2980) ppos_estimate
= frame_seq_estimate
+ 10;
1210 else ppos_estimate
= frame_seq_estimate
+ 20;
1211 while (++retries
< 10) {
1212 if (ppos_estimate
> STp
->eod_frame_ppos
-2) {
1213 frame_seq_estimate
+= STp
->eod_frame_ppos
- 2 - ppos_estimate
;
1214 ppos_estimate
= STp
->eod_frame_ppos
- 2;
1216 if (frame_seq_estimate
< 0) {
1217 frame_seq_estimate
= 0;
1220 osst_set_frame_position(STp
, aSRpnt
, ppos_estimate
, 0);
1221 if (osst_get_logical_frame(STp
, aSRpnt
, frame_seq_estimate
, 1) >= 0) {
1222 /* we've located the estimated frame, now does it have our block? */
1223 if (logical_blk_num
< STp
->logical_blk_num
||
1224 logical_blk_num
>= STp
->logical_blk_num
+ ntohs(STp
->buffer
->aux
->dat
.dat_list
[0].blk_cnt
)) {
1225 if (STps
->eof
== ST_FM_HIT
)
1226 move
= logical_blk_num
< STp
->logical_blk_num
? -2 : 1;
1228 move
= logical_blk_num
- STp
->logical_blk_num
;
1229 if (move
< 0) move
-= (OS_DATA_SIZE
/ STp
->block_size
) - 1;
1230 move
/= (OS_DATA_SIZE
/ STp
->block_size
);
1232 if (!move
) move
= logical_blk_num
> STp
->logical_blk_num
? 1 : -1;
1235 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1236 name
, retries
, ppos_estimate
, STp
->frame_seq_number
, frame_seq_estimate
,
1237 STp
->logical_blk_num
, logical_blk_num
, move
);
1239 frame_seq_estimate
+= move
;
1240 ppos_estimate
+= move
;
1243 STp
->buffer
->read_pointer
= (logical_blk_num
- STp
->logical_blk_num
) * STp
->block_size
;
1244 STp
->buffer
->buffer_bytes
-= STp
->buffer
->read_pointer
;
1245 STp
->logical_blk_num
= logical_blk_num
;
1248 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1249 name
, ppos_estimate
, STp
->frame_seq_number
, STp
->frame_in_buffer
,
1250 STp
->buffer
->buffer_bytes
, STp
->buffer
->read_pointer
/ STp
->block_size
,
1253 STps
->drv_file
= ntohl(STp
->buffer
->aux
->filemark_cnt
);
1254 if (STps
->eof
== ST_FM_HIT
) {
1256 STps
->drv_block
= 0;
1258 STps
->drv_block
= ntohl(STp
->buffer
->aux
->last_mark_lbn
)?
1259 STp
->logical_blk_num
-
1260 (STps
->drv_file
? ntohl(STp
->buffer
->aux
->last_mark_lbn
) + 1 : 0):
1263 STps
->eof
= (STp
->first_frame_position
>= STp
->eod_frame_ppos
)?ST_EOD
:ST_NOEOF
;
1267 if (osst_get_logical_frame(STp
, aSRpnt
, -1, 1) < 0)
1269 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1271 printk(OSST_DEB_MSG
"%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1272 name
, retries
, ppos_estimate
, STp
->frame_seq_number
, frame_seq_estimate
,
1273 STp
->logical_blk_num
, logical_blk_num
);
1275 if (frame_seq_estimate
!= STp
->frame_seq_number
)
1276 ppos_estimate
+= frame_seq_estimate
- STp
->frame_seq_number
;
1281 printk(KERN_ERR
"%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1282 name
, logical_blk_num
, STp
->logical_blk_num
, retries
);
1286 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1287 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1288 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1289 * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1291 #define OSST_FRAME_SHIFT 6
1292 #define OSST_SECTOR_SHIFT 9
1293 #define OSST_SECTOR_MASK 0x03F
1295 static int osst_get_sector(struct osst_tape
* STp
, struct osst_request
** aSRpnt
)
1299 char * name
= tape_name(STp
);
1302 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1303 name
, STp
->first_frame_position
, STp
->frame_seq_number
, STp
->logical_blk_num
,
1304 STp
->ps
[STp
->partition
].drv_file
, STp
->ps
[STp
->partition
].drv_block
,
1305 STp
->ps
[STp
->partition
].rw
== ST_WRITING
?'w':'r',
1306 STp
->ps
[STp
->partition
].rw
== ST_WRITING
?STp
->buffer
->buffer_bytes
:
1307 STp
->buffer
->read_pointer
, STp
->ps
[STp
->partition
].eof
);
1309 /* do we know where we are inside a file? */
1310 if (STp
->ps
[STp
->partition
].drv_block
>= 0) {
1311 sector
= (STp
->frame_in_buffer
? STp
->first_frame_position
-1 :
1312 STp
->first_frame_position
) << OSST_FRAME_SHIFT
;
1313 if (STp
->ps
[STp
->partition
].rw
== ST_WRITING
)
1314 sector
|= (STp
->buffer
->buffer_bytes
>> OSST_SECTOR_SHIFT
) & OSST_SECTOR_MASK
;
1316 sector
|= (STp
->buffer
->read_pointer
>> OSST_SECTOR_SHIFT
) & OSST_SECTOR_MASK
;
1318 sector
= osst_get_frame_position(STp
, aSRpnt
);
1320 sector
<<= OSST_FRAME_SHIFT
;
1325 static int osst_seek_sector(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int sector
)
1327 struct st_partstat
* STps
= &(STp
->ps
[STp
->partition
]);
1328 int frame
= sector
>> OSST_FRAME_SHIFT
,
1329 offset
= (sector
& OSST_SECTOR_MASK
) << OSST_SECTOR_SHIFT
,
1332 char * name
= tape_name(STp
);
1334 printk(OSST_DEB_MSG
"%s:D: Seeking sector %d in frame %d at offset %d\n",
1335 name
, sector
, frame
, offset
);
1337 if (frame
< 0 || frame
>= STp
->capacity
) return (-ENXIO
);
1339 if (frame
<= STp
->first_data_ppos
) {
1340 STp
->frame_seq_number
= STp
->logical_blk_num
= STps
->drv_file
= STps
->drv_block
= 0;
1341 return (osst_set_frame_position(STp
, aSRpnt
, frame
, 0));
1343 r
= osst_set_frame_position(STp
, aSRpnt
, offset
?frame
:frame
-1, 0);
1344 if (r
< 0) return r
;
1346 r
= osst_get_logical_frame(STp
, aSRpnt
, -1, 1);
1347 if (r
< 0) return r
;
1349 if (osst_get_frame_position(STp
, aSRpnt
) != (offset
?frame
+1:frame
)) return (-EIO
);
1352 STp
->logical_blk_num
+= offset
/ STp
->block_size
;
1353 STp
->buffer
->read_pointer
= offset
;
1354 STp
->buffer
->buffer_bytes
-= offset
;
1356 STp
->frame_seq_number
++;
1357 STp
->frame_in_buffer
= 0;
1358 STp
->logical_blk_num
+= ntohs(STp
->buffer
->aux
->dat
.dat_list
[0].blk_cnt
);
1359 STp
->buffer
->buffer_bytes
= STp
->buffer
->read_pointer
= 0;
1361 STps
->drv_file
= ntohl(STp
->buffer
->aux
->filemark_cnt
);
1362 if (STps
->eof
== ST_FM_HIT
) {
1364 STps
->drv_block
= 0;
1366 STps
->drv_block
= ntohl(STp
->buffer
->aux
->last_mark_lbn
)?
1367 STp
->logical_blk_num
-
1368 (STps
->drv_file
? ntohl(STp
->buffer
->aux
->last_mark_lbn
) + 1 : 0):
1371 STps
->eof
= (STp
->first_frame_position
>= STp
->eod_frame_ppos
)?ST_EOD
:ST_NOEOF
;
1374 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1375 name
, STp
->first_frame_position
, STp
->frame_seq_number
, STp
->logical_blk_num
,
1376 STps
->drv_file
, STps
->drv_block
, STp
->buffer
->read_pointer
, STps
->eof
);
1382 * Read back the drive's internal buffer contents, as a part
1383 * of the write error recovery mechanism for old OnStream
1384 * firmware revisions.
1385 * Precondition for this function to work: all frames in the
1386 * drive's buffer must be of one type (DATA, MARK or EOD)!
1388 static int osst_read_back_buffer_and_rewrite(struct osst_tape
* STp
, struct osst_request
** aSRpnt
,
1389 unsigned int frame
, unsigned int skip
, int pending
)
1391 struct osst_request
* SRpnt
= * aSRpnt
;
1392 unsigned char * buffer
, * p
;
1393 unsigned char cmd
[MAX_COMMAND_SIZE
];
1394 int flag
, new_frame
, i
;
1395 int nframes
= STp
->cur_frames
;
1396 int blks_per_frame
= ntohs(STp
->buffer
->aux
->dat
.dat_list
[0].blk_cnt
);
1397 int frame_seq_number
= ntohl(STp
->buffer
->aux
->frame_seq_num
)
1398 - (nframes
+ pending
- 1);
1399 int logical_blk_num
= ntohl(STp
->buffer
->aux
->logical_blk_num
)
1400 - (nframes
+ pending
- 1) * blks_per_frame
;
1401 char * name
= tape_name(STp
);
1402 unsigned long startwait
= jiffies
;
1404 int dbg
= debugging
;
1407 if ((buffer
= (unsigned char *)vmalloc((nframes
+ 1) * OS_DATA_SIZE
)) == NULL
)
1410 printk(KERN_INFO
"%s:I: Reading back %d frames from drive buffer%s\n",
1411 name
, nframes
, pending
?" and one that was pending":"");
1413 osst_copy_from_buffer(STp
->buffer
, (p
= &buffer
[nframes
* OS_DATA_SIZE
]));
1415 if (pending
&& debugging
)
1416 printk(OSST_DEB_MSG
"%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1417 name
, frame_seq_number
+ nframes
,
1418 logical_blk_num
+ nframes
* blks_per_frame
,
1419 p
[0], p
[1], p
[2], p
[3]);
1421 for (i
= 0, p
= buffer
; i
< nframes
; i
++, p
+= OS_DATA_SIZE
) {
1423 memset(cmd
, 0, MAX_COMMAND_SIZE
);
1424 cmd
[0] = 0x3C; /* Buffer Read */
1425 cmd
[1] = 6; /* Retrieve Faulty Block */
1426 cmd
[7] = 32768 >> 8;
1427 cmd
[8] = 32768 & 0xff;
1429 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, OS_FRAME_SIZE
, DMA_FROM_DEVICE
,
1430 STp
->timeout
, MAX_RETRIES
, 1);
1432 if ((STp
->buffer
)->syscall_result
|| !SRpnt
) {
1433 printk(KERN_ERR
"%s:E: Failed to read frame back from OnStream buffer\n", name
);
1438 osst_copy_from_buffer(STp
->buffer
, p
);
1441 printk(OSST_DEB_MSG
"%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1442 name
, frame_seq_number
+ i
, p
[0], p
[1], p
[2], p
[3]);
1446 osst_get_frame_position(STp
, aSRpnt
);
1449 printk(OSST_DEB_MSG
"%s:D: Frames left in buffer: %d\n", name
, STp
->cur_frames
);
1451 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1452 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1454 for (flag
=1, new_frame
=frame
, p
=buffer
, i
=0; i
< nframes
+ pending
; ) {
1457 if (STp
->write_type
== OS_WRITE_HEADER
) {
1459 p
+= skip
* OS_DATA_SIZE
;
1461 else if (new_frame
< 2990 && new_frame
+skip
+nframes
+pending
>= 2990)
1466 printk(OSST_DEB_MSG
"%s:D: Position to frame %d, write fseq %d\n",
1467 name
, new_frame
+i
, frame_seq_number
+i
);
1469 osst_set_frame_position(STp
, aSRpnt
, new_frame
+ i
, 0);
1470 osst_wait_ready(STp
, aSRpnt
, 60, OSST_WAIT_POSITION_COMPLETE
);
1471 osst_get_frame_position(STp
, aSRpnt
);
1474 if (new_frame
> frame
+ 1000) {
1475 printk(KERN_ERR
"%s:E: Failed to find writable tape media\n", name
);
1479 if ( i
>= nframes
+ pending
) break;
1482 osst_copy_to_buffer(STp
->buffer
, p
);
1484 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1486 osst_init_aux(STp
, STp
->buffer
->aux
->frame_type
, frame_seq_number
+i
,
1487 logical_blk_num
+ i
*blks_per_frame
,
1488 ntohl(STp
->buffer
->aux
->dat
.dat_list
[0].blk_sz
), blks_per_frame
);
1489 memset(cmd
, 0, MAX_COMMAND_SIZE
);
1497 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1498 name
, new_frame
+i
, frame_seq_number
+i
, logical_blk_num
+ i
*blks_per_frame
,
1499 p
[0], p
[1], p
[2], p
[3]);
1501 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, OS_FRAME_SIZE
, DMA_TO_DEVICE
,
1502 STp
->timeout
, MAX_RETRIES
, 1);
1504 if (STp
->buffer
->syscall_result
)
1507 p
+= OS_DATA_SIZE
; i
++;
1509 /* if we just sent the last frame, wait till all successfully written */
1510 if ( i
== nframes
+ pending
) {
1512 printk(OSST_DEB_MSG
"%s:D: Check re-write successful\n", name
);
1514 memset(cmd
, 0, MAX_COMMAND_SIZE
);
1515 cmd
[0] = WRITE_FILEMARKS
;
1517 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, 0, DMA_NONE
,
1518 STp
->timeout
, MAX_RETRIES
, 1);
1521 printk(OSST_DEB_MSG
"%s:D: Sleeping in re-write wait ready\n", name
);
1522 printk(OSST_DEB_MSG
"%s:D: Turning off debugging for a while\n", name
);
1526 flag
= STp
->buffer
->syscall_result
;
1527 while ( !flag
&& time_before(jiffies
, startwait
+ 60*HZ
) ) {
1529 memset(cmd
, 0, MAX_COMMAND_SIZE
);
1530 cmd
[0] = TEST_UNIT_READY
;
1532 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, 0, DMA_NONE
, STp
->timeout
,
1535 if (SRpnt
->sense
[2] == 2 && SRpnt
->sense
[12] == 4 &&
1536 (SRpnt
->sense
[13] == 1 || SRpnt
->sense
[13] == 8)) {
1537 /* in the process of becoming ready */
1541 if (STp
->buffer
->syscall_result
)
1547 printk(OSST_DEB_MSG
"%s:D: Wait re-write finished\n", name
);
1553 if ((SRpnt
->sense
[ 2] & 0x0f) == 13 &&
1554 SRpnt
->sense
[12] == 0 &&
1555 SRpnt
->sense
[13] == 2) {
1556 printk(KERN_ERR
"%s:E: Volume overflow in write error recovery\n", name
);
1558 return (-EIO
); /* hit end of tape = fail */
1560 i
= ((SRpnt
->sense
[3] << 24) |
1561 (SRpnt
->sense
[4] << 16) |
1562 (SRpnt
->sense
[5] << 8) |
1563 SRpnt
->sense
[6] ) - new_frame
;
1564 p
= &buffer
[i
* OS_DATA_SIZE
];
1566 printk(OSST_DEB_MSG
"%s:D: Additional write error at %d\n", name
, new_frame
+i
);
1568 osst_get_frame_position(STp
, aSRpnt
);
1570 printk(OSST_DEB_MSG
"%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1571 name
, STp
->first_frame_position
, STp
->last_frame_position
, STp
->cur_frames
);
1576 /* error recovery did not successfully complete */
1577 printk(KERN_ERR
"%s:D: Write error recovery failed in %s\n", name
,
1578 STp
->write_type
== OS_WRITE_HEADER
?"header":"body");
1581 osst_copy_to_buffer(STp
->buffer
, p
); /* so buffer content == at entry in all cases */
1586 static int osst_reposition_and_retry(struct osst_tape
* STp
, struct osst_request
** aSRpnt
,
1587 unsigned int frame
, unsigned int skip
, int pending
)
1589 unsigned char cmd
[MAX_COMMAND_SIZE
];
1590 struct osst_request
* SRpnt
;
1591 char * name
= tape_name(STp
);
1593 int attempts
= 1000 / skip
;
1595 unsigned long startwait
= jiffies
;
1597 int dbg
= debugging
;
1600 while (attempts
&& time_before(jiffies
, startwait
+ 60*HZ
)) {
1605 if (frame
< 2990 && frame
+skip
+STp
->cur_frames
+pending
>= 2990)
1607 expected
= frame
+skip
+STp
->cur_frames
+pending
;
1609 printk(OSST_DEB_MSG
"%s:D: Position to fppos %d, re-write from fseq %d\n",
1610 name
, frame
+skip
, STp
->frame_seq_number
-STp
->cur_frames
-pending
);
1612 osst_set_frame_position(STp
, aSRpnt
, frame
+ skip
, 1);
1615 schedule_timeout_interruptible(msecs_to_jiffies(100));
1617 if (osst_get_frame_position(STp
, aSRpnt
) < 0) { /* additional write error */
1619 printk(OSST_DEB_MSG
"%s:D: Addl error, host %d, tape %d, buffer %d\n",
1620 name
, STp
->first_frame_position
,
1621 STp
->last_frame_position
, STp
->cur_frames
);
1623 frame
= STp
->last_frame_position
;
1627 if (pending
&& STp
->cur_frames
< 50) {
1629 memset(cmd
, 0, MAX_COMMAND_SIZE
);
1634 printk(OSST_DEB_MSG
"%s:D: About to write pending fseq %d at fppos %d\n",
1635 name
, STp
->frame_seq_number
-1, STp
->first_frame_position
);
1637 SRpnt
= osst_do_scsi(*aSRpnt
, STp
, cmd
, OS_FRAME_SIZE
, DMA_TO_DEVICE
,
1638 STp
->timeout
, MAX_RETRIES
, 1);
1641 if (STp
->buffer
->syscall_result
) { /* additional write error */
1642 if ((SRpnt
->sense
[ 2] & 0x0f) == 13 &&
1643 SRpnt
->sense
[12] == 0 &&
1644 SRpnt
->sense
[13] == 2) {
1646 "%s:E: Volume overflow in write error recovery\n",
1648 break; /* hit end of tape = fail */
1657 if (STp
->cur_frames
== 0) {
1660 printk(OSST_DEB_MSG
"%s:D: Wait re-write finished\n", name
);
1662 if (STp
->first_frame_position
!= expected
) {
1663 printk(KERN_ERR
"%s:A: Actual position %d - expected %d\n",
1664 name
, STp
->first_frame_position
, expected
);
1671 printk(OSST_DEB_MSG
"%s:D: Sleeping in re-write wait ready\n", name
);
1672 printk(OSST_DEB_MSG
"%s:D: Turning off debugging for a while\n", name
);
1676 schedule_timeout_interruptible(msecs_to_jiffies(100));
1678 printk(KERN_ERR
"%s:E: Failed to find valid tape media\n", name
);
1686 * Error recovery algorithm for the OnStream tape.
1689 static int osst_write_error_recovery(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int pending
)
1691 struct osst_request
* SRpnt
= * aSRpnt
;
1692 struct st_partstat
* STps
= & STp
->ps
[STp
->partition
];
1693 char * name
= tape_name(STp
);
1696 unsigned int frame
, skip
;
1698 rw_state
= STps
->rw
;
1700 if ((SRpnt
->sense
[ 2] & 0x0f) != 3
1701 || SRpnt
->sense
[12] != 12
1702 || SRpnt
->sense
[13] != 0) {
1704 printk(OSST_DEB_MSG
"%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name
,
1705 SRpnt
->sense
[2], SRpnt
->sense
[12], SRpnt
->sense
[13]);
1709 frame
= (SRpnt
->sense
[3] << 24) |
1710 (SRpnt
->sense
[4] << 16) |
1711 (SRpnt
->sense
[5] << 8) |
1713 skip
= SRpnt
->sense
[9];
1716 printk(OSST_DEB_MSG
"%s:D: Detected physical bad frame at %u, advised to skip %d\n", name
, frame
, skip
);
1718 osst_get_frame_position(STp
, aSRpnt
);
1720 printk(OSST_DEB_MSG
"%s:D: reported frame positions: host = %d, tape = %d\n",
1721 name
, STp
->first_frame_position
, STp
->last_frame_position
);
1723 switch (STp
->write_type
) {
1726 case OS_WRITE_NEW_MARK
:
1728 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1729 name
, STp
->cur_frames
, frame
, (frame
+ skip
> 3000 && frame
< 3000)?3000:frame
+ skip
);
1730 if (STp
->os_fw_rev
>= 10600)
1731 retval
= osst_reposition_and_retry(STp
, aSRpnt
, frame
, skip
, pending
);
1733 retval
= osst_read_back_buffer_and_rewrite(STp
, aSRpnt
, frame
, skip
, pending
);
1734 printk(KERN_WARNING
"%s:%s: %sWrite error%srecovered\n", name
,
1736 retval
?"" :"Don't worry, ",
1737 retval
?" not ":" ");
1739 case OS_WRITE_LAST_MARK
:
1740 printk(KERN_ERR
"%s:E: Bad frame in update last marker, fatal\n", name
);
1741 osst_set_frame_position(STp
, aSRpnt
, frame
+ STp
->cur_frames
+ pending
, 0);
1744 case OS_WRITE_HEADER
:
1745 printk(KERN_WARNING
"%s:I: Bad frame in header partition, skipped\n", name
);
1746 retval
= osst_read_back_buffer_and_rewrite(STp
, aSRpnt
, frame
, 1, pending
);
1749 printk(KERN_INFO
"%s:I: Bad frame in filler, ignored\n", name
);
1750 osst_set_frame_position(STp
, aSRpnt
, frame
+ STp
->cur_frames
+ pending
, 0);
1752 osst_get_frame_position(STp
, aSRpnt
);
1754 printk(OSST_DEB_MSG
"%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1755 name
, STp
->cur_frames
, STp
->first_frame_position
, STp
->last_frame_position
);
1756 printk(OSST_DEB_MSG
"%s:D: next logical frame to write: %d\n", name
, STp
->logical_blk_num
);
1759 STp
->recover_count
++;
1760 STp
->recover_erreg
++;
1764 STps
->rw
= rw_state
;
1768 static int osst_space_over_filemarks_backward(struct osst_tape
* STp
, struct osst_request
** aSRpnt
,
1769 int mt_op
, int mt_count
)
1771 char * name
= tape_name(STp
);
1773 int last_mark_ppos
= -1;
1776 printk(OSST_DEB_MSG
"%s:D: Reached space_over_filemarks_backwards %d %d\n", name
, mt_op
, mt_count
);
1778 if (osst_get_logical_frame(STp
, aSRpnt
, -1, 0) < 0) {
1780 printk(OSST_DEB_MSG
"%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name
);
1784 if (STp
->linux_media_version
>= 4) {
1786 * direct lookup in header filemark list
1788 cnt
= ntohl(STp
->buffer
->aux
->filemark_cnt
);
1789 if (STp
->header_ok
&&
1790 STp
->header_cache
!= NULL
&&
1791 (cnt
- mt_count
) >= 0 &&
1792 (cnt
- mt_count
) < OS_FM_TAB_MAX
&&
1793 (cnt
- mt_count
) < STp
->filemark_cnt
&&
1794 STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[cnt
-1] == STp
->buffer
->aux
->last_mark_ppos
)
1796 last_mark_ppos
= ntohl(STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[cnt
- mt_count
]);
1798 if (STp
->header_cache
== NULL
|| (cnt
- mt_count
) < 0 || (cnt
- mt_count
) >= OS_FM_TAB_MAX
)
1799 printk(OSST_DEB_MSG
"%s:D: Filemark lookup fail due to %s\n", name
,
1800 STp
->header_cache
== NULL
?"lack of header cache":"count out of range");
1802 printk(OSST_DEB_MSG
"%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1804 ((cnt
== -1 && ntohl(STp
->buffer
->aux
->last_mark_ppos
) == -1) ||
1805 (STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[cnt
-1] ==
1806 STp
->buffer
->aux
->last_mark_ppos
))?"match":"error",
1807 mt_count
, last_mark_ppos
);
1809 if (last_mark_ppos
> 10 && last_mark_ppos
< STp
->eod_frame_ppos
) {
1810 osst_position_tape_and_confirm(STp
, aSRpnt
, last_mark_ppos
);
1811 if (osst_get_logical_frame(STp
, aSRpnt
, -1, 0) < 0) {
1814 "%s:D: Couldn't get logical blk num in space_filemarks\n", name
);
1818 if (STp
->buffer
->aux
->frame_type
!= OS_FRAME_TYPE_MARKER
) {
1819 printk(KERN_WARNING
"%s:W: Expected to find marker at ppos %d, not found\n",
1820 name
, last_mark_ppos
);
1826 printk(OSST_DEB_MSG
"%s:D: Reverting to scan filemark backwards\n", name
);
1830 while (cnt
!= mt_count
) {
1831 last_mark_ppos
= ntohl(STp
->buffer
->aux
->last_mark_ppos
);
1832 if (last_mark_ppos
== -1)
1835 printk(OSST_DEB_MSG
"%s:D: Positioning to last mark at %d\n", name
, last_mark_ppos
);
1837 osst_position_tape_and_confirm(STp
, aSRpnt
, last_mark_ppos
);
1839 if (osst_get_logical_frame(STp
, aSRpnt
, -1, 0) < 0) {
1841 printk(OSST_DEB_MSG
"%s:D: Couldn't get logical blk num in space_filemarks\n", name
);
1845 if (STp
->buffer
->aux
->frame_type
!= OS_FRAME_TYPE_MARKER
) {
1846 printk(KERN_WARNING
"%s:W: Expected to find marker at ppos %d, not found\n",
1847 name
, last_mark_ppos
);
1852 if (mt_op
== MTBSFM
) {
1853 STp
->frame_seq_number
++;
1854 STp
->frame_in_buffer
= 0;
1855 STp
->buffer
->buffer_bytes
= 0;
1856 STp
->buffer
->read_pointer
= 0;
1857 STp
->logical_blk_num
+= ntohs(STp
->buffer
->aux
->dat
.dat_list
[0].blk_cnt
);
1863 * ADRL 1.1 compatible "slow" space filemarks fwd version
1865 * Just scans for the filemark sequentially.
1867 static int osst_space_over_filemarks_forward_slow(struct osst_tape
* STp
, struct osst_request
** aSRpnt
,
1868 int mt_op
, int mt_count
)
1872 char * name
= tape_name(STp
);
1874 printk(OSST_DEB_MSG
"%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name
, mt_op
, mt_count
);
1876 if (osst_get_logical_frame(STp
, aSRpnt
, -1, 0) < 0) {
1878 printk(OSST_DEB_MSG
"%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name
);
1883 if (osst_get_logical_frame(STp
, aSRpnt
, -1, 0) < 0) {
1885 printk(OSST_DEB_MSG
"%s:D: Couldn't get logical blk num in space_filemarks\n", name
);
1889 if (STp
->buffer
->aux
->frame_type
== OS_FRAME_TYPE_MARKER
)
1891 if (STp
->buffer
->aux
->frame_type
== OS_FRAME_TYPE_EOD
) {
1893 printk(OSST_DEB_MSG
"%s:D: space_fwd: EOD reached\n", name
);
1895 if (STp
->first_frame_position
> STp
->eod_frame_ppos
+1) {
1897 printk(OSST_DEB_MSG
"%s:D: EOD position corrected (%d=>%d)\n",
1898 name
, STp
->eod_frame_ppos
, STp
->first_frame_position
-1);
1900 STp
->eod_frame_ppos
= STp
->first_frame_position
-1;
1904 if (cnt
== mt_count
)
1906 STp
->frame_in_buffer
= 0;
1908 if (mt_op
== MTFSF
) {
1909 STp
->frame_seq_number
++;
1910 STp
->frame_in_buffer
= 0;
1911 STp
->buffer
->buffer_bytes
= 0;
1912 STp
->buffer
->read_pointer
= 0;
1913 STp
->logical_blk_num
+= ntohs(STp
->buffer
->aux
->dat
.dat_list
[0].blk_cnt
);
1919 * Fast linux specific version of OnStream FSF
1921 static int osst_space_over_filemarks_forward_fast(struct osst_tape
* STp
, struct osst_request
** aSRpnt
,
1922 int mt_op
, int mt_count
)
1924 char * name
= tape_name(STp
);
1926 next_mark_ppos
= -1;
1929 printk(OSST_DEB_MSG
"%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name
, mt_op
, mt_count
);
1931 if (osst_get_logical_frame(STp
, aSRpnt
, -1, 0) < 0) {
1933 printk(OSST_DEB_MSG
"%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name
);
1938 if (STp
->linux_media_version
>= 4) {
1940 * direct lookup in header filemark list
1942 cnt
= ntohl(STp
->buffer
->aux
->filemark_cnt
) - 1;
1943 if (STp
->header_ok
&&
1944 STp
->header_cache
!= NULL
&&
1945 (cnt
+ mt_count
) < OS_FM_TAB_MAX
&&
1946 (cnt
+ mt_count
) < STp
->filemark_cnt
&&
1947 ((cnt
== -1 && ntohl(STp
->buffer
->aux
->last_mark_ppos
) == -1) ||
1948 (STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[cnt
] == STp
->buffer
->aux
->last_mark_ppos
)))
1950 next_mark_ppos
= ntohl(STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[cnt
+ mt_count
]);
1952 if (STp
->header_cache
== NULL
|| (cnt
+ mt_count
) >= OS_FM_TAB_MAX
)
1953 printk(OSST_DEB_MSG
"%s:D: Filemark lookup fail due to %s\n", name
,
1954 STp
->header_cache
== NULL
?"lack of header cache":"count out of range");
1956 printk(OSST_DEB_MSG
"%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1958 ((cnt
== -1 && ntohl(STp
->buffer
->aux
->last_mark_ppos
) == -1) ||
1959 (STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[cnt
] ==
1960 STp
->buffer
->aux
->last_mark_ppos
))?"match":"error",
1961 mt_count
, next_mark_ppos
);
1963 if (next_mark_ppos
<= 10 || next_mark_ppos
> STp
->eod_frame_ppos
) {
1965 printk(OSST_DEB_MSG
"%s:D: Reverting to slow filemark space\n", name
);
1967 return osst_space_over_filemarks_forward_slow(STp
, aSRpnt
, mt_op
, mt_count
);
1969 osst_position_tape_and_confirm(STp
, aSRpnt
, next_mark_ppos
);
1970 if (osst_get_logical_frame(STp
, aSRpnt
, -1, 0) < 0) {
1972 printk(OSST_DEB_MSG
"%s:D: Couldn't get logical blk num in space_filemarks\n",
1977 if (STp
->buffer
->aux
->frame_type
!= OS_FRAME_TYPE_MARKER
) {
1978 printk(KERN_WARNING
"%s:W: Expected to find marker at ppos %d, not found\n",
1979 name
, next_mark_ppos
);
1982 if (ntohl(STp
->buffer
->aux
->filemark_cnt
) != cnt
+ mt_count
) {
1983 printk(KERN_WARNING
"%s:W: Expected to find marker %d at ppos %d, not %d\n",
1984 name
, cnt
+mt_count
, next_mark_ppos
,
1985 ntohl(STp
->buffer
->aux
->filemark_cnt
));
1991 * Find nearest (usually previous) marker, then jump from marker to marker
1994 if (STp
->buffer
->aux
->frame_type
== OS_FRAME_TYPE_MARKER
)
1996 if (STp
->buffer
->aux
->frame_type
== OS_FRAME_TYPE_EOD
) {
1998 printk(OSST_DEB_MSG
"%s:D: space_fwd: EOD reached\n", name
);
2002 if (ntohl(STp
->buffer
->aux
->filemark_cnt
) == 0) {
2003 if (STp
->first_mark_ppos
== -1) {
2005 printk(OSST_DEB_MSG
"%s:D: Reverting to slow filemark space\n", name
);
2007 return osst_space_over_filemarks_forward_slow(STp
, aSRpnt
, mt_op
, mt_count
);
2009 osst_position_tape_and_confirm(STp
, aSRpnt
, STp
->first_mark_ppos
);
2010 if (osst_get_logical_frame(STp
, aSRpnt
, -1, 0) < 0) {
2013 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2018 if (STp
->buffer
->aux
->frame_type
!= OS_FRAME_TYPE_MARKER
) {
2019 printk(KERN_WARNING
"%s:W: Expected to find filemark at %d\n",
2020 name
, STp
->first_mark_ppos
);
2024 if (osst_space_over_filemarks_backward(STp
, aSRpnt
, MTBSF
, 1) < 0)
2030 while (cnt
!= mt_count
) {
2031 next_mark_ppos
= ntohl(STp
->buffer
->aux
->next_mark_ppos
);
2032 if (!next_mark_ppos
|| next_mark_ppos
> STp
->eod_frame_ppos
) {
2034 printk(OSST_DEB_MSG
"%s:D: Reverting to slow filemark space\n", name
);
2036 return osst_space_over_filemarks_forward_slow(STp
, aSRpnt
, mt_op
, mt_count
- cnt
);
2039 else printk(OSST_DEB_MSG
"%s:D: Positioning to next mark at %d\n", name
, next_mark_ppos
);
2041 osst_position_tape_and_confirm(STp
, aSRpnt
, next_mark_ppos
);
2043 if (osst_get_logical_frame(STp
, aSRpnt
, -1, 0) < 0) {
2045 printk(OSST_DEB_MSG
"%s:D: Couldn't get logical blk num in space_filemarks\n",
2050 if (STp
->buffer
->aux
->frame_type
!= OS_FRAME_TYPE_MARKER
) {
2051 printk(KERN_WARNING
"%s:W: Expected to find marker at ppos %d, not found\n",
2052 name
, next_mark_ppos
);
2057 if (mt_op
== MTFSF
) {
2058 STp
->frame_seq_number
++;
2059 STp
->frame_in_buffer
= 0;
2060 STp
->buffer
->buffer_bytes
= 0;
2061 STp
->buffer
->read_pointer
= 0;
2062 STp
->logical_blk_num
+= ntohs(STp
->buffer
->aux
->dat
.dat_list
[0].blk_cnt
);
2068 * In debug mode, we want to see as many errors as possible
2069 * to test the error recovery mechanism.
2072 static void osst_set_retries(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int retries
)
2074 unsigned char cmd
[MAX_COMMAND_SIZE
];
2075 struct osst_request
* SRpnt
= * aSRpnt
;
2076 char * name
= tape_name(STp
);
2078 memset(cmd
, 0, MAX_COMMAND_SIZE
);
2079 cmd
[0] = MODE_SELECT
;
2081 cmd
[4] = NUMBER_RETRIES_PAGE_LENGTH
+ MODE_HEADER_LENGTH
;
2083 (STp
->buffer
)->b_data
[0] = cmd
[4] - 1;
2084 (STp
->buffer
)->b_data
[1] = 0; /* Medium Type - ignoring */
2085 (STp
->buffer
)->b_data
[2] = 0; /* Reserved */
2086 (STp
->buffer
)->b_data
[3] = 0; /* Block Descriptor Length */
2087 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 0] = NUMBER_RETRIES_PAGE
| (1 << 7);
2088 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 1] = 2;
2089 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 2] = 4;
2090 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 3] = retries
;
2093 printk(OSST_DEB_MSG
"%s:D: Setting number of retries on OnStream tape to %d\n", name
, retries
);
2095 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, cmd
[4], DMA_TO_DEVICE
, STp
->timeout
, 0, 1);
2098 if ((STp
->buffer
)->syscall_result
)
2099 printk (KERN_ERR
"%s:D: Couldn't set retries to %d\n", name
, retries
);
2104 static int osst_write_filemark(struct osst_tape
* STp
, struct osst_request
** aSRpnt
)
2107 int this_mark_ppos
= STp
->first_frame_position
;
2108 int this_mark_lbn
= STp
->logical_blk_num
;
2110 char * name
= tape_name(STp
);
2113 if (STp
->raw
) return 0;
2115 STp
->write_type
= OS_WRITE_NEW_MARK
;
2117 printk(OSST_DEB_MSG
"%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2118 name
, STp
->filemark_cnt
, this_mark_ppos
, STp
->frame_seq_number
, this_mark_lbn
);
2121 result
= osst_flush_write_buffer(STp
, aSRpnt
);
2122 result
|= osst_flush_drive_buffer(STp
, aSRpnt
);
2123 STp
->last_mark_ppos
= this_mark_ppos
;
2124 STp
->last_mark_lbn
= this_mark_lbn
;
2125 if (STp
->header_cache
!= NULL
&& STp
->filemark_cnt
< OS_FM_TAB_MAX
)
2126 STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[STp
->filemark_cnt
] = htonl(this_mark_ppos
);
2127 if (STp
->filemark_cnt
++ == 0)
2128 STp
->first_mark_ppos
= this_mark_ppos
;
2132 static int osst_write_eod(struct osst_tape
* STp
, struct osst_request
** aSRpnt
)
2136 char * name
= tape_name(STp
);
2139 if (STp
->raw
) return 0;
2141 STp
->write_type
= OS_WRITE_EOD
;
2142 STp
->eod_frame_ppos
= STp
->first_frame_position
;
2144 printk(OSST_DEB_MSG
"%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name
,
2145 STp
->eod_frame_ppos
, STp
->frame_seq_number
, STp
->logical_blk_num
);
2149 result
= osst_flush_write_buffer(STp
, aSRpnt
);
2150 result
|= osst_flush_drive_buffer(STp
, aSRpnt
);
2151 STp
->eod_frame_lfa
= --(STp
->frame_seq_number
);
2155 static int osst_write_filler(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int where
, int count
)
2157 char * name
= tape_name(STp
);
2160 printk(OSST_DEB_MSG
"%s:D: Reached onstream write filler group %d\n", name
, where
);
2162 osst_wait_ready(STp
, aSRpnt
, 60 * 5, 0);
2163 osst_set_frame_position(STp
, aSRpnt
, where
, 0);
2164 STp
->write_type
= OS_WRITE_FILLER
;
2166 memcpy(STp
->buffer
->b_data
, "Filler", 6);
2167 STp
->buffer
->buffer_bytes
= 6;
2169 if (osst_flush_write_buffer(STp
, aSRpnt
)) {
2170 printk(KERN_INFO
"%s:I: Couldn't write filler frame\n", name
);
2175 printk(OSST_DEB_MSG
"%s:D: Exiting onstream write filler group\n", name
);
2177 return osst_flush_drive_buffer(STp
, aSRpnt
);
2180 static int __osst_write_header(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int where
, int count
)
2182 char * name
= tape_name(STp
);
2186 printk(OSST_DEB_MSG
"%s:D: Reached onstream write header group %d\n", name
, where
);
2188 osst_wait_ready(STp
, aSRpnt
, 60 * 5, 0);
2189 osst_set_frame_position(STp
, aSRpnt
, where
, 0);
2190 STp
->write_type
= OS_WRITE_HEADER
;
2192 osst_copy_to_buffer(STp
->buffer
, (unsigned char *)STp
->header_cache
);
2193 STp
->buffer
->buffer_bytes
= sizeof(os_header_t
);
2195 if (osst_flush_write_buffer(STp
, aSRpnt
)) {
2196 printk(KERN_INFO
"%s:I: Couldn't write header frame\n", name
);
2200 result
= osst_flush_drive_buffer(STp
, aSRpnt
);
2202 printk(OSST_DEB_MSG
"%s:D: Write onstream header group %s\n", name
, result
?"failed":"done");
2207 static int osst_write_header(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int locate_eod
)
2209 os_header_t
* header
;
2211 char * name
= tape_name(STp
);
2214 printk(OSST_DEB_MSG
"%s:D: Writing tape header\n", name
);
2216 if (STp
->raw
) return 0;
2218 if (STp
->header_cache
== NULL
) {
2219 if ((STp
->header_cache
= (os_header_t
*)vmalloc(sizeof(os_header_t
))) == NULL
) {
2220 printk(KERN_ERR
"%s:E: Failed to allocate header cache\n", name
);
2223 memset(STp
->header_cache
, 0, sizeof(os_header_t
));
2225 printk(OSST_DEB_MSG
"%s:D: Allocated and cleared memory for header cache\n", name
);
2228 if (STp
->header_ok
) STp
->update_frame_cntr
++;
2229 else STp
->update_frame_cntr
= 0;
2231 header
= STp
->header_cache
;
2232 strcpy(header
->ident_str
, "ADR_SEQ");
2233 header
->major_rev
= 1;
2234 header
->minor_rev
= 4;
2235 header
->ext_trk_tb_off
= htons(17192);
2236 header
->pt_par_num
= 1;
2237 header
->partition
[0].partition_num
= OS_DATA_PARTITION
;
2238 header
->partition
[0].par_desc_ver
= OS_PARTITION_VERSION
;
2239 header
->partition
[0].wrt_pass_cntr
= htons(STp
->wrt_pass_cntr
);
2240 header
->partition
[0].first_frame_ppos
= htonl(STp
->first_data_ppos
);
2241 header
->partition
[0].last_frame_ppos
= htonl(STp
->capacity
);
2242 header
->partition
[0].eod_frame_ppos
= htonl(STp
->eod_frame_ppos
);
2243 header
->cfg_col_width
= htonl(20);
2244 header
->dat_col_width
= htonl(1500);
2245 header
->qfa_col_width
= htonl(0);
2246 header
->ext_track_tb
.nr_stream_part
= 1;
2247 header
->ext_track_tb
.et_ent_sz
= 32;
2248 header
->ext_track_tb
.dat_ext_trk_ey
.et_part_num
= 0;
2249 header
->ext_track_tb
.dat_ext_trk_ey
.fmt
= 1;
2250 header
->ext_track_tb
.dat_ext_trk_ey
.fm_tab_off
= htons(17736);
2251 header
->ext_track_tb
.dat_ext_trk_ey
.last_hlb_hi
= 0;
2252 header
->ext_track_tb
.dat_ext_trk_ey
.last_hlb
= htonl(STp
->eod_frame_lfa
);
2253 header
->ext_track_tb
.dat_ext_trk_ey
.last_pp
= htonl(STp
->eod_frame_ppos
);
2254 header
->dat_fm_tab
.fm_part_num
= 0;
2255 header
->dat_fm_tab
.fm_tab_ent_sz
= 4;
2256 header
->dat_fm_tab
.fm_tab_ent_cnt
= htons(STp
->filemark_cnt
<OS_FM_TAB_MAX
?
2257 STp
->filemark_cnt
:OS_FM_TAB_MAX
);
2259 result
= __osst_write_header(STp
, aSRpnt
, 0xbae, 5);
2260 if (STp
->update_frame_cntr
== 0)
2261 osst_write_filler(STp
, aSRpnt
, 0xbb3, 5);
2262 result
&= __osst_write_header(STp
, aSRpnt
, 5, 5);
2266 printk(OSST_DEB_MSG
"%s:D: Locating back to eod frame addr %d\n", name
, STp
->eod_frame_ppos
);
2268 osst_set_frame_position(STp
, aSRpnt
, STp
->eod_frame_ppos
, 0);
2271 printk(KERN_ERR
"%s:E: Write header failed\n", name
);
2273 memcpy(STp
->application_sig
, "LIN4", 4);
2274 STp
->linux_media
= 1;
2275 STp
->linux_media_version
= 4;
2281 static int osst_reset_header(struct osst_tape
* STp
, struct osst_request
** aSRpnt
)
2283 if (STp
->header_cache
!= NULL
)
2284 memset(STp
->header_cache
, 0, sizeof(os_header_t
));
2286 STp
->logical_blk_num
= STp
->frame_seq_number
= 0;
2287 STp
->frame_in_buffer
= 0;
2288 STp
->eod_frame_ppos
= STp
->first_data_ppos
= 0x0000000A;
2289 STp
->filemark_cnt
= 0;
2290 STp
->first_mark_ppos
= STp
->last_mark_ppos
= STp
->last_mark_lbn
= -1;
2291 return osst_write_header(STp
, aSRpnt
, 1);
2294 static int __osst_analyze_headers(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int ppos
)
2296 char * name
= tape_name(STp
);
2297 os_header_t
* header
;
2300 int linux_media_version
,
2306 if (ppos
== 5 || ppos
== 0xbae || STp
->buffer
->syscall_result
) {
2307 if (osst_set_frame_position(STp
, aSRpnt
, ppos
, 0))
2308 printk(KERN_WARNING
"%s:W: Couldn't position tape\n", name
);
2309 osst_wait_ready(STp
, aSRpnt
, 60 * 15, 0);
2310 if (osst_initiate_read (STp
, aSRpnt
)) {
2311 printk(KERN_WARNING
"%s:W: Couldn't initiate read\n", name
);
2315 if (osst_read_frame(STp
, aSRpnt
, 180)) {
2317 printk(OSST_DEB_MSG
"%s:D: Couldn't read header frame\n", name
);
2321 header
= (os_header_t
*) STp
->buffer
->b_data
; /* warning: only first segment addressable */
2322 aux
= STp
->buffer
->aux
;
2323 if (aux
->frame_type
!= OS_FRAME_TYPE_HEADER
) {
2325 printk(OSST_DEB_MSG
"%s:D: Skipping non-header frame (%d)\n", name
, ppos
);
2329 if (ntohl(aux
->frame_seq_num
) != 0 ||
2330 ntohl(aux
->logical_blk_num
) != 0 ||
2331 aux
->partition
.partition_num
!= OS_CONFIG_PARTITION
||
2332 ntohl(aux
->partition
.first_frame_ppos
) != 0 ||
2333 ntohl(aux
->partition
.last_frame_ppos
) != 0xbb7 ) {
2335 printk(OSST_DEB_MSG
"%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name
,
2336 ntohl(aux
->frame_seq_num
), ntohl(aux
->logical_blk_num
),
2337 aux
->partition
.partition_num
, ntohl(aux
->partition
.first_frame_ppos
),
2338 ntohl(aux
->partition
.last_frame_ppos
));
2342 if (strncmp(header
->ident_str
, "ADR_SEQ", 7) != 0 &&
2343 strncmp(header
->ident_str
, "ADR-SEQ", 7) != 0) {
2344 strlcpy(id_string
, header
->ident_str
, 8);
2346 printk(OSST_DEB_MSG
"%s:D: Invalid header identification string %s\n", name
, id_string
);
2350 update_frame_cntr
= ntohl(aux
->update_frame_cntr
);
2351 if (update_frame_cntr
< STp
->update_frame_cntr
) {
2353 printk(OSST_DEB_MSG
"%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2354 name
, ppos
, update_frame_cntr
, STp
->update_frame_cntr
);
2358 if (header
->major_rev
!= 1 || header
->minor_rev
!= 4 ) {
2360 printk(OSST_DEB_MSG
"%s:D: %s revision %d.%d detected (1.4 supported)\n",
2361 name
, (header
->major_rev
!= 1 || header
->minor_rev
< 2 ||
2362 header
->minor_rev
> 4 )? "Invalid" : "Warning:",
2363 header
->major_rev
, header
->minor_rev
);
2365 if (header
->major_rev
!= 1 || header
->minor_rev
< 2 || header
->minor_rev
> 4)
2369 if (header
->pt_par_num
!= 1)
2370 printk(KERN_INFO
"%s:W: %d partitions defined, only one supported\n",
2371 name
, header
->pt_par_num
);
2373 memcpy(id_string
, aux
->application_sig
, 4);
2375 if (memcmp(id_string
, "LIN", 3) == 0) {
2376 STp
->linux_media
= 1;
2377 linux_media_version
= id_string
[3] - '0';
2378 if (linux_media_version
!= 4)
2379 printk(KERN_INFO
"%s:I: Linux media version %d detected (current 4)\n",
2380 name
, linux_media_version
);
2382 printk(KERN_WARNING
"%s:W: Non Linux media detected (%s)\n", name
, id_string
);
2385 if (linux_media_version
< STp
->linux_media_version
) {
2387 printk(OSST_DEB_MSG
"%s:D: Skipping frame %d with linux_media_version %d\n",
2388 name
, ppos
, linux_media_version
);
2392 if (linux_media_version
> STp
->linux_media_version
) {
2394 printk(OSST_DEB_MSG
"%s:D: Frame %d sets linux_media_version to %d\n",
2395 name
, ppos
, linux_media_version
);
2397 memcpy(STp
->application_sig
, id_string
, 5);
2398 STp
->linux_media_version
= linux_media_version
;
2399 STp
->update_frame_cntr
= -1;
2401 if (update_frame_cntr
> STp
->update_frame_cntr
) {
2403 printk(OSST_DEB_MSG
"%s:D: Frame %d sets update_frame_counter to %d\n",
2404 name
, ppos
, update_frame_cntr
);
2406 if (STp
->header_cache
== NULL
) {
2407 if ((STp
->header_cache
= (os_header_t
*)vmalloc(sizeof(os_header_t
))) == NULL
) {
2408 printk(KERN_ERR
"%s:E: Failed to allocate header cache\n", name
);
2412 printk(OSST_DEB_MSG
"%s:D: Allocated memory for header cache\n", name
);
2415 osst_copy_from_buffer(STp
->buffer
, (unsigned char *)STp
->header_cache
);
2416 header
= STp
->header_cache
; /* further accesses from cached (full) copy */
2418 STp
->wrt_pass_cntr
= ntohs(header
->partition
[0].wrt_pass_cntr
);
2419 STp
->first_data_ppos
= ntohl(header
->partition
[0].first_frame_ppos
);
2420 STp
->eod_frame_ppos
= ntohl(header
->partition
[0].eod_frame_ppos
);
2421 STp
->eod_frame_lfa
= ntohl(header
->ext_track_tb
.dat_ext_trk_ey
.last_hlb
);
2422 STp
->filemark_cnt
= ntohl(aux
->filemark_cnt
);
2423 STp
->first_mark_ppos
= ntohl(aux
->next_mark_ppos
);
2424 STp
->last_mark_ppos
= ntohl(aux
->last_mark_ppos
);
2425 STp
->last_mark_lbn
= ntohl(aux
->last_mark_lbn
);
2426 STp
->update_frame_cntr
= update_frame_cntr
;
2428 printk(OSST_DEB_MSG
"%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2429 name
, STp
->wrt_pass_cntr
, STp
->update_frame_cntr
, STp
->filemark_cnt
);
2430 printk(OSST_DEB_MSG
"%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name
,
2431 STp
->first_data_ppos
,
2432 ntohl(header
->partition
[0].last_frame_ppos
),
2433 ntohl(header
->partition
[0].eod_frame_ppos
));
2434 printk(OSST_DEB_MSG
"%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2435 name
, STp
->first_mark_ppos
, STp
->last_mark_ppos
, STp
->eod_frame_ppos
);
2437 if (header
->minor_rev
< 4 && STp
->linux_media_version
== 4) {
2439 printk(OSST_DEB_MSG
"%s:D: Moving filemark list to ADR 1.4 location\n", name
);
2441 memcpy((void *)header
->dat_fm_tab
.fm_tab_ent
,
2442 (void *)header
->old_filemark_list
, sizeof(header
->dat_fm_tab
.fm_tab_ent
));
2443 memset((void *)header
->old_filemark_list
, 0, sizeof(header
->old_filemark_list
));
2445 if (header
->minor_rev
== 4 &&
2446 (header
->ext_trk_tb_off
!= htons(17192) ||
2447 header
->partition
[0].partition_num
!= OS_DATA_PARTITION
||
2448 header
->partition
[0].par_desc_ver
!= OS_PARTITION_VERSION
||
2449 header
->partition
[0].last_frame_ppos
!= htonl(STp
->capacity
) ||
2450 header
->cfg_col_width
!= htonl(20) ||
2451 header
->dat_col_width
!= htonl(1500) ||
2452 header
->qfa_col_width
!= htonl(0) ||
2453 header
->ext_track_tb
.nr_stream_part
!= 1 ||
2454 header
->ext_track_tb
.et_ent_sz
!= 32 ||
2455 header
->ext_track_tb
.dat_ext_trk_ey
.et_part_num
!= OS_DATA_PARTITION
||
2456 header
->ext_track_tb
.dat_ext_trk_ey
.fmt
!= 1 ||
2457 header
->ext_track_tb
.dat_ext_trk_ey
.fm_tab_off
!= htons(17736) ||
2458 header
->ext_track_tb
.dat_ext_trk_ey
.last_hlb_hi
!= 0 ||
2459 header
->ext_track_tb
.dat_ext_trk_ey
.last_pp
!= htonl(STp
->eod_frame_ppos
) ||
2460 header
->dat_fm_tab
.fm_part_num
!= OS_DATA_PARTITION
||
2461 header
->dat_fm_tab
.fm_tab_ent_sz
!= 4 ||
2462 header
->dat_fm_tab
.fm_tab_ent_cnt
!=
2463 htons(STp
->filemark_cnt
<OS_FM_TAB_MAX
?STp
->filemark_cnt
:OS_FM_TAB_MAX
)))
2464 printk(KERN_WARNING
"%s:W: Failed consistency check ADR 1.4 format\n", name
);
2471 static int osst_analyze_headers(struct osst_tape
* STp
, struct osst_request
** aSRpnt
)
2476 char * name
= tape_name(STp
);
2478 position
= osst_get_frame_position(STp
, aSRpnt
);
2481 STp
->header_ok
= STp
->linux_media
= 1;
2482 STp
->linux_media_version
= 0;
2485 STp
->header_ok
= STp
->linux_media
= STp
->linux_media_version
= 0;
2486 STp
->wrt_pass_cntr
= STp
->update_frame_cntr
= -1;
2487 STp
->eod_frame_ppos
= STp
->first_data_ppos
= -1;
2488 STp
->first_mark_ppos
= STp
->last_mark_ppos
= STp
->last_mark_lbn
= -1;
2490 printk(OSST_DEB_MSG
"%s:D: Reading header\n", name
);
2493 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2494 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2496 first
= position
==10?0xbae: 5;
2497 last
= position
==10?0xbb3:10;
2499 for (ppos
= first
; ppos
< last
; ppos
++)
2500 if (__osst_analyze_headers(STp
, aSRpnt
, ppos
))
2503 first
= position
==10? 5:0xbae;
2504 last
= position
==10?10:0xbb3;
2506 for (ppos
= first
; ppos
< last
; ppos
++)
2507 if (__osst_analyze_headers(STp
, aSRpnt
, ppos
))
2511 printk(KERN_ERR
"%s:E: Failed to find valid ADRL header, new media?\n", name
);
2512 STp
->eod_frame_ppos
= STp
->first_data_ppos
= 0;
2513 osst_set_frame_position(STp
, aSRpnt
, 10, 0);
2516 if (position
<= STp
->first_data_ppos
) {
2517 position
= STp
->first_data_ppos
;
2518 STp
->ps
[0].drv_file
= STp
->ps
[0].drv_block
= STp
->frame_seq_number
= STp
->logical_blk_num
= 0;
2520 osst_set_frame_position(STp
, aSRpnt
, position
, 0);
2526 static int osst_verify_position(struct osst_tape
* STp
, struct osst_request
** aSRpnt
)
2528 int frame_position
= STp
->first_frame_position
;
2529 int frame_seq_numbr
= STp
->frame_seq_number
;
2530 int logical_blk_num
= STp
->logical_blk_num
;
2531 int halfway_frame
= STp
->frame_in_buffer
;
2532 int read_pointer
= STp
->buffer
->read_pointer
;
2533 int prev_mark_ppos
= -1;
2534 int actual_mark_ppos
, i
, n
;
2536 char * name
= tape_name(STp
);
2538 printk(OSST_DEB_MSG
"%s:D: Verify that the tape is really the one we think before writing\n", name
);
2540 osst_set_frame_position(STp
, aSRpnt
, frame_position
- 1, 0);
2541 if (osst_get_logical_frame(STp
, aSRpnt
, -1, 0) < 0) {
2543 printk(OSST_DEB_MSG
"%s:D: Couldn't get logical blk num in verify_position\n", name
);
2547 if (STp
->linux_media_version
>= 4) {
2548 for (i
=0; i
<STp
->filemark_cnt
; i
++)
2549 if ((n
=ntohl(STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[i
])) < frame_position
)
2552 prev_mark_ppos
= frame_position
- 1; /* usually - we don't really know */
2553 actual_mark_ppos
= STp
->buffer
->aux
->frame_type
== OS_FRAME_TYPE_MARKER
?
2554 frame_position
- 1 : ntohl(STp
->buffer
->aux
->last_mark_ppos
);
2555 if (frame_position
!= STp
->first_frame_position
||
2556 frame_seq_numbr
!= STp
->frame_seq_number
+ (halfway_frame
?0:1) ||
2557 prev_mark_ppos
!= actual_mark_ppos
) {
2559 printk(OSST_DEB_MSG
"%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name
,
2560 STp
->first_frame_position
, frame_position
,
2561 STp
->frame_seq_number
+ (halfway_frame
?0:1),
2562 frame_seq_numbr
, actual_mark_ppos
, prev_mark_ppos
);
2566 if (halfway_frame
) {
2567 /* prepare buffer for append and rewrite on top of original */
2568 osst_set_frame_position(STp
, aSRpnt
, frame_position
- 1, 0);
2569 STp
->buffer
->buffer_bytes
= read_pointer
;
2570 STp
->ps
[STp
->partition
].rw
= ST_WRITING
;
2573 STp
->frame_in_buffer
= halfway_frame
;
2574 STp
->frame_seq_number
= frame_seq_numbr
;
2575 STp
->logical_blk_num
= logical_blk_num
;
2579 /* Acc. to OnStream, the vers. numbering is the following:
2580 * X.XX for released versions (X=digit),
2581 * XXXY for unreleased versions (Y=letter)
2582 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2583 * This fn makes monoton numbers out of this scheme ...
2585 static unsigned int osst_parse_firmware_rev (const char * str
)
2587 if (str
[1] == '.') {
2588 return (str
[0]-'0')*10000
2592 return (str
[0]-'0')*10000
2594 +(str
[2]-'0')*100 - 100
2600 * Configure the OnStream SCII tape drive for default operation
2602 static int osst_configure_onstream(struct osst_tape
*STp
, struct osst_request
** aSRpnt
)
2604 unsigned char cmd
[MAX_COMMAND_SIZE
];
2605 char * name
= tape_name(STp
);
2606 struct osst_request
* SRpnt
= * aSRpnt
;
2607 osst_mode_parameter_header_t
* header
;
2608 osst_block_size_page_t
* bs
;
2609 osst_capabilities_page_t
* cp
;
2610 osst_tape_paramtr_page_t
* prm
;
2611 int drive_buffer_size
;
2613 if (STp
->ready
!= ST_READY
) {
2615 printk(OSST_DEB_MSG
"%s:D: Not Ready\n", name
);
2620 if (STp
->os_fw_rev
< 10600) {
2621 printk(KERN_INFO
"%s:I: Old OnStream firmware revision detected (%s),\n", name
, STp
->device
->rev
);
2622 printk(KERN_INFO
"%s:I: an upgrade to version 1.06 or above is recommended\n", name
);
2626 * Configure 32.5KB (data+aux) frame size.
2627 * Get the current frame size from the block size mode page
2629 memset(cmd
, 0, MAX_COMMAND_SIZE
);
2630 cmd
[0] = MODE_SENSE
;
2632 cmd
[2] = BLOCK_SIZE_PAGE
;
2633 cmd
[4] = BLOCK_SIZE_PAGE_LENGTH
+ MODE_HEADER_LENGTH
;
2635 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, cmd
[4], DMA_FROM_DEVICE
, STp
->timeout
, 0, 1);
2636 if (SRpnt
== NULL
) {
2638 printk(OSST_DEB_MSG
"osst :D: Busy\n");
2643 if ((STp
->buffer
)->syscall_result
!= 0) {
2644 printk (KERN_ERR
"%s:E: Can't get tape block size mode page\n", name
);
2648 header
= (osst_mode_parameter_header_t
*) (STp
->buffer
)->b_data
;
2649 bs
= (osst_block_size_page_t
*) ((STp
->buffer
)->b_data
+ sizeof(osst_mode_parameter_header_t
) + header
->bdl
);
2652 printk(OSST_DEB_MSG
"%s:D: 32KB play back: %s\n", name
, bs
->play32
? "Yes" : "No");
2653 printk(OSST_DEB_MSG
"%s:D: 32.5KB play back: %s\n", name
, bs
->play32_5
? "Yes" : "No");
2654 printk(OSST_DEB_MSG
"%s:D: 32KB record: %s\n", name
, bs
->record32
? "Yes" : "No");
2655 printk(OSST_DEB_MSG
"%s:D: 32.5KB record: %s\n", name
, bs
->record32_5
? "Yes" : "No");
2659 * Configure default auto columns mode, 32.5KB transfer mode
2667 memset(cmd
, 0, MAX_COMMAND_SIZE
);
2668 cmd
[0] = MODE_SELECT
;
2670 cmd
[4] = BLOCK_SIZE_PAGE_LENGTH
+ MODE_HEADER_LENGTH
;
2672 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, cmd
[4], DMA_TO_DEVICE
, STp
->timeout
, 0, 1);
2674 if ((STp
->buffer
)->syscall_result
!= 0) {
2675 printk (KERN_ERR
"%s:E: Couldn't set tape block size mode page\n", name
);
2680 printk(KERN_INFO
"%s:D: Drive Block Size changed to 32.5K\n", name
);
2682 * In debug mode, we want to see as many errors as possible
2683 * to test the error recovery mechanism.
2685 osst_set_retries(STp
, aSRpnt
, 0);
2690 * Set vendor name to 'LIN4' for "Linux support version 4".
2693 memset(cmd
, 0, MAX_COMMAND_SIZE
);
2694 cmd
[0] = MODE_SELECT
;
2696 cmd
[4] = VENDOR_IDENT_PAGE_LENGTH
+ MODE_HEADER_LENGTH
;
2698 header
->mode_data_length
= VENDOR_IDENT_PAGE_LENGTH
+ MODE_HEADER_LENGTH
- 1;
2699 header
->medium_type
= 0; /* Medium Type - ignoring */
2700 header
->dsp
= 0; /* Reserved */
2701 header
->bdl
= 0; /* Block Descriptor Length */
2703 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 0] = VENDOR_IDENT_PAGE
| (1 << 7);
2704 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 1] = 6;
2705 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 2] = 'L';
2706 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 3] = 'I';
2707 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 4] = 'N';
2708 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 5] = '4';
2709 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 6] = 0;
2710 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 7] = 0;
2712 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, cmd
[4], DMA_TO_DEVICE
, STp
->timeout
, 0, 1);
2715 if ((STp
->buffer
)->syscall_result
!= 0) {
2716 printk (KERN_ERR
"%s:E: Couldn't set vendor name to %s\n", name
,
2717 (char *) ((STp
->buffer
)->b_data
+ MODE_HEADER_LENGTH
+ 2));
2721 memset(cmd
, 0, MAX_COMMAND_SIZE
);
2722 cmd
[0] = MODE_SENSE
;
2724 cmd
[2] = CAPABILITIES_PAGE
;
2725 cmd
[4] = CAPABILITIES_PAGE_LENGTH
+ MODE_HEADER_LENGTH
;
2727 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, cmd
[4], DMA_FROM_DEVICE
, STp
->timeout
, 0, 1);
2730 if ((STp
->buffer
)->syscall_result
!= 0) {
2731 printk (KERN_ERR
"%s:E: Can't get capabilities page\n", name
);
2735 header
= (osst_mode_parameter_header_t
*) (STp
->buffer
)->b_data
;
2736 cp
= (osst_capabilities_page_t
*) ((STp
->buffer
)->b_data
+
2737 sizeof(osst_mode_parameter_header_t
) + header
->bdl
);
2739 drive_buffer_size
= ntohs(cp
->buffer_size
) / 2;
2741 memset(cmd
, 0, MAX_COMMAND_SIZE
);
2742 cmd
[0] = MODE_SENSE
;
2744 cmd
[2] = TAPE_PARAMTR_PAGE
;
2745 cmd
[4] = TAPE_PARAMTR_PAGE_LENGTH
+ MODE_HEADER_LENGTH
;
2747 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, cmd
[4], DMA_FROM_DEVICE
, STp
->timeout
, 0, 1);
2750 if ((STp
->buffer
)->syscall_result
!= 0) {
2751 printk (KERN_ERR
"%s:E: Can't get tape parameter page\n", name
);
2755 header
= (osst_mode_parameter_header_t
*) (STp
->buffer
)->b_data
;
2756 prm
= (osst_tape_paramtr_page_t
*) ((STp
->buffer
)->b_data
+
2757 sizeof(osst_mode_parameter_header_t
) + header
->bdl
);
2759 STp
->density
= prm
->density
;
2760 STp
->capacity
= ntohs(prm
->segtrk
) * ntohs(prm
->trks
);
2762 printk(OSST_DEB_MSG
"%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2763 name
, STp
->density
, STp
->capacity
/ 32, drive_buffer_size
);
2771 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2772 it messes up the block number). */
2773 static int cross_eof(struct osst_tape
*STp
, struct osst_request
** aSRpnt
, int forward
)
2776 char * name
= tape_name(STp
);
2780 printk(OSST_DEB_MSG
"%s:D: Stepping over filemark %s.\n",
2781 name
, forward
? "forward" : "backward");
2785 /* assumes that the filemark is already read by the drive, so this is low cost */
2786 result
= osst_space_over_filemarks_forward_slow(STp
, aSRpnt
, MTFSF
, 1);
2789 /* assumes this is only called if we just read the filemark! */
2790 result
= osst_seek_logical_blk(STp
, aSRpnt
, STp
->logical_blk_num
- 1);
2793 printk(KERN_WARNING
"%s:W: Stepping over filemark %s failed.\n",
2794 name
, forward
? "forward" : "backward");
2800 /* Get the tape position. */
2802 static int osst_get_frame_position(struct osst_tape
*STp
, struct osst_request
** aSRpnt
)
2804 unsigned char scmd
[MAX_COMMAND_SIZE
];
2805 struct osst_request
* SRpnt
;
2807 char * name
= tape_name(STp
);
2809 /* KG: We want to be able to use it for checking Write Buffer availability
2810 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2812 char * olddata
= STp
->buffer
->b_data
;
2813 int oldsize
= STp
->buffer
->buffer_size
;
2815 if (STp
->ready
!= ST_READY
) return (-EIO
);
2817 memset (scmd
, 0, MAX_COMMAND_SIZE
);
2818 scmd
[0] = READ_POSITION
;
2820 STp
->buffer
->b_data
= mybuf
; STp
->buffer
->buffer_size
= 24;
2821 SRpnt
= osst_do_scsi(*aSRpnt
, STp
, scmd
, 20, DMA_FROM_DEVICE
,
2822 STp
->timeout
, MAX_RETRIES
, 1);
2824 STp
->buffer
->b_data
= olddata
; STp
->buffer
->buffer_size
= oldsize
;
2829 if (STp
->buffer
->syscall_result
)
2830 result
= ((SRpnt
->sense
[2] & 0x0f) == 3) ? -EIO
: -EINVAL
; /* 3: Write Error */
2832 if (result
== -EINVAL
)
2833 printk(KERN_ERR
"%s:E: Can't read tape position.\n", name
);
2835 if (result
== -EIO
) { /* re-read position - this needs to preserve media errors */
2836 unsigned char mysense
[16];
2837 memcpy (mysense
, SRpnt
->sense
, 16);
2838 memset (scmd
, 0, MAX_COMMAND_SIZE
);
2839 scmd
[0] = READ_POSITION
;
2840 STp
->buffer
->b_data
= mybuf
; STp
->buffer
->buffer_size
= 24;
2841 SRpnt
= osst_do_scsi(SRpnt
, STp
, scmd
, 20, DMA_FROM_DEVICE
,
2842 STp
->timeout
, MAX_RETRIES
, 1);
2844 printk(OSST_DEB_MSG
"%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2845 name
, mysense
[2], mysense
[12], mysense
[13], STp
->buffer
->syscall_result
?"":"ok:",
2846 SRpnt
->sense
[2],SRpnt
->sense
[12],SRpnt
->sense
[13]);
2848 if (!STp
->buffer
->syscall_result
)
2849 memcpy (SRpnt
->sense
, mysense
, 16);
2851 printk(KERN_WARNING
"%s:W: Double error in get position\n", name
);
2853 STp
->first_frame_position
= ((STp
->buffer
)->b_data
[4] << 24)
2854 + ((STp
->buffer
)->b_data
[5] << 16)
2855 + ((STp
->buffer
)->b_data
[6] << 8)
2856 + (STp
->buffer
)->b_data
[7];
2857 STp
->last_frame_position
= ((STp
->buffer
)->b_data
[ 8] << 24)
2858 + ((STp
->buffer
)->b_data
[ 9] << 16)
2859 + ((STp
->buffer
)->b_data
[10] << 8)
2860 + (STp
->buffer
)->b_data
[11];
2861 STp
->cur_frames
= (STp
->buffer
)->b_data
[15];
2864 printk(OSST_DEB_MSG
"%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name
,
2865 STp
->first_frame_position
, STp
->last_frame_position
,
2866 ((STp
->buffer
)->b_data
[0]&0x80)?" (BOP)":
2867 ((STp
->buffer
)->b_data
[0]&0x40)?" (EOP)":"",
2871 if (STp
->cur_frames
== 0 && STp
->first_frame_position
!= STp
->last_frame_position
) {
2873 printk(OSST_DEB_MSG
"%s:D: Correcting read position %d, %d, %d\n", name
,
2874 STp
->first_frame_position
, STp
->last_frame_position
, STp
->cur_frames
);
2876 STp
->first_frame_position
= STp
->last_frame_position
;
2879 STp
->buffer
->b_data
= olddata
; STp
->buffer
->buffer_size
= oldsize
;
2881 return (result
== 0 ? STp
->first_frame_position
: result
);
2885 /* Set the tape block */
2886 static int osst_set_frame_position(struct osst_tape
*STp
, struct osst_request
** aSRpnt
, int ppos
, int skip
)
2888 unsigned char scmd
[MAX_COMMAND_SIZE
];
2889 struct osst_request
* SRpnt
;
2890 struct st_partstat
* STps
;
2892 int pp
= (ppos
== 3000 && !skip
)? 0 : ppos
;
2893 char * name
= tape_name(STp
);
2895 if (STp
->ready
!= ST_READY
) return (-EIO
);
2897 STps
= &(STp
->ps
[STp
->partition
]);
2899 if (ppos
< 0 || ppos
> STp
->capacity
) {
2900 printk(KERN_WARNING
"%s:W: Reposition request %d out of range\n", name
, ppos
);
2901 pp
= ppos
= ppos
< 0 ? 0 : (STp
->capacity
- 1);
2908 printk(OSST_DEB_MSG
"%s:D: Setting ppos to %d.\n", name
, pp
);
2910 memset (scmd
, 0, MAX_COMMAND_SIZE
);
2913 scmd
[3] = (pp
>> 24);
2914 scmd
[4] = (pp
>> 16);
2915 scmd
[5] = (pp
>> 8);
2920 SRpnt
= osst_do_scsi(*aSRpnt
, STp
, scmd
, 0, DMA_NONE
, STp
->long_timeout
,
2926 if ((STp
->buffer
)->syscall_result
!= 0) {
2928 printk(OSST_DEB_MSG
"%s:D: SEEK command from %d to %d failed.\n",
2929 name
, STp
->first_frame_position
, pp
);
2934 osst_wait_ready(STp
, aSRpnt
, 5 * 60, OSST_WAIT_POSITION_COMPLETE
);
2935 } while ((pp
!= ppos
) && (pp
= ppos
));
2936 STp
->first_frame_position
= STp
->last_frame_position
= ppos
;
2937 STps
->eof
= ST_NOEOF
;
2940 STp
->frame_in_buffer
= 0;
2944 static int osst_write_trailer(struct osst_tape
*STp
, struct osst_request
** aSRpnt
, int leave_at_EOT
)
2946 struct st_partstat
* STps
= &(STp
->ps
[STp
->partition
]);
2949 if (STp
->write_type
!= OS_WRITE_NEW_MARK
) {
2950 /* true unless the user wrote the filemark for us */
2951 result
= osst_flush_drive_buffer(STp
, aSRpnt
);
2952 if (result
< 0) goto out
;
2953 result
= osst_write_filemark(STp
, aSRpnt
);
2954 if (result
< 0) goto out
;
2956 if (STps
->drv_file
>= 0)
2958 STps
->drv_block
= 0;
2960 result
= osst_write_eod(STp
, aSRpnt
);
2961 osst_write_header(STp
, aSRpnt
, leave_at_EOT
);
2968 /* osst versions of st functions - augmented and stripped to suit OnStream only */
2970 /* Flush the write buffer (never need to write if variable blocksize). */
2971 static int osst_flush_write_buffer(struct osst_tape
*STp
, struct osst_request
** aSRpnt
)
2973 int offset
, transfer
, blks
= 0;
2975 unsigned char cmd
[MAX_COMMAND_SIZE
];
2976 struct osst_request
* SRpnt
= *aSRpnt
;
2977 struct st_partstat
* STps
;
2978 char * name
= tape_name(STp
);
2980 if ((STp
->buffer
)->writing
) {
2981 if (SRpnt
== (STp
->buffer
)->last_SRpnt
)
2983 { printk(OSST_DEB_MSG
2984 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name
);
2986 *aSRpnt
= SRpnt
= NULL
;
2990 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name
);
2992 osst_write_behind_check(STp
);
2993 if ((STp
->buffer
)->syscall_result
) {
2996 printk(OSST_DEB_MSG
"%s:D: Async write error (flush) %x.\n",
2997 name
, (STp
->buffer
)->midlevel_result
);
2999 if ((STp
->buffer
)->midlevel_result
== INT_MAX
)
3006 if (STp
->dirty
== 1) {
3009 STps
= &(STp
->ps
[STp
->partition
]);
3010 STps
->rw
= ST_WRITING
;
3011 offset
= STp
->buffer
->buffer_bytes
;
3012 blks
= (offset
+ STp
->block_size
- 1) / STp
->block_size
;
3013 transfer
= OS_FRAME_SIZE
;
3015 if (offset
< OS_DATA_SIZE
)
3016 osst_zero_buffer_tail(STp
->buffer
);
3019 if (osst_wait_frame (STp
, aSRpnt
, STp
->first_frame_position
, -50, 120))
3020 result
= osst_recover_wait_frame(STp
, aSRpnt
, 1);
3022 memset(cmd
, 0, MAX_COMMAND_SIZE
);
3027 switch (STp
->write_type
) {
3031 printk(OSST_DEB_MSG
"%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
3032 name
, blks
, STp
->frame_seq_number
,
3033 STp
->logical_blk_num
- blks
, STp
->logical_blk_num
- 1);
3035 osst_init_aux(STp
, OS_FRAME_TYPE_DATA
, STp
->frame_seq_number
++,
3036 STp
->logical_blk_num
- blks
, STp
->block_size
, blks
);
3039 osst_init_aux(STp
, OS_FRAME_TYPE_EOD
, STp
->frame_seq_number
++,
3040 STp
->logical_blk_num
, 0, 0);
3042 case OS_WRITE_NEW_MARK
:
3043 osst_init_aux(STp
, OS_FRAME_TYPE_MARKER
, STp
->frame_seq_number
++,
3044 STp
->logical_blk_num
++, 0, blks
=1);
3046 case OS_WRITE_HEADER
:
3047 osst_init_aux(STp
, OS_FRAME_TYPE_HEADER
, 0, 0, 0, blks
=0);
3049 default: /* probably FILLER */
3050 osst_init_aux(STp
, OS_FRAME_TYPE_FILL
, 0, 0, 0, 0);
3054 printk(OSST_DEB_MSG
"%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
3055 name
, offset
, transfer
, blks
);
3058 SRpnt
= osst_do_scsi(*aSRpnt
, STp
, cmd
, transfer
, DMA_TO_DEVICE
,
3059 STp
->timeout
, MAX_RETRIES
, 1);
3064 if ((STp
->buffer
)->syscall_result
!= 0) {
3067 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3068 name
, SRpnt
->sense
[0], SRpnt
->sense
[2],
3069 SRpnt
->sense
[12], SRpnt
->sense
[13]);
3071 if ((SRpnt
->sense
[0] & 0x70) == 0x70 &&
3072 (SRpnt
->sense
[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3073 (SRpnt
->sense
[2] & 0x0f) == NO_SENSE
) {
3075 (STp
->buffer
)->buffer_bytes
= 0;
3079 if (osst_write_error_recovery(STp
, aSRpnt
, 1)) {
3080 printk(KERN_ERR
"%s:E: Error on flush write.\n", name
);
3084 STps
->drv_block
= (-1); /* FIXME - even if write recovery succeeds? */
3087 STp
->first_frame_position
++;
3089 (STp
->buffer
)->buffer_bytes
= 0;
3093 printk(OSST_DEB_MSG
"%s:D: Exit flush write buffer with code %d\n", name
, result
);
3099 /* Flush the tape buffer. The tape will be positioned correctly unless
3100 seek_next is true. */
3101 static int osst_flush_buffer(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int seek_next
)
3103 struct st_partstat
* STps
;
3104 int backspace
= 0, result
= 0;
3106 char * name
= tape_name(STp
);
3110 * If there was a bus reset, block further access
3113 if( STp
->pos_unknown
)
3116 if (STp
->ready
!= ST_READY
)
3119 STps
= &(STp
->ps
[STp
->partition
]);
3120 if (STps
->rw
== ST_WRITING
|| STp
->dirty
) { /* Writing */
3121 STp
->write_type
= OS_WRITE_DATA
;
3122 return osst_flush_write_buffer(STp
, aSRpnt
);
3124 if (STp
->block_size
== 0)
3128 printk(OSST_DEB_MSG
"%s:D: Reached flush (read) buffer\n", name
);
3131 if (!STp
->can_bsr
) {
3132 backspace
= ((STp
->buffer
)->buffer_bytes
+ (STp
->buffer
)->read_pointer
) / STp
->block_size
-
3133 ((STp
->buffer
)->read_pointer
+ STp
->block_size
- 1 ) / STp
->block_size
;
3134 (STp
->buffer
)->buffer_bytes
= 0;
3135 (STp
->buffer
)->read_pointer
= 0;
3136 STp
->frame_in_buffer
= 0; /* FIXME is this relevant w. OSST? */
3140 if (STps
->eof
== ST_FM_HIT
) {
3141 result
= cross_eof(STp
, aSRpnt
, 0); /* Back over the EOF hit */
3143 STps
->eof
= ST_NOEOF
;
3145 if (STps
->drv_file
>= 0)
3147 STps
->drv_block
= 0;
3150 if (!result
&& backspace
> 0) /* TODO -- design and run a test case for this */
3151 result
= osst_seek_logical_blk(STp
, aSRpnt
, STp
->logical_blk_num
- backspace
);
3153 else if (STps
->eof
== ST_FM_HIT
) {
3154 if (STps
->drv_file
>= 0)
3156 STps
->drv_block
= 0;
3157 STps
->eof
= ST_NOEOF
;
3163 static int osst_write_frame(struct osst_tape
* STp
, struct osst_request
** aSRpnt
, int synchronous
)
3165 unsigned char cmd
[MAX_COMMAND_SIZE
];
3166 struct osst_request
* SRpnt
;
3169 char * name
= tape_name(STp
);
3172 if ((!STp
-> raw
) && (STp
->first_frame_position
== 0xbae)) { /* _must_ preserve buffer! */
3174 printk(OSST_DEB_MSG
"%s:D: Reaching config partition.\n", name
);
3176 if (osst_flush_drive_buffer(STp
, aSRpnt
) < 0) {
3179 /* error recovery may have bumped us past the header partition */
3180 if (osst_get_frame_position(STp
, aSRpnt
) < 0xbb8) {
3182 printk(OSST_DEB_MSG
"%s:D: Skipping over config partition.\n", name
);
3184 osst_position_tape_and_confirm(STp
, aSRpnt
, 0xbb8);
3189 if (osst_wait_frame (STp
, aSRpnt
, STp
->first_frame_position
, -48, 120))
3190 if (osst_recover_wait_frame(STp
, aSRpnt
, 1))
3193 // osst_build_stats(STp, &SRpnt);
3195 STp
->ps
[STp
->partition
].rw
= ST_WRITING
;
3196 STp
->write_type
= OS_WRITE_DATA
;
3198 memset(cmd
, 0, MAX_COMMAND_SIZE
);
3201 cmd
[4] = 1; /* one frame at a time... */
3202 blks
= STp
->buffer
->buffer_bytes
/ STp
->block_size
;
3205 printk(OSST_DEB_MSG
"%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name
, blks
,
3206 STp
->frame_seq_number
, STp
->logical_blk_num
- blks
, STp
->logical_blk_num
- 1);
3208 osst_init_aux(STp
, OS_FRAME_TYPE_DATA
, STp
->frame_seq_number
++,
3209 STp
->logical_blk_num
- blks
, STp
->block_size
, blks
);
3213 STp
->write_pending
= 1;
3215 SRpnt
= osst_do_scsi(*aSRpnt
, STp
, cmd
, OS_FRAME_SIZE
, DMA_TO_DEVICE
, STp
->timeout
,
3216 MAX_RETRIES
, synchronous
);
3222 if (STp
->buffer
->syscall_result
!= 0) {
3225 printk(OSST_DEB_MSG
"%s:D: Error on write:\n", name
);
3227 if ((SRpnt
->sense
[0] & 0x70) == 0x70 &&
3228 (SRpnt
->sense
[2] & 0x40)) {
3229 if ((SRpnt
->sense
[2] & 0x0f) == VOLUME_OVERFLOW
)
3233 if (osst_write_error_recovery(STp
, aSRpnt
, 1))
3238 STp
->first_frame_position
++;
3246 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */
3247 static int do_door_lock(struct osst_tape
* STp
, int do_lock
)
3251 cmd
= do_lock
? SCSI_IOCTL_DOORLOCK
: SCSI_IOCTL_DOORUNLOCK
;
3253 printk(OSST_DEB_MSG
"%s:D: %socking drive door.\n", tape_name(STp
), do_lock
? "L" : "Unl");
3255 retval
= scsi_ioctl(STp
->device
, cmd
, NULL
);
3257 STp
->door_locked
= do_lock
? ST_LOCKED_EXPLICIT
: ST_UNLOCKED
;
3260 STp
->door_locked
= ST_LOCK_FAILS
;
3265 /* Set the internal state after reset */
3266 static void reset_state(struct osst_tape
*STp
)
3269 struct st_partstat
*STps
;
3271 STp
->pos_unknown
= 0;
3272 for (i
= 0; i
< ST_NBR_PARTITIONS
; i
++) {
3273 STps
= &(STp
->ps
[i
]);
3275 STps
->eof
= ST_NOEOF
;
3277 STps
->last_block_valid
= 0;
3278 STps
->drv_block
= -1;
3279 STps
->drv_file
= -1;
3284 /* Entry points to osst */
3287 static ssize_t
osst_write(struct file
* filp
, const char __user
* buf
, size_t count
, loff_t
*ppos
)
3289 ssize_t total
, retval
= 0;
3290 ssize_t i
, do_count
, blks
, transfer
;
3291 int write_threshold
;
3292 int doing_write
= 0;
3293 const char __user
* b_point
;
3294 struct osst_request
* SRpnt
= NULL
;
3295 struct st_modedef
* STm
;
3296 struct st_partstat
* STps
;
3297 struct osst_tape
* STp
= filp
->private_data
;
3298 char * name
= tape_name(STp
);
3301 if (mutex_lock_interruptible(&STp
->lock
))
3302 return (-ERESTARTSYS
);
3305 * If we are in the middle of error recovery, don't let anyone
3306 * else try and use this device. Also, if error recovery fails, it
3307 * may try and take the device offline, in which case all further
3308 * access to the device is prohibited.
3310 if( !scsi_block_when_processing_errors(STp
->device
) ) {
3315 if (STp
->ready
!= ST_READY
) {
3316 if (STp
->ready
== ST_NO_TAPE
)
3317 retval
= (-ENOMEDIUM
);
3322 STm
= &(STp
->modes
[STp
->current_mode
]);
3323 if (!STm
->defined
) {
3331 * If there was a bus reset, block further access
3334 if (STp
->pos_unknown
) {
3341 printk(OSST_DEB_MSG
"%s:D: Incorrect device.\n", name
);
3347 if (STp
->write_prot
) {
3352 /* Write must be integral number of blocks */
3353 if (STp
->block_size
!= 0 && (count
% STp
->block_size
) != 0) {
3354 printk(KERN_ERR
"%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3355 name
, count
, STp
->block_size
<1024?
3356 STp
->block_size
:STp
->block_size
/1024, STp
->block_size
<1024?'b':'k');
3361 if (STp
->first_frame_position
>= STp
->capacity
- OSST_EOM_RESERVE
) {
3362 printk(KERN_ERR
"%s:E: Write truncated at EOM early warning (frame %d).\n",
3363 name
, STp
->first_frame_position
);
3368 if (STp
->do_auto_lock
&& STp
->door_locked
== ST_UNLOCKED
&& !do_door_lock(STp
, 1))
3369 STp
->door_locked
= ST_LOCKED_AUTO
;
3371 STps
= &(STp
->ps
[STp
->partition
]);
3373 if (STps
->rw
== ST_READING
) {
3375 printk(OSST_DEB_MSG
"%s:D: Switching from read to write at file %d, block %d\n", name
,
3376 STps
->drv_file
, STps
->drv_block
);
3378 retval
= osst_flush_buffer(STp
, &SRpnt
, 0);
3383 if (STps
->rw
!= ST_WRITING
) {
3384 /* Are we totally rewriting this tape? */
3385 if (!STp
->header_ok
||
3386 (STp
->first_frame_position
== STp
->first_data_ppos
&& STps
->drv_block
< 0) ||
3387 (STps
->drv_file
== 0 && STps
->drv_block
== 0)) {
3388 STp
->wrt_pass_cntr
++;
3390 printk(OSST_DEB_MSG
"%s:D: Allocating next write pass counter: %d\n",
3391 name
, STp
->wrt_pass_cntr
);
3393 osst_reset_header(STp
, &SRpnt
);
3394 STps
->drv_file
= STps
->drv_block
= 0;
3396 /* Do we know where we'll be writing on the tape? */
3398 if ((STp
->fast_open
&& osst_verify_position(STp
, &SRpnt
)) ||
3399 STps
->drv_file
< 0 || STps
->drv_block
< 0) {
3400 if (STp
->first_frame_position
== STp
->eod_frame_ppos
) { /* at EOD */
3401 STps
->drv_file
= STp
->filemark_cnt
;
3402 STps
->drv_block
= 0;
3405 /* We have no idea where the tape is positioned - give up */
3408 "%s:D: Cannot write at indeterminate position.\n", name
);
3414 if ((STps
->drv_file
+ STps
->drv_block
) > 0 && STps
->drv_file
< STp
->filemark_cnt
) {
3415 STp
->filemark_cnt
= STps
->drv_file
;
3416 STp
->last_mark_ppos
=
3417 ntohl(STp
->header_cache
->dat_fm_tab
.fm_tab_ent
[STp
->filemark_cnt
-1]);
3419 "%s:W: Overwriting file %d with old write pass counter %d\n",
3420 name
, STps
->drv_file
, STp
->wrt_pass_cntr
);
3422 "%s:W: may lead to stale data being accepted on reading back!\n",
3426 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3427 name
, STp
->filemark_cnt
, STp
->last_mark_ppos
, STp
->last_mark_lbn
);
3433 if (!STp
->header_ok
) {
3435 printk(OSST_DEB_MSG
"%s:D: Write cannot proceed without valid headers\n", name
);
3441 if ((STp
->buffer
)->writing
) {
3442 if (SRpnt
) printk(KERN_ERR
"%s:A: Not supposed to have SRpnt at line %d\n", name
, __LINE__
);
3443 osst_write_behind_check(STp
);
3444 if ((STp
->buffer
)->syscall_result
) {
3447 printk(OSST_DEB_MSG
"%s:D: Async write error (write) %x.\n", name
,
3448 (STp
->buffer
)->midlevel_result
);
3450 if ((STp
->buffer
)->midlevel_result
== INT_MAX
)
3451 STps
->eof
= ST_EOM_OK
;
3453 STps
->eof
= ST_EOM_ERROR
;
3456 if (STps
->eof
== ST_EOM_OK
) {
3460 else if (STps
->eof
== ST_EOM_ERROR
) {
3465 /* Check the buffer readability in cases where copy_user might catch
3466 the problems after some tape movement. */
3467 if ((copy_from_user(&i
, buf
, 1) != 0 ||
3468 copy_from_user(&i
, buf
+ count
- 1, 1) != 0)) {
3473 if (!STm
->do_buffer_writes
) {
3474 write_threshold
= 1;
3477 write_threshold
= (STp
->buffer
)->buffer_blocks
* STp
->block_size
;
3478 if (!STm
->do_async_writes
)
3484 printk(OSST_DEB_MSG
"%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3485 name
, (int) count
, STps
->drv_file
, STps
->drv_block
,
3486 STp
->logical_blk_num
, STp
->frame_seq_number
, STp
->first_frame_position
);
3489 while ((STp
->buffer
)->buffer_bytes
+ count
> write_threshold
)
3492 do_count
= (STp
->buffer
)->buffer_blocks
* STp
->block_size
-
3493 (STp
->buffer
)->buffer_bytes
;
3494 if (do_count
> count
)
3497 i
= append_to_buffer(b_point
, STp
->buffer
, do_count
);
3503 blks
= do_count
/ STp
->block_size
;
3504 STp
->logical_blk_num
+= blks
; /* logical_blk_num is incremented as data is moved from user */
3506 i
= osst_write_frame(STp
, &SRpnt
, 1);
3508 if (i
== (-ENOSPC
)) {
3509 transfer
= STp
->buffer
->writing
; /* FIXME -- check this logic */
3510 if (transfer
<= do_count
) {
3511 filp
->f_pos
+= do_count
- transfer
;
3512 count
-= do_count
- transfer
;
3513 if (STps
->drv_block
>= 0) {
3514 STps
->drv_block
+= (do_count
- transfer
) / STp
->block_size
;
3516 STps
->eof
= ST_EOM_OK
;
3517 retval
= (-ENOSPC
); /* EOM within current request */
3520 printk(OSST_DEB_MSG
"%s:D: EOM with %d bytes unwritten.\n",
3521 name
, (int) transfer
);
3525 STps
->eof
= ST_EOM_ERROR
;
3526 STps
->drv_block
= (-1); /* Too cautious? */
3527 retval
= (-EIO
); /* EOM for old data */
3530 printk(OSST_DEB_MSG
"%s:D: EOM with lost data.\n", name
);
3538 if (SRpnt
!= NULL
) {
3539 osst_release_request(SRpnt
);
3542 STp
->buffer
->buffer_bytes
= 0;
3545 retval
= total
- count
;
3549 filp
->f_pos
+= do_count
;
3550 b_point
+= do_count
;
3552 if (STps
->drv_block
>= 0) {
3553 STps
->drv_block
+= blks
;
3555 STp
->buffer
->buffer_bytes
= 0;
3557 } /* end while write threshold exceeded */
3561 i
= append_to_buffer(b_point
, STp
->buffer
, count
);
3566 blks
= count
/ STp
->block_size
;
3567 STp
->logical_blk_num
+= blks
;
3568 if (STps
->drv_block
>= 0) {
3569 STps
->drv_block
+= blks
;
3571 filp
->f_pos
+= count
;
3575 if (doing_write
&& (STp
->buffer
)->syscall_result
!= 0) {
3576 retval
= (STp
->buffer
)->syscall_result
;
3580 if (STm
->do_async_writes
&& ((STp
->buffer
)->buffer_bytes
>= STp
->write_threshold
)) {
3581 /* Schedule an asynchronous write */
3582 (STp
->buffer
)->writing
= ((STp
->buffer
)->buffer_bytes
/
3583 STp
->block_size
) * STp
->block_size
;
3584 STp
->dirty
= !((STp
->buffer
)->writing
==
3585 (STp
->buffer
)->buffer_bytes
);
3587 i
= osst_write_frame(STp
, &SRpnt
, 0);
3592 SRpnt
= NULL
; /* Prevent releasing this request! */
3594 STps
->at_sm
&= (total
== 0);
3596 STps
->eof
= ST_NOEOF
;
3601 if (SRpnt
!= NULL
) osst_release_request(SRpnt
);
3603 mutex_unlock(&STp
->lock
);
3610 static ssize_t
osst_read(struct file
* filp
, char __user
* buf
, size_t count
, loff_t
*ppos
)
3612 ssize_t total
, retval
= 0;
3613 ssize_t i
, transfer
;
3615 struct st_modedef
* STm
;
3616 struct st_partstat
* STps
;
3617 struct osst_request
* SRpnt
= NULL
;
3618 struct osst_tape
* STp
= filp
->private_data
;
3619 char * name
= tape_name(STp
);
3622 if (mutex_lock_interruptible(&STp
->lock
))
3623 return (-ERESTARTSYS
);
3626 * If we are in the middle of error recovery, don't let anyone
3627 * else try and use this device. Also, if error recovery fails, it
3628 * may try and take the device offline, in which case all further
3629 * access to the device is prohibited.
3631 if( !scsi_block_when_processing_errors(STp
->device
) ) {
3636 if (STp
->ready
!= ST_READY
) {
3637 if (STp
->ready
== ST_NO_TAPE
)
3638 retval
= (-ENOMEDIUM
);
3643 STm
= &(STp
->modes
[STp
->current_mode
]);
3644 if (!STm
->defined
) {
3650 printk(OSST_DEB_MSG
"%s:D: Incorrect device.\n", name
);
3655 /* Must have initialized medium */
3656 if (!STp
->header_ok
) {
3661 if (STp
->do_auto_lock
&& STp
->door_locked
== ST_UNLOCKED
&& !do_door_lock(STp
, 1))
3662 STp
->door_locked
= ST_LOCKED_AUTO
;
3664 STps
= &(STp
->ps
[STp
->partition
]);
3665 if (STps
->rw
== ST_WRITING
) {
3666 retval
= osst_flush_buffer(STp
, &SRpnt
, 0);
3670 /* FIXME -- this may leave the tape without EOD and up2date headers */
3673 if ((count
% STp
->block_size
) != 0) {
3675 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name
, count
,
3676 STp
->block_size
<1024?STp
->block_size
:STp
->block_size
/1024, STp
->block_size
<1024?'b':'k');
3680 if (debugging
&& STps
->eof
!= ST_NOEOF
)
3681 printk(OSST_DEB_MSG
"%s:D: EOF/EOM flag up (%d). Bytes %d\n", name
,
3682 STps
->eof
, (STp
->buffer
)->buffer_bytes
);
3684 if ((STp
->buffer
)->buffer_bytes
== 0 &&
3685 STps
->eof
>= ST_EOD_1
) {
3686 if (STps
->eof
< ST_EOD
) {
3691 retval
= (-EIO
); /* EOM or Blank Check */
3695 /* Check the buffer writability before any tape movement. Don't alter
3697 if (copy_from_user(&i
, buf
, 1) != 0 ||
3698 copy_to_user (buf
, &i
, 1) != 0 ||
3699 copy_from_user(&i
, buf
+ count
- 1, 1) != 0 ||
3700 copy_to_user (buf
+ count
- 1, &i
, 1) != 0) {
3705 /* Loop until enough data in buffer or a special condition found */
3706 for (total
= 0, special
= 0; total
< count
- STp
->block_size
+ 1 && !special
; ) {
3708 /* Get new data if the buffer is empty */
3709 if ((STp
->buffer
)->buffer_bytes
== 0) {
3710 if (STps
->eof
== ST_FM_HIT
)
3712 special
= osst_get_logical_frame(STp
, &SRpnt
, STp
->frame_seq_number
, 0);
3713 if (special
< 0) { /* No need to continue read */
3714 STp
->frame_in_buffer
= 0;
3720 /* Move the data from driver buffer to user buffer */
3721 if ((STp
->buffer
)->buffer_bytes
> 0) {
3723 if (debugging
&& STps
->eof
!= ST_NOEOF
)
3724 printk(OSST_DEB_MSG
"%s:D: EOF up (%d). Left %d, needed %d.\n", name
,
3725 STps
->eof
, (STp
->buffer
)->buffer_bytes
, (int) (count
- total
));
3727 /* force multiple of block size, note block_size may have been adjusted */
3728 transfer
= (((STp
->buffer
)->buffer_bytes
< count
- total
?
3729 (STp
->buffer
)->buffer_bytes
: count
- total
)/
3730 STp
->block_size
) * STp
->block_size
;
3732 if (transfer
== 0) {
3734 "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
3735 name
, count
, STp
->block_size
< 1024?
3736 STp
->block_size
:STp
->block_size
/1024,
3737 STp
->block_size
<1024?'b':'k');
3740 i
= from_buffer(STp
->buffer
, buf
, transfer
);
3745 STp
->logical_blk_num
+= transfer
/ STp
->block_size
;
3746 STps
->drv_block
+= transfer
/ STp
->block_size
;
3747 filp
->f_pos
+= transfer
;
3752 if ((STp
->buffer
)->buffer_bytes
== 0) {
3755 printk(OSST_DEB_MSG
"%s:D: Finished with frame %d\n",
3756 name
, STp
->frame_seq_number
);
3758 STp
->frame_in_buffer
= 0;
3759 STp
->frame_seq_number
++; /* frame to look for next time */
3761 } /* for (total = 0, special = 0; total < count && !special; ) */
3763 /* Change the eof state if no data from tape or buffer */
3765 if (STps
->eof
== ST_FM_HIT
) {
3766 STps
->eof
= (STp
->first_frame_position
>= STp
->eod_frame_ppos
)?ST_EOD_2
:ST_FM
;
3767 STps
->drv_block
= 0;
3768 if (STps
->drv_file
>= 0)
3771 else if (STps
->eof
== ST_EOD_1
) {
3772 STps
->eof
= ST_EOD_2
;
3773 if (STps
->drv_block
> 0 && STps
->drv_file
>= 0)
3775 STps
->drv_block
= 0;
3777 else if (STps
->eof
== ST_EOD_2
)
3780 else if (STps
->eof
== ST_FM
)
3781 STps
->eof
= ST_NOEOF
;
3786 if (SRpnt
!= NULL
) osst_release_request(SRpnt
);
3788 mutex_unlock(&STp
->lock
);
3794 /* Set the driver options */
3795 static void osst_log_options(struct osst_tape
*STp
, struct st_modedef
*STm
, char *name
)
3798 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3799 name
, STp
->current_mode
, STm
->do_buffer_writes
, STm
->do_async_writes
,
3800 STm
->do_read_ahead
);
3802 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3803 name
, STp
->can_bsr
, STp
->two_fm
, STp
->fast_mteom
, STp
->do_auto_lock
);
3805 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3806 name
, STm
->defaults_for_writes
, STp
->omit_blklims
, STp
->can_partitions
,
3807 STp
->scsi2_logical
);
3809 "%s:I: sysv: %d\n", name
, STm
->sysv
);
3812 "%s:D: debugging: %d\n",
3818 static int osst_set_options(struct osst_tape
*STp
, long options
)
3822 struct st_modedef
* STm
;
3823 char * name
= tape_name(STp
);
3825 STm
= &(STp
->modes
[STp
->current_mode
]);
3826 if (!STm
->defined
) {
3827 memcpy(STm
, &(STp
->modes
[0]), sizeof(*STm
));
3831 printk(OSST_DEB_MSG
"%s:D: Initialized mode %d definition from mode 0\n",
3832 name
, STp
->current_mode
);
3836 code
= options
& MT_ST_OPTIONS
;
3837 if (code
== MT_ST_BOOLEANS
) {
3838 STm
->do_buffer_writes
= (options
& MT_ST_BUFFER_WRITES
) != 0;
3839 STm
->do_async_writes
= (options
& MT_ST_ASYNC_WRITES
) != 0;
3840 STm
->defaults_for_writes
= (options
& MT_ST_DEF_WRITES
) != 0;
3841 STm
->do_read_ahead
= (options
& MT_ST_READ_AHEAD
) != 0;
3842 STp
->two_fm
= (options
& MT_ST_TWO_FM
) != 0;
3843 STp
->fast_mteom
= (options
& MT_ST_FAST_MTEOM
) != 0;
3844 STp
->do_auto_lock
= (options
& MT_ST_AUTO_LOCK
) != 0;
3845 STp
->can_bsr
= (options
& MT_ST_CAN_BSR
) != 0;
3846 STp
->omit_blklims
= (options
& MT_ST_NO_BLKLIMS
) != 0;
3847 if ((STp
->device
)->scsi_level
>= SCSI_2
)
3848 STp
->can_partitions
= (options
& MT_ST_CAN_PARTITIONS
) != 0;
3849 STp
->scsi2_logical
= (options
& MT_ST_SCSI2LOGICAL
) != 0;
3850 STm
->sysv
= (options
& MT_ST_SYSV
) != 0;
3852 debugging
= (options
& MT_ST_DEBUGGING
) != 0;
3854 osst_log_options(STp
, STm
, name
);
3856 else if (code
== MT_ST_SETBOOLEANS
|| code
== MT_ST_CLEARBOOLEANS
) {
3857 value
= (code
== MT_ST_SETBOOLEANS
);
3858 if ((options
& MT_ST_BUFFER_WRITES
) != 0)
3859 STm
->do_buffer_writes
= value
;
3860 if ((options
& MT_ST_ASYNC_WRITES
) != 0)
3861 STm
->do_async_writes
= value
;
3862 if ((options
& MT_ST_DEF_WRITES
) != 0)
3863 STm
->defaults_for_writes
= value
;
3864 if ((options
& MT_ST_READ_AHEAD
) != 0)
3865 STm
->do_read_ahead
= value
;
3866 if ((options
& MT_ST_TWO_FM
) != 0)
3867 STp
->two_fm
= value
;
3868 if ((options
& MT_ST_FAST_MTEOM
) != 0)
3869 STp
->fast_mteom
= value
;
3870 if ((options
& MT_ST_AUTO_LOCK
) != 0)
3871 STp
->do_auto_lock
= value
;
3872 if ((options
& MT_ST_CAN_BSR
) != 0)
3873 STp
->can_bsr
= value
;
3874 if ((options
& MT_ST_NO_BLKLIMS
) != 0)
3875 STp
->omit_blklims
= value
;
3876 if ((STp
->device
)->scsi_level
>= SCSI_2
&&
3877 (options
& MT_ST_CAN_PARTITIONS
) != 0)
3878 STp
->can_partitions
= value
;
3879 if ((options
& MT_ST_SCSI2LOGICAL
) != 0)
3880 STp
->scsi2_logical
= value
;
3881 if ((options
& MT_ST_SYSV
) != 0)
3884 if ((options
& MT_ST_DEBUGGING
) != 0)
3887 osst_log_options(STp
, STm
, name
);
3889 else if (code
== MT_ST_WRITE_THRESHOLD
) {
3890 value
= (options
& ~MT_ST_OPTIONS
) * ST_KILOBYTE
;
3891 if (value
< 1 || value
> osst_buffer_size
) {
3892 printk(KERN_WARNING
"%s:W: Write threshold %d too small or too large.\n",
3896 STp
->write_threshold
= value
;
3897 printk(KERN_INFO
"%s:I: Write threshold set to %d bytes.\n",
3900 else if (code
== MT_ST_DEF_BLKSIZE
) {
3901 value
= (options
& ~MT_ST_OPTIONS
);
3902 if (value
== ~MT_ST_OPTIONS
) {
3903 STm
->default_blksize
= (-1);
3904 printk(KERN_INFO
"%s:I: Default block size disabled.\n", name
);
3907 if (value
< 512 || value
> OS_DATA_SIZE
|| OS_DATA_SIZE
% value
) {
3908 printk(KERN_WARNING
"%s:W: Default block size cannot be set to %d.\n",
3912 STm
->default_blksize
= value
;
3913 printk(KERN_INFO
"%s:I: Default block size set to %d bytes.\n",
3914 name
, STm
->default_blksize
);
3917 else if (code
== MT_ST_TIMEOUTS
) {
3918 value
= (options
& ~MT_ST_OPTIONS
);
3919 if ((value
& MT_ST_SET_LONG_TIMEOUT
) != 0) {
3920 STp
->long_timeout
= (value
& ~MT_ST_SET_LONG_TIMEOUT
) * HZ
;
3921 printk(KERN_INFO
"%s:I: Long timeout set to %d seconds.\n", name
,
3922 (value
& ~MT_ST_SET_LONG_TIMEOUT
));
3925 STp
->timeout
= value
* HZ
;
3926 printk(KERN_INFO
"%s:I: Normal timeout set to %d seconds.\n", name
, value
);
3929 else if (code
== MT_ST_DEF_OPTIONS
) {
3930 code
= (options
& ~MT_ST_CLEAR_DEFAULT
);
3931 value
= (options
& MT_ST_CLEAR_DEFAULT
);
3932 if (code
== MT_ST_DEF_DENSITY
) {
3933 if (value
== MT_ST_CLEAR_DEFAULT
) {
3934 STm
->default_density
= (-1);
3935 printk(KERN_INFO
"%s:I: Density default disabled.\n", name
);
3938 STm
->default_density
= value
& 0xff;
3939 printk(KERN_INFO
"%s:I: Density default set to %x\n",
3940 name
, STm
->default_density
);
3943 else if (code
== MT_ST_DEF_DRVBUFFER
) {
3944 if (value
== MT_ST_CLEAR_DEFAULT
) {
3945 STp
->default_drvbuffer
= 0xff;
3946 printk(KERN_INFO
"%s:I: Drive buffer default disabled.\n", name
);
3949 STp
->default_drvbuffer
= value
& 7;
3950 printk(KERN_INFO
"%s:I: Drive buffer default set to %x\n",
3951 name
, STp
->default_drvbuffer
);
3954 else if (code
== MT_ST_DEF_COMPRESSION
) {
3955 if (value
== MT_ST_CLEAR_DEFAULT
) {
3956 STm
->default_compression
= ST_DONT_TOUCH
;
3957 printk(KERN_INFO
"%s:I: Compression default disabled.\n", name
);
3960 STm
->default_compression
= (value
& 1 ? ST_YES
: ST_NO
);
3961 printk(KERN_INFO
"%s:I: Compression default set to %x\n",
3973 /* Internal ioctl function */
3974 static int osst_int_ioctl(struct osst_tape
* STp
, struct osst_request
** aSRpnt
,
3975 unsigned int cmd_in
, unsigned long arg
)
3979 int i
, ioctl_result
;
3981 unsigned char cmd
[MAX_COMMAND_SIZE
];
3982 struct osst_request
* SRpnt
= * aSRpnt
;
3983 struct st_partstat
* STps
;
3984 int fileno
, blkno
, at_sm
, frame_seq_numbr
, logical_blk_num
;
3985 int datalen
= 0, direction
= DMA_NONE
;
3986 char * name
= tape_name(STp
);
3988 if (STp
->ready
!= ST_READY
&& cmd_in
!= MTLOAD
) {
3989 if (STp
->ready
== ST_NO_TAPE
)
3990 return (-ENOMEDIUM
);
3994 timeout
= STp
->long_timeout
;
3995 STps
= &(STp
->ps
[STp
->partition
]);
3996 fileno
= STps
->drv_file
;
3997 blkno
= STps
->drv_block
;
3998 at_sm
= STps
->at_sm
;
3999 frame_seq_numbr
= STp
->frame_seq_number
;
4000 logical_blk_num
= STp
->logical_blk_num
;
4002 memset(cmd
, 0, MAX_COMMAND_SIZE
);
4005 chg_eof
= 0; /* Changed from the FSF after this */
4009 if (STp
->linux_media
)
4010 ioctl_result
= osst_space_over_filemarks_forward_fast(STp
, &SRpnt
, cmd_in
, arg
);
4012 ioctl_result
= osst_space_over_filemarks_forward_slow(STp
, &SRpnt
, cmd_in
, arg
);
4016 at_sm
&= (arg
== 0);
4020 chg_eof
= 0; /* Changed from the FSF after this */
4024 ioctl_result
= osst_space_over_filemarks_backward(STp
, &SRpnt
, cmd_in
, arg
);
4027 blkno
= (-1); /* We can't know the block number */
4028 at_sm
&= (arg
== 0);
4035 printk(OSST_DEB_MSG
"%s:D: Skipping %lu blocks %s from logical block %d\n",
4036 name
, arg
, cmd_in
==MTFSR
?"forward":"backward", logical_blk_num
);
4038 if (cmd_in
== MTFSR
) {
4039 logical_blk_num
+= arg
;
4040 if (blkno
>= 0) blkno
+= arg
;
4043 logical_blk_num
-= arg
;
4044 if (blkno
>= 0) blkno
-= arg
;
4046 ioctl_result
= osst_seek_logical_blk(STp
, &SRpnt
, logical_blk_num
);
4047 fileno
= STps
->drv_file
;
4048 blkno
= STps
->drv_block
;
4049 at_sm
&= (arg
== 0);
4054 cmd
[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4055 cmd
[2] = (arg
>> 16);
4056 cmd
[3] = (arg
>> 8);
4060 printk(OSST_DEB_MSG
"%s:D: Spacing tape forward %d setmarks.\n", name
,
4061 cmd
[2] * 65536 + cmd
[3] * 256 + cmd
[4]);
4064 blkno
= fileno
= (-1);
4070 cmd
[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4072 cmd
[2] = (ltmp
>> 16);
4073 cmd
[3] = (ltmp
>> 8);
4079 ltmp
= ltmp
| (cmd
[2] << 16) | (cmd
[3] << 8) | cmd
[4];
4080 printk(OSST_DEB_MSG
"%s:D: Spacing tape backward %ld setmarks.\n",
4085 blkno
= fileno
= (-1);
4090 if ((STps
->rw
== ST_WRITING
|| STp
->dirty
) && !STp
->pos_unknown
) {
4091 STp
->write_type
= OS_WRITE_DATA
;
4092 ioctl_result
= osst_flush_write_buffer(STp
, &SRpnt
);
4097 printk(OSST_DEB_MSG
"%s:D: Writing %ld filemark(s).\n", name
, arg
);
4099 for (i
=0; i
<arg
; i
++)
4100 ioctl_result
|= osst_write_filemark(STp
, &SRpnt
);
4101 if (fileno
>= 0) fileno
+= arg
;
4102 if (blkno
>= 0) blkno
= 0;
4106 if (STp
->write_prot
)
4110 cmd
[0] = WRITE_FILEMARKS
; /* FIXME -- need OS version */
4111 if (cmd_in
== MTWSM
)
4113 cmd
[2] = (arg
>> 16);
4114 cmd
[3] = (arg
>> 8);
4116 timeout
= STp
->timeout
;
4119 printk(OSST_DEB_MSG
"%s:D: Writing %d setmark(s).\n", name
,
4120 cmd
[2] * 65536 + cmd
[3] * 256 + cmd
[4]);
4125 at_sm
= (cmd_in
== MTWSM
);
4131 cmd
[0] = START_STOP
;
4132 cmd
[1] = 1; /* Don't wait for completion */
4133 if (cmd_in
== MTLOAD
) {
4134 if (STp
->ready
== ST_NO_TAPE
)
4135 cmd
[4] = 4; /* open tray */
4137 cmd
[4] = 1; /* load */
4139 if (cmd_in
== MTRETEN
)
4140 cmd
[4] = 3; /* retension then mount */
4141 if (cmd_in
== MTOFFL
)
4142 cmd
[4] = 4; /* rewind then eject */
4143 timeout
= STp
->timeout
;
4148 printk(OSST_DEB_MSG
"%s:D: Unloading tape.\n", name
);
4151 printk(OSST_DEB_MSG
"%s:D: Loading tape.\n", name
);
4154 printk(OSST_DEB_MSG
"%s:D: Retensioning tape.\n", name
);
4157 printk(OSST_DEB_MSG
"%s:D: Ejecting tape.\n", name
);
4162 fileno
= blkno
= at_sm
= frame_seq_numbr
= logical_blk_num
= 0 ;
4167 printk(OSST_DEB_MSG
"%s:D: No-op on tape.\n", name
);
4169 return 0; /* Should do something ? */
4174 printk(OSST_DEB_MSG
"%s:D: Spacing to end of recorded medium.\n", name
);
4176 if ((osst_position_tape_and_confirm(STp
, &SRpnt
, STp
->eod_frame_ppos
) < 0) ||
4177 (osst_get_logical_frame(STp
, &SRpnt
, -1, 0) < 0)) {
4178 ioctl_result
= -EIO
;
4181 if (STp
->buffer
->aux
->frame_type
!= OS_FRAME_TYPE_EOD
) {
4183 printk(OSST_DEB_MSG
"%s:D: No EOD frame found where expected.\n", name
);
4185 ioctl_result
= -EIO
;
4188 ioctl_result
= osst_set_frame_position(STp
, &SRpnt
, STp
->eod_frame_ppos
, 0);
4189 fileno
= STp
->filemark_cnt
;
4194 if (STp
->write_prot
)
4196 ioctl_result
= osst_reset_header(STp
, &SRpnt
);
4197 i
= osst_write_eod(STp
, &SRpnt
);
4198 if (i
< ioctl_result
) ioctl_result
= i
;
4199 i
= osst_position_tape_and_confirm(STp
, &SRpnt
, STp
->eod_frame_ppos
);
4200 if (i
< ioctl_result
) ioctl_result
= i
;
4201 fileno
= blkno
= at_sm
= 0 ;
4205 cmd
[0] = REZERO_UNIT
; /* rewind */
4209 printk(OSST_DEB_MSG
"%s:D: Rewinding tape, Immed=%d.\n", name
, cmd
[1]);
4211 fileno
= blkno
= at_sm
= frame_seq_numbr
= logical_blk_num
= 0 ;
4214 case MTSETBLK
: /* Set block length */
4215 if ((STps
->drv_block
== 0 ) &&
4217 ((STp
->buffer
)->buffer_bytes
== 0) &&
4218 ((arg
& MT_ST_BLKSIZE_MASK
) >= 512 ) &&
4219 ((arg
& MT_ST_BLKSIZE_MASK
) <= OS_DATA_SIZE
) &&
4220 !(OS_DATA_SIZE
% (arg
& MT_ST_BLKSIZE_MASK
)) ) {
4222 * Only allowed to change the block size if you opened the
4223 * device at the beginning of a file before writing anything.
4224 * Note, that when reading, changing block_size is futile,
4225 * as the size used when writing overrides it.
4227 STp
->block_size
= (arg
& MT_ST_BLKSIZE_MASK
);
4228 printk(KERN_INFO
"%s:I: Block size set to %d bytes.\n",
4229 name
, STp
->block_size
);
4232 case MTSETDENSITY
: /* Set tape density */
4233 case MTSETDRVBUFFER
: /* Set drive buffering */
4234 case SET_DENS_AND_BLK
: /* Set density and block size */
4236 if (STp
->dirty
|| (STp
->buffer
)->buffer_bytes
!= 0)
4237 return (-EIO
); /* Not allowed if data in buffer */
4238 if ((cmd_in
== MTSETBLK
|| cmd_in
== SET_DENS_AND_BLK
) &&
4239 (arg
& MT_ST_BLKSIZE_MASK
) != 0 &&
4240 (arg
& MT_ST_BLKSIZE_MASK
) != STp
->block_size
) {
4241 printk(KERN_WARNING
"%s:W: Illegal to set block size to %d%s.\n",
4242 name
, (int)(arg
& MT_ST_BLKSIZE_MASK
),
4243 (OS_DATA_SIZE
% (arg
& MT_ST_BLKSIZE_MASK
))?"":" now");
4246 return 0; /* FIXME silently ignore if block size didn't change */
4252 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, datalen
, direction
, timeout
, MAX_RETRIES
, 1);
4254 ioctl_result
= (STp
->buffer
)->syscall_result
;
4258 printk(OSST_DEB_MSG
"%s:D: Couldn't exec scsi cmd for IOCTL\n", name
);
4260 return ioctl_result
;
4263 if (!ioctl_result
) { /* SCSI command successful */
4264 STp
->frame_seq_number
= frame_seq_numbr
;
4265 STp
->logical_blk_num
= logical_blk_num
;
4271 printk(OSST_DEB_MSG
"%s:D: IOCTL (%d) Result=%d\n", name
, cmd_in
, ioctl_result
);
4274 if (!ioctl_result
) { /* success */
4276 if (cmd_in
== MTFSFM
) {
4280 if (cmd_in
== MTBSFM
) {
4284 STps
->drv_block
= blkno
;
4285 STps
->drv_file
= fileno
;
4286 STps
->at_sm
= at_sm
;
4288 if (cmd_in
== MTEOM
)
4290 else if ((cmd_in
== MTFSFM
|| cmd_in
== MTBSF
) && STps
->eof
== ST_FM_HIT
) {
4291 ioctl_result
= osst_seek_logical_blk(STp
, &SRpnt
, STp
->logical_blk_num
-1);
4293 STp
->logical_blk_num
++;
4294 STp
->frame_seq_number
++;
4295 STp
->frame_in_buffer
= 0;
4296 STp
->buffer
->read_pointer
= 0;
4298 else if (cmd_in
== MTFSF
)
4299 STps
->eof
= (STp
->first_frame_position
>= STp
->eod_frame_ppos
)?ST_EOD
:ST_FM
;
4301 STps
->eof
= ST_NOEOF
;
4303 if (cmd_in
== MTOFFL
|| cmd_in
== MTUNLOAD
)
4304 STp
->rew_at_close
= 0;
4305 else if (cmd_in
== MTLOAD
) {
4306 for (i
=0; i
< ST_NBR_PARTITIONS
; i
++) {
4307 STp
->ps
[i
].rw
= ST_IDLE
;
4308 STp
->ps
[i
].last_block_valid
= 0;/* FIXME - where else is this field maintained? */
4313 if (cmd_in
== MTREW
) {
4314 ioctl_result
= osst_position_tape_and_confirm(STp
, &SRpnt
, STp
->first_data_ppos
);
4315 if (ioctl_result
> 0)
4319 } else if (cmd_in
== MTBSF
|| cmd_in
== MTBSFM
) {
4320 if (osst_position_tape_and_confirm(STp
, &SRpnt
, STp
->first_data_ppos
) < 0)
4321 STps
->drv_file
= STps
->drv_block
= -1;
4323 STps
->drv_file
= STps
->drv_block
= 0;
4324 STps
->eof
= ST_NOEOF
;
4325 } else if (cmd_in
== MTFSF
|| cmd_in
== MTFSFM
) {
4326 if (osst_position_tape_and_confirm(STp
, &SRpnt
, STp
->eod_frame_ppos
) < 0)
4327 STps
->drv_file
= STps
->drv_block
= -1;
4329 STps
->drv_file
= STp
->filemark_cnt
;
4330 STps
->drv_block
= 0;
4333 } else if (cmd_in
== MTBSR
|| cmd_in
== MTFSR
|| cmd_in
== MTWEOF
|| cmd_in
== MTEOM
) {
4334 STps
->drv_file
= STps
->drv_block
= (-1);
4335 STps
->eof
= ST_NOEOF
;
4337 } else if (cmd_in
== MTERASE
) {
4339 } else if (SRpnt
) { /* SCSI command was not completely successful. */
4340 if (SRpnt
->sense
[2] & 0x40) {
4341 STps
->eof
= ST_EOM_OK
;
4342 STps
->drv_block
= 0;
4345 STps
->eof
= ST_NOEOF
;
4347 if ((SRpnt
->sense
[2] & 0x0f) == BLANK_CHECK
)
4350 if (cmd_in
== MTLOAD
&& osst_wait_for_medium(STp
, &SRpnt
, 60))
4351 ioctl_result
= osst_wait_ready(STp
, &SRpnt
, 5 * 60, OSST_WAIT_POSITION_COMPLETE
);
4355 return ioctl_result
;
4359 /* Open the device */
4360 static int os_scsi_tape_open(struct inode
* inode
, struct file
* filp
)
4362 unsigned short flags
;
4363 int i
, b_size
, new_session
= 0, retval
= 0;
4364 unsigned char cmd
[MAX_COMMAND_SIZE
];
4365 struct osst_request
* SRpnt
= NULL
;
4366 struct osst_tape
* STp
;
4367 struct st_modedef
* STm
;
4368 struct st_partstat
* STps
;
4370 int dev
= TAPE_NR(inode
);
4371 int mode
= TAPE_MODE(inode
);
4374 * We really want to do nonseekable_open(inode, filp); here, but some
4375 * versions of tar incorrectly call lseek on tapes and bail out if that
4376 * fails. So we disallow pread() and pwrite(), but permit lseeks.
4378 filp
->f_mode
&= ~(FMODE_PREAD
| FMODE_PWRITE
);
4380 write_lock(&os_scsi_tapes_lock
);
4381 if (dev
>= osst_max_dev
|| os_scsi_tapes
== NULL
||
4382 (STp
= os_scsi_tapes
[dev
]) == NULL
|| !STp
->device
) {
4383 write_unlock(&os_scsi_tapes_lock
);
4387 name
= tape_name(STp
);
4390 write_unlock(&os_scsi_tapes_lock
);
4392 printk(OSST_DEB_MSG
"%s:D: Device already in use.\n", name
);
4396 if (scsi_device_get(STp
->device
)) {
4397 write_unlock(&os_scsi_tapes_lock
);
4399 printk(OSST_DEB_MSG
"%s:D: Failed scsi_device_get.\n", name
);
4403 filp
->private_data
= STp
;
4405 write_unlock(&os_scsi_tapes_lock
);
4406 STp
->rew_at_close
= TAPE_REWIND(inode
);
4408 if( !scsi_block_when_processing_errors(STp
->device
) ) {
4412 if (mode
!= STp
->current_mode
) {
4415 printk(OSST_DEB_MSG
"%s:D: Mode change from %d to %d.\n",
4416 name
, STp
->current_mode
, mode
);
4419 STp
->current_mode
= mode
;
4421 STm
= &(STp
->modes
[STp
->current_mode
]);
4423 flags
= filp
->f_flags
;
4424 STp
->write_prot
= ((flags
& O_ACCMODE
) == O_RDONLY
);
4426 STp
->raw
= TAPE_IS_RAW(inode
);
4430 /* Allocate data segments for this device's tape buffer */
4431 if (!enlarge_buffer(STp
->buffer
, STp
->restr_dma
)) {
4432 printk(KERN_ERR
"%s:E: Unable to allocate memory segments for tape buffer.\n", name
);
4433 retval
= (-EOVERFLOW
);
4436 if (STp
->buffer
->buffer_size
>= OS_FRAME_SIZE
) {
4437 for (i
= 0, b_size
= 0;
4438 (i
< STp
->buffer
->sg_segs
) && ((b_size
+ STp
->buffer
->sg
[i
].length
) <= OS_DATA_SIZE
);
4439 b_size
+= STp
->buffer
->sg
[i
++].length
);
4440 STp
->buffer
->aux
= (os_aux_t
*) (page_address(STp
->buffer
->sg
[i
].page
) + OS_DATA_SIZE
- b_size
);
4442 printk(OSST_DEB_MSG
"%s:D: b_data points to %p in segment 0 at %p\n", name
,
4443 STp
->buffer
->b_data
, page_address(STp
->buffer
->sg
[0].page
));
4444 printk(OSST_DEB_MSG
"%s:D: AUX points to %p in segment %d at %p\n", name
,
4445 STp
->buffer
->aux
, i
, page_address(STp
->buffer
->sg
[i
].page
));
4448 STp
->buffer
->aux
= NULL
; /* this had better never happen! */
4449 printk(KERN_NOTICE
"%s:A: Framesize %d too large for buffer.\n", name
, OS_FRAME_SIZE
);
4453 STp
->buffer
->writing
= 0;
4454 STp
->buffer
->syscall_result
= 0;
4456 for (i
=0; i
< ST_NBR_PARTITIONS
; i
++) {
4457 STps
= &(STp
->ps
[i
]);
4460 STp
->ready
= ST_READY
;
4462 STp
->nbr_waits
= STp
->nbr_finished
= 0;
4465 memset (cmd
, 0, MAX_COMMAND_SIZE
);
4466 cmd
[0] = TEST_UNIT_READY
;
4468 SRpnt
= osst_do_scsi(NULL
, STp
, cmd
, 0, DMA_NONE
, STp
->timeout
, MAX_RETRIES
, 1);
4470 retval
= (STp
->buffer
)->syscall_result
; /* FIXME - valid? */
4473 if ((SRpnt
->sense
[0] & 0x70) == 0x70 &&
4474 (SRpnt
->sense
[2] & 0x0f) == NOT_READY
&&
4475 SRpnt
->sense
[12] == 4 ) {
4477 printk(OSST_DEB_MSG
"%s:D: Unit not ready, cause %x\n", name
, SRpnt
->sense
[13]);
4479 if (filp
->f_flags
& O_NONBLOCK
) {
4483 if (SRpnt
->sense
[13] == 2) { /* initialize command required (LOAD) */
4484 memset (cmd
, 0, MAX_COMMAND_SIZE
);
4485 cmd
[0] = START_STOP
;
4488 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, 0, DMA_NONE
,
4489 STp
->timeout
, MAX_RETRIES
, 1);
4491 osst_wait_ready(STp
, &SRpnt
, (SRpnt
->sense
[13]==1?15:3) * 60, 0);
4493 if ((SRpnt
->sense
[0] & 0x70) == 0x70 &&
4494 (SRpnt
->sense
[2] & 0x0f) == UNIT_ATTENTION
) { /* New media? */
4496 printk(OSST_DEB_MSG
"%s:D: Unit wants attention\n", name
);
4500 for (i
=0; i
< 10; i
++) {
4502 memset (cmd
, 0, MAX_COMMAND_SIZE
);
4503 cmd
[0] = TEST_UNIT_READY
;
4505 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, 0, DMA_NONE
,
4506 STp
->timeout
, MAX_RETRIES
, 1);
4507 if ((SRpnt
->sense
[0] & 0x70) != 0x70 ||
4508 (SRpnt
->sense
[2] & 0x0f) != UNIT_ATTENTION
)
4512 STp
->pos_unknown
= 0;
4513 STp
->partition
= STp
->new_partition
= 0;
4514 if (STp
->can_partitions
)
4515 STp
->nbr_partitions
= 1; /* This guess will be updated later if necessary */
4516 for (i
=0; i
< ST_NBR_PARTITIONS
; i
++) {
4517 STps
= &(STp
->ps
[i
]);
4518 STps
->rw
= ST_IDLE
; /* FIXME - seems to be redundant... */
4519 STps
->eof
= ST_NOEOF
;
4521 STps
->last_block_valid
= 0;
4522 STps
->drv_block
= 0;
4523 STps
->drv_file
= 0 ;
4526 STp
->recover_count
= 0;
4527 STp
->abort_count
= 0;
4530 * if we have valid headers from before, and the drive/tape seem untouched,
4531 * open without reconfiguring and re-reading the headers
4533 if (!STp
->buffer
->syscall_result
&& STp
->header_ok
&&
4534 !SRpnt
->result
&& SRpnt
->sense
[0] == 0) {
4536 memset(cmd
, 0, MAX_COMMAND_SIZE
);
4537 cmd
[0] = MODE_SENSE
;
4539 cmd
[2] = VENDOR_IDENT_PAGE
;
4540 cmd
[4] = VENDOR_IDENT_PAGE_LENGTH
+ MODE_HEADER_LENGTH
;
4542 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, cmd
[4], DMA_FROM_DEVICE
, STp
->timeout
, 0, 1);
4544 if (STp
->buffer
->syscall_result
||
4545 STp
->buffer
->b_data
[MODE_HEADER_LENGTH
+ 2] != 'L' ||
4546 STp
->buffer
->b_data
[MODE_HEADER_LENGTH
+ 3] != 'I' ||
4547 STp
->buffer
->b_data
[MODE_HEADER_LENGTH
+ 4] != 'N' ||
4548 STp
->buffer
->b_data
[MODE_HEADER_LENGTH
+ 5] != '4' ) {
4550 printk(OSST_DEB_MSG
"%s:D: Signature was changed to %c%c%c%c\n", name
,
4551 STp
->buffer
->b_data
[MODE_HEADER_LENGTH
+ 2],
4552 STp
->buffer
->b_data
[MODE_HEADER_LENGTH
+ 3],
4553 STp
->buffer
->b_data
[MODE_HEADER_LENGTH
+ 4],
4554 STp
->buffer
->b_data
[MODE_HEADER_LENGTH
+ 5]);
4558 i
= STp
->first_frame_position
;
4559 if (STp
->header_ok
&& i
== osst_get_frame_position(STp
, &SRpnt
)) {
4560 if (STp
->door_locked
== ST_UNLOCKED
) {
4561 if (do_door_lock(STp
, 1))
4562 printk(KERN_INFO
"%s:I: Can't lock drive door\n", name
);
4564 STp
->door_locked
= ST_LOCKED_AUTO
;
4566 if (!STp
->frame_in_buffer
) {
4567 STp
->block_size
= (STm
->default_blksize
> 0) ?
4568 STm
->default_blksize
: OS_DATA_SIZE
;
4569 STp
->buffer
->buffer_bytes
= STp
->buffer
->read_pointer
= 0;
4571 STp
->buffer
->buffer_blocks
= OS_DATA_SIZE
/ STp
->block_size
;
4573 osst_release_request(SRpnt
);
4577 if (i
!= STp
->first_frame_position
)
4578 printk(OSST_DEB_MSG
"%s:D: Tape position changed from %d to %d\n",
4579 name
, i
, STp
->first_frame_position
);
4585 if ((STp
->buffer
)->syscall_result
!= 0 && /* in all error conditions except no medium */
4586 (SRpnt
->sense
[2] != 2 || SRpnt
->sense
[12] != 0x3A) ) {
4588 memset(cmd
, 0, MAX_COMMAND_SIZE
);
4589 cmd
[0] = MODE_SELECT
;
4591 cmd
[4] = 4 + MODE_HEADER_LENGTH
;
4593 (STp
->buffer
)->b_data
[0] = cmd
[4] - 1;
4594 (STp
->buffer
)->b_data
[1] = 0; /* Medium Type - ignoring */
4595 (STp
->buffer
)->b_data
[2] = 0; /* Reserved */
4596 (STp
->buffer
)->b_data
[3] = 0; /* Block Descriptor Length */
4597 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 0] = 0x3f;
4598 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 1] = 1;
4599 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 2] = 2;
4600 (STp
->buffer
)->b_data
[MODE_HEADER_LENGTH
+ 3] = 3;
4603 printk(OSST_DEB_MSG
"%s:D: Applying soft reset\n", name
);
4605 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, cmd
[4], DMA_TO_DEVICE
, STp
->timeout
, 0, 1);
4609 for (i
=0; i
< 10; i
++) {
4611 memset (cmd
, 0, MAX_COMMAND_SIZE
);
4612 cmd
[0] = TEST_UNIT_READY
;
4614 SRpnt
= osst_do_scsi(SRpnt
, STp
, cmd
, 0, DMA_NONE
,
4615 STp
->timeout
, MAX_RETRIES
, 1);
4616 if ((SRpnt
->sense
[0] & 0x70) != 0x70 ||
4617 (SRpnt
->sense
[2] & 0x0f) == NOT_READY
)
4620 if ((SRpnt
->sense
[2] & 0x0f) == UNIT_ATTENTION
) {
4621 STp
->pos_unknown
= 0;
4622 STp
->partition
= STp
->new_partition
= 0;
4623 if (STp
->can_partitions
)
4624 STp
->nbr_partitions
= 1; /* This guess will be updated later if necessary */
4625 for (i
=0; i
< ST_NBR_PARTITIONS
; i
++) {
4626 STps
= &(STp
->ps
[i
]);
4628 STps
->eof
= ST_NOEOF
;
4630 STps
->last_block_valid
= 0;
4631 STps
->drv_block
= 0;
4632 STps
->drv_file
= 0 ;
4639 if (osst_wait_ready(STp
, &SRpnt
, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4640 printk(KERN_INFO
"%s:I: Device did not become Ready in open\n", name
);
4642 if ((STp
->buffer
)->syscall_result
!= 0) {
4643 if ((STp
->device
)->scsi_level
>= SCSI_2
&&
4644 (SRpnt
->sense
[0] & 0x70) == 0x70 &&
4645 (SRpnt
->sense
[2] & 0x0f) == NOT_READY
&&
4646 SRpnt
->sense
[12] == 0x3a) { /* Check ASC */
4647 STp
->ready
= ST_NO_TAPE
;
4649 STp
->ready
= ST_NOT_READY
;
4650 osst_release_request(SRpnt
);
4652 STp
->density
= 0; /* Clear the erroneous "residue" */
4653 STp
->write_prot
= 0;
4654 STp
->block_size
= 0;
4655 STp
->ps
[0].drv_file
= STp
->ps
[0].drv_block
= (-1);
4656 STp
->partition
= STp
->new_partition
= 0;
4657 STp
->door_locked
= ST_UNLOCKED
;
4661 osst_configure_onstream(STp
, &SRpnt
);
4663 STp
->block_size
= STp
->raw
? OS_FRAME_SIZE
: (
4664 (STm
->default_blksize
> 0) ? STm
->default_blksize
: OS_DATA_SIZE
);
4665 STp
->buffer
->buffer_blocks
= STp
->raw
? 1 : OS_DATA_SIZE
/ STp
->block_size
;
4666 STp
->buffer
->buffer_bytes
=
4667 STp
->buffer
->read_pointer
=
4668 STp
->frame_in_buffer
= 0;
4672 printk(OSST_DEB_MSG
"%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4673 name
, STp
->block_size
, OS_FRAME_SIZE
, (STp
->buffer
)->buffer_size
,
4674 (STp
->buffer
)->buffer_blocks
);
4677 if (STp
->drv_write_prot
) {
4678 STp
->write_prot
= 1;
4681 printk(OSST_DEB_MSG
"%s:D: Write protected\n", name
);
4683 if ((flags
& O_ACCMODE
) == O_WRONLY
|| (flags
& O_ACCMODE
) == O_RDWR
) {
4689 if (new_session
) { /* Change the drive parameters for the new mode */
4692 printk(OSST_DEB_MSG
"%s:D: New Session\n", name
);
4694 STp
->density_changed
= STp
->blksize_changed
= 0;
4695 STp
->compression_changed
= 0;
4699 * properly position the tape and check the ADR headers
4701 if (STp
->door_locked
== ST_UNLOCKED
) {
4702 if (do_door_lock(STp
, 1))
4703 printk(KERN_INFO
"%s:I: Can't lock drive door\n", name
);
4705 STp
->door_locked
= ST_LOCKED_AUTO
;
4708 osst_analyze_headers(STp
, &SRpnt
);
4710 osst_release_request(SRpnt
);
4717 osst_release_request(SRpnt
);
4718 normalize_buffer(STp
->buffer
);
4721 scsi_device_put(STp
->device
);
4727 /* Flush the tape buffer before close */
4728 static int os_scsi_tape_flush(struct file
* filp
, fl_owner_t id
)
4730 int result
= 0, result2
;
4731 struct osst_tape
* STp
= filp
->private_data
;
4732 struct st_modedef
* STm
= &(STp
->modes
[STp
->current_mode
]);
4733 struct st_partstat
* STps
= &(STp
->ps
[STp
->partition
]);
4734 struct osst_request
* SRpnt
= NULL
;
4735 char * name
= tape_name(STp
);
4737 if (file_count(filp
) > 1)
4740 if ((STps
->rw
== ST_WRITING
|| STp
->dirty
) && !STp
->pos_unknown
) {
4741 STp
->write_type
= OS_WRITE_DATA
;
4742 result
= osst_flush_write_buffer(STp
, &SRpnt
);
4743 if (result
!= 0 && result
!= (-ENOSPC
))
4746 if ( STps
->rw
>= ST_WRITING
&& !STp
->pos_unknown
) {
4750 printk(OSST_DEB_MSG
"%s:D: File length %ld bytes.\n",
4751 name
, (long)(filp
->f_pos
));
4752 printk(OSST_DEB_MSG
"%s:D: Async write waits %d, finished %d.\n",
4753 name
, STp
->nbr_waits
, STp
->nbr_finished
);
4756 result
= osst_write_trailer(STp
, &SRpnt
, !(STp
->rew_at_close
));
4759 printk(OSST_DEB_MSG
"%s:D: Buffer flushed, %d EOF(s) written\n",
4760 name
, 1+STp
->two_fm
);
4763 else if (!STp
->rew_at_close
) {
4764 STps
= &(STp
->ps
[STp
->partition
]);
4765 if (!STm
->sysv
|| STps
->rw
!= ST_READING
) {
4767 result
= osst_flush_buffer(STp
, &SRpnt
, 0); /* this is the default path */
4768 else if (STps
->eof
== ST_FM_HIT
) {
4769 result
= cross_eof(STp
, &SRpnt
, 0);
4771 if (STps
->drv_file
>= 0)
4773 STps
->drv_block
= 0;
4777 STps
->eof
= ST_NOEOF
;
4780 else if ((STps
->eof
== ST_NOEOF
&&
4781 !(result
= cross_eof(STp
, &SRpnt
, 1))) ||
4782 STps
->eof
== ST_FM_HIT
) {
4783 if (STps
->drv_file
>= 0)
4785 STps
->drv_block
= 0;
4791 if (STp
->rew_at_close
) {
4792 result2
= osst_position_tape_and_confirm(STp
, &SRpnt
, STp
->first_data_ppos
);
4793 STps
->drv_file
= STps
->drv_block
= STp
->frame_seq_number
= STp
->logical_blk_num
= 0;
4794 if (result
== 0 && result2
< 0)
4797 if (SRpnt
) osst_release_request(SRpnt
);
4799 if (STp
->abort_count
|| STp
->recover_count
) {
4800 printk(KERN_INFO
"%s:I:", name
);
4801 if (STp
->abort_count
)
4802 printk(" %d unrecovered errors", STp
->abort_count
);
4803 if (STp
->recover_count
)
4804 printk(" %d recovered errors", STp
->recover_count
);
4805 if (STp
->write_count
)
4806 printk(" in %d frames written", STp
->write_count
);
4807 if (STp
->read_count
)
4808 printk(" in %d frames read", STp
->read_count
);
4810 STp
->recover_count
= 0;
4811 STp
->abort_count
= 0;
4813 STp
->write_count
= 0;
4814 STp
->read_count
= 0;
4820 /* Close the device and release it */
4821 static int os_scsi_tape_close(struct inode
* inode
, struct file
* filp
)
4824 struct osst_tape
* STp
= filp
->private_data
;
4826 if (STp
->door_locked
== ST_LOCKED_AUTO
)
4827 do_door_lock(STp
, 0);
4832 normalize_buffer(STp
->buffer
);
4833 write_lock(&os_scsi_tapes_lock
);
4835 write_unlock(&os_scsi_tapes_lock
);
4837 scsi_device_put(STp
->device
);
4843 /* The ioctl command */
4844 static int osst_ioctl(struct inode
* inode
,struct file
* file
,
4845 unsigned int cmd_in
, unsigned long arg
)
4847 int i
, cmd_nr
, cmd_type
, blk
, retval
= 0;
4848 struct st_modedef
* STm
;
4849 struct st_partstat
* STps
;
4850 struct osst_request
* SRpnt
= NULL
;
4851 struct osst_tape
* STp
= file
->private_data
;
4852 char * name
= tape_name(STp
);
4853 void __user
* p
= (void __user
*)arg
;
4855 if (mutex_lock_interruptible(&STp
->lock
))
4856 return -ERESTARTSYS
;
4859 if (debugging
&& !STp
->in_use
) {
4860 printk(OSST_DEB_MSG
"%s:D: Incorrect device.\n", name
);
4865 STm
= &(STp
->modes
[STp
->current_mode
]);
4866 STps
= &(STp
->ps
[STp
->partition
]);
4869 * If we are in the middle of error recovery, don't let anyone
4870 * else try and use this device. Also, if error recovery fails, it
4871 * may try and take the device offline, in which case all further
4872 * access to the device is prohibited.
4874 if( !scsi_block_when_processing_errors(STp
->device
) ) {
4879 cmd_type
= _IOC_TYPE(cmd_in
);
4880 cmd_nr
= _IOC_NR(cmd_in
);
4882 printk(OSST_DEB_MSG
"%s:D: Ioctl %d,%d in %s mode\n", name
,
4883 cmd_type
, cmd_nr
, STp
->raw
?"raw":"normal");
4885 if (cmd_type
== _IOC_TYPE(MTIOCTOP
) && cmd_nr
== _IOC_NR(MTIOCTOP
)) {
4889 if (_IOC_SIZE(cmd_in
) != sizeof(mtc
)) {
4894 i
= copy_from_user((char *) &mtc
, p
, sizeof(struct mtop
));
4900 if (mtc
.mt_op
== MTSETDRVBUFFER
&& !capable(CAP_SYS_ADMIN
)) {
4901 printk(KERN_WARNING
"%s:W: MTSETDRVBUFFER only allowed for root.\n", name
);
4906 if (!STm
->defined
&& (mtc
.mt_op
!= MTSETDRVBUFFER
&& (mtc
.mt_count
& MT_ST_OPTIONS
) == 0)) {
4911 if (!STp
->pos_unknown
) {
4913 if (STps
->eof
== ST_FM_HIT
) {
4914 if (mtc
.mt_op
== MTFSF
|| mtc
.mt_op
== MTFSFM
|| mtc
.mt_op
== MTEOM
) {
4916 if (STps
->drv_file
>= 0)
4917 STps
->drv_file
+= 1;
4919 else if (mtc
.mt_op
== MTBSF
|| mtc
.mt_op
== MTBSFM
) {
4921 if (STps
->drv_file
>= 0)
4922 STps
->drv_file
+= 1;
4926 if (mtc
.mt_op
== MTSEEK
) {
4927 /* Old position must be restored if partition will be changed */
4928 i
= !STp
->can_partitions
|| (STp
->new_partition
!= STp
->partition
);
4931 i
= mtc
.mt_op
== MTREW
|| mtc
.mt_op
== MTOFFL
||
4932 mtc
.mt_op
== MTRETEN
|| mtc
.mt_op
== MTEOM
||
4933 mtc
.mt_op
== MTLOCK
|| mtc
.mt_op
== MTLOAD
||
4934 mtc
.mt_op
== MTFSF
|| mtc
.mt_op
== MTFSFM
||
4935 mtc
.mt_op
== MTBSF
|| mtc
.mt_op
== MTBSFM
||
4936 mtc
.mt_op
== MTCOMPRESSION
;
4938 i
= osst_flush_buffer(STp
, &SRpnt
, i
);
4946 * If there was a bus reset, block further access
4947 * to this device. If the user wants to rewind the tape,
4948 * then reset the flag and allow access again.
4950 if(mtc
.mt_op
!= MTREW
&&
4951 mtc
.mt_op
!= MTOFFL
&&
4952 mtc
.mt_op
!= MTRETEN
&&
4953 mtc
.mt_op
!= MTERASE
&&
4954 mtc
.mt_op
!= MTSEEK
&&
4955 mtc
.mt_op
!= MTEOM
) {
4960 /* remove this when the midlevel properly clears was_reset */
4961 STp
->device
->was_reset
= 0;
4964 if (mtc
.mt_op
!= MTCOMPRESSION
&& mtc
.mt_op
!= MTLOCK
&&
4965 mtc
.mt_op
!= MTNOP
&& mtc
.mt_op
!= MTSETBLK
&&
4966 mtc
.mt_op
!= MTSETDENSITY
&& mtc
.mt_op
!= MTSETDRVBUFFER
&&
4967 mtc
.mt_op
!= MTMKPART
&& mtc
.mt_op
!= MTSETPART
&&
4968 mtc
.mt_op
!= MTWEOF
&& mtc
.mt_op
!= MTWSM
) {
4971 * The user tells us to move to another position on the tape.
4972 * If we were appending to the tape content, that would leave
4973 * the tape without proper end, in that case write EOD and
4974 * update the header to reflect its position.
4977 printk(KERN_WARNING
"%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name
,
4978 STps
->rw
>= ST_WRITING
? "write" : STps
->rw
== ST_READING
? "read" : "idle",
4979 STp
->first_frame_position
, STp
->eod_frame_ppos
, STp
->frame_seq_number
,
4980 STp
->logical_blk_num
, STps
->drv_file
, STps
->drv_block
);
4982 if (STps
->rw
>= ST_WRITING
&& STp
->first_frame_position
>= STp
->eod_frame_ppos
) {
4983 auto_weof
= ((STp
->write_type
!= OS_WRITE_NEW_MARK
) &&
4984 !(mtc
.mt_op
== MTREW
|| mtc
.mt_op
== MTOFFL
));
4985 i
= osst_write_trailer(STp
, &SRpnt
,
4986 !(mtc
.mt_op
== MTREW
|| mtc
.mt_op
== MTOFFL
));
4988 printk(KERN_WARNING
"%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
4989 name
, auto_weof
, STp
->first_frame_position
, STp
->eod_frame_ppos
,
4990 STp
->frame_seq_number
, STp
->logical_blk_num
, STps
->drv_file
, STps
->drv_block
);
5000 if (mtc
.mt_op
== MTOFFL
&& STp
->door_locked
!= ST_UNLOCKED
)
5001 do_door_lock(STp
, 0); /* Ignore result! */
5003 if (mtc
.mt_op
== MTSETDRVBUFFER
&&
5004 (mtc
.mt_count
& MT_ST_OPTIONS
) != 0) {
5005 retval
= osst_set_options(STp
, mtc
.mt_count
);
5009 if (mtc
.mt_op
== MTSETPART
) {
5010 if (mtc
.mt_count
>= STp
->nbr_partitions
)
5013 STp
->new_partition
= mtc
.mt_count
;
5019 if (mtc
.mt_op
== MTMKPART
) {
5020 if (!STp
->can_partitions
) {
5024 if ((i
= osst_int_ioctl(STp
, &SRpnt
, MTREW
, 0)) < 0 /*||
5025 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
5029 for (i
=0; i
< ST_NBR_PARTITIONS
; i
++) {
5030 STp
->ps
[i
].rw
= ST_IDLE
;
5031 STp
->ps
[i
].at_sm
= 0;
5032 STp
->ps
[i
].last_block_valid
= 0;
5034 STp
->partition
= STp
->new_partition
= 0;
5035 STp
->nbr_partitions
= 1; /* Bad guess ?-) */
5036 STps
->drv_block
= STps
->drv_file
= 0;
5041 if (mtc
.mt_op
== MTSEEK
) {
5043 i
= osst_set_frame_position(STp
, &SRpnt
, mtc
.mt_count
, 0);
5045 i
= osst_seek_sector(STp
, &SRpnt
, mtc
.mt_count
);
5046 if (!STp
->can_partitions
)
5047 STp
->ps
[0].rw
= ST_IDLE
;
5052 if (mtc
.mt_op
== MTLOCK
|| mtc
.mt_op
== MTUNLOCK
) {
5053 retval
= do_door_lock(STp
, (mtc
.mt_op
== MTLOCK
));
5058 cross_eof(STp
, &SRpnt
, 0);
5060 if (mtc
.mt_op
== MTCOMPRESSION
)
5061 retval
= -EINVAL
; /* OnStream drives don't have compression hardware */
5063 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5064 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5065 retval
= osst_int_ioctl(STp
, &SRpnt
, mtc
.mt_op
, mtc
.mt_count
);
5069 if (!STm
->defined
) {
5074 if ((i
= osst_flush_buffer(STp
, &SRpnt
, 0)) < 0) {
5079 if (cmd_type
== _IOC_TYPE(MTIOCGET
) && cmd_nr
== _IOC_NR(MTIOCGET
)) {
5080 struct mtget mt_status
;
5082 if (_IOC_SIZE(cmd_in
) != sizeof(struct mtget
)) {
5087 mt_status
.mt_type
= MT_ISONSTREAM_SC
;
5088 mt_status
.mt_erreg
= STp
->recover_erreg
<< MT_ST_SOFTERR_SHIFT
;
5089 mt_status
.mt_dsreg
=
5090 ((STp
->block_size
<< MT_ST_BLKSIZE_SHIFT
) & MT_ST_BLKSIZE_MASK
) |
5091 ((STp
->density
<< MT_ST_DENSITY_SHIFT
) & MT_ST_DENSITY_MASK
);
5092 mt_status
.mt_blkno
= STps
->drv_block
;
5093 mt_status
.mt_fileno
= STps
->drv_file
;
5094 if (STp
->block_size
!= 0) {
5095 if (STps
->rw
== ST_WRITING
)
5096 mt_status
.mt_blkno
+= (STp
->buffer
)->buffer_bytes
/ STp
->block_size
;
5097 else if (STps
->rw
== ST_READING
)
5098 mt_status
.mt_blkno
-= ((STp
->buffer
)->buffer_bytes
+
5099 STp
->block_size
- 1) / STp
->block_size
;
5102 mt_status
.mt_gstat
= 0;
5103 if (STp
->drv_write_prot
)
5104 mt_status
.mt_gstat
|= GMT_WR_PROT(0xffffffff);
5105 if (mt_status
.mt_blkno
== 0) {
5106 if (mt_status
.mt_fileno
== 0)
5107 mt_status
.mt_gstat
|= GMT_BOT(0xffffffff);
5109 mt_status
.mt_gstat
|= GMT_EOF(0xffffffff);
5111 mt_status
.mt_resid
= STp
->partition
;
5112 if (STps
->eof
== ST_EOM_OK
|| STps
->eof
== ST_EOM_ERROR
)
5113 mt_status
.mt_gstat
|= GMT_EOT(0xffffffff);
5114 else if (STps
->eof
>= ST_EOM_OK
)
5115 mt_status
.mt_gstat
|= GMT_EOD(0xffffffff);
5116 if (STp
->density
== 1)
5117 mt_status
.mt_gstat
|= GMT_D_800(0xffffffff);
5118 else if (STp
->density
== 2)
5119 mt_status
.mt_gstat
|= GMT_D_1600(0xffffffff);
5120 else if (STp
->density
== 3)
5121 mt_status
.mt_gstat
|= GMT_D_6250(0xffffffff);
5122 if (STp
->ready
== ST_READY
)
5123 mt_status
.mt_gstat
|= GMT_ONLINE(0xffffffff);
5124 if (STp
->ready
== ST_NO_TAPE
)
5125 mt_status
.mt_gstat
|= GMT_DR_OPEN(0xffffffff);
5127 mt_status
.mt_gstat
|= GMT_SM(0xffffffff);
5128 if (STm
->do_async_writes
|| (STm
->do_buffer_writes
&& STp
->block_size
!= 0) ||
5129 STp
->drv_buffer
!= 0)
5130 mt_status
.mt_gstat
|= GMT_IM_REP_EN(0xffffffff);
5132 i
= copy_to_user(p
, &mt_status
, sizeof(struct mtget
));
5138 STp
->recover_erreg
= 0; /* Clear after read */
5141 } /* End of MTIOCGET */
5143 if (cmd_type
== _IOC_TYPE(MTIOCPOS
) && cmd_nr
== _IOC_NR(MTIOCPOS
)) {
5144 struct mtpos mt_pos
;
5146 if (_IOC_SIZE(cmd_in
) != sizeof(struct mtpos
)) {
5151 blk
= osst_get_frame_position(STp
, &SRpnt
);
5153 blk
= osst_get_sector(STp
, &SRpnt
);
5158 mt_pos
.mt_blkno
= blk
;
5159 i
= copy_to_user(p
, &mt_pos
, sizeof(struct mtpos
));
5164 if (SRpnt
) osst_release_request(SRpnt
);
5166 mutex_unlock(&STp
->lock
);
5168 return scsi_ioctl(STp
->device
, cmd_in
, p
);
5171 if (SRpnt
) osst_release_request(SRpnt
);
5173 mutex_unlock(&STp
->lock
);
5178 #ifdef CONFIG_COMPAT
5179 static long osst_compat_ioctl(struct file
* file
, unsigned int cmd_in
, unsigned long arg
)
5181 struct osst_tape
*STp
= file
->private_data
;
5182 struct scsi_device
*sdev
= STp
->device
;
5183 int ret
= -ENOIOCTLCMD
;
5184 if (sdev
->host
->hostt
->compat_ioctl
) {
5186 ret
= sdev
->host
->hostt
->compat_ioctl(sdev
, cmd_in
, (void __user
*)arg
);
5195 /* Memory handling routines */
5197 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5198 static struct osst_buffer
* new_tape_buffer( int from_initialization
, int need_dma
, int max_sg
)
5202 struct osst_buffer
*tb
;
5204 if (from_initialization
)
5205 priority
= GFP_ATOMIC
;
5207 priority
= GFP_KERNEL
;
5209 i
= sizeof(struct osst_buffer
) + (osst_max_sg_segs
- 1) * sizeof(struct scatterlist
);
5210 tb
= kzalloc(i
, priority
);
5212 printk(KERN_NOTICE
"osst :I: Can't allocate new tape buffer.\n");
5216 tb
->sg_segs
= tb
->orig_sg_segs
= 0;
5217 tb
->use_sg
= max_sg
;
5220 tb
->buffer_size
= 0;
5224 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5225 i
, max_sg
, need_dma
);
5230 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5231 static int enlarge_buffer(struct osst_buffer
*STbuffer
, int need_dma
)
5233 int segs
, nbr
, max_segs
, b_size
, order
, got
;
5236 if (STbuffer
->buffer_size
>= OS_FRAME_SIZE
)
5239 if (STbuffer
->sg_segs
) {
5240 printk(KERN_WARNING
"osst :A: Buffer not previously normalized.\n");
5241 normalize_buffer(STbuffer
);
5243 /* See how many segments we can use -- need at least two */
5244 nbr
= max_segs
= STbuffer
->use_sg
;
5248 priority
= GFP_KERNEL
/* | __GFP_NOWARN */;
5250 priority
|= GFP_DMA
;
5252 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5253 big enough to reach the goal (code assumes no segments in place) */
5254 for (b_size
= OS_DATA_SIZE
, order
= OSST_FIRST_ORDER
; b_size
>= PAGE_SIZE
; order
--, b_size
/= 2) {
5255 STbuffer
->sg
[0].page
= alloc_pages(priority
, order
);
5256 STbuffer
->sg
[0].offset
= 0;
5257 if (STbuffer
->sg
[0].page
!= NULL
) {
5258 STbuffer
->sg
[0].length
= b_size
;
5259 STbuffer
->b_data
= page_address(STbuffer
->sg
[0].page
);
5263 if (STbuffer
->sg
[0].page
== NULL
) {
5264 printk(KERN_NOTICE
"osst :I: Can't allocate tape buffer main segment.\n");
5267 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5268 for (segs
=STbuffer
->sg_segs
=1, got
=b_size
;
5269 segs
< max_segs
&& got
< OS_FRAME_SIZE
; ) {
5270 STbuffer
->sg
[segs
].page
=
5271 alloc_pages(priority
, (OS_FRAME_SIZE
- got
<= PAGE_SIZE
) ? 0 : order
);
5272 STbuffer
->sg
[segs
].offset
= 0;
5273 if (STbuffer
->sg
[segs
].page
== NULL
) {
5274 if (OS_FRAME_SIZE
- got
<= (max_segs
- segs
) * b_size
/ 2 && order
) {
5275 b_size
/= 2; /* Large enough for the rest of the buffers */
5279 printk(KERN_WARNING
"osst :W: Failed to enlarge buffer to %d bytes.\n",
5282 STbuffer
->buffer_size
= got
;
5284 normalize_buffer(STbuffer
);
5287 STbuffer
->sg
[segs
].length
= (OS_FRAME_SIZE
- got
<= PAGE_SIZE
/ 2) ? (OS_FRAME_SIZE
- got
) : b_size
;
5288 got
+= STbuffer
->sg
[segs
].length
;
5289 STbuffer
->buffer_size
= got
;
5290 STbuffer
->sg_segs
= ++segs
;
5295 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5296 got
, STbuffer
->orig_sg_segs
, STbuffer
->sg_segs
, need_dma
, STbuffer
->b_data
);
5298 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5299 STbuffer
->sg
[0].length
, page_address(STbuffer
->sg
[0].page
),
5300 STbuffer
->sg
[segs
-1].length
, page_address(STbuffer
->sg
[segs
-1].page
));
5308 /* Release the segments */
5309 static void normalize_buffer(struct osst_buffer
*STbuffer
)
5311 int i
, order
, b_size
;
5313 for (i
=0; i
< STbuffer
->sg_segs
; i
++) {
5315 for (b_size
= PAGE_SIZE
, order
= 0;
5316 b_size
< STbuffer
->sg
[i
].length
;
5317 b_size
*= 2, order
++);
5319 __free_pages(STbuffer
->sg
[i
].page
, order
);
5320 STbuffer
->buffer_size
-= STbuffer
->sg
[i
].length
;
5323 if (debugging
&& STbuffer
->orig_sg_segs
< STbuffer
->sg_segs
)
5324 printk(OSST_DEB_MSG
"osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5325 STbuffer
->b_data
, STbuffer
->buffer_size
, STbuffer
->sg_segs
);
5327 STbuffer
->sg_segs
= STbuffer
->orig_sg_segs
= 0;
5331 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5332 negative error code. */
5333 static int append_to_buffer(const char __user
*ubp
, struct osst_buffer
*st_bp
, int do_count
)
5335 int i
, cnt
, res
, offset
;
5337 for (i
=0, offset
=st_bp
->buffer_bytes
;
5338 i
< st_bp
->sg_segs
&& offset
>= st_bp
->sg
[i
].length
; i
++)
5339 offset
-= st_bp
->sg
[i
].length
;
5340 if (i
== st_bp
->sg_segs
) { /* Should never happen */
5341 printk(KERN_WARNING
"osst :A: Append_to_buffer offset overflow.\n");
5344 for ( ; i
< st_bp
->sg_segs
&& do_count
> 0; i
++) {
5345 cnt
= st_bp
->sg
[i
].length
- offset
< do_count
?
5346 st_bp
->sg
[i
].length
- offset
: do_count
;
5347 res
= copy_from_user(page_address(st_bp
->sg
[i
].page
) + offset
, ubp
, cnt
);
5351 st_bp
->buffer_bytes
+= cnt
;
5355 if (do_count
) { /* Should never happen */
5356 printk(KERN_WARNING
"osst :A: Append_to_buffer overflow (left %d).\n",
5364 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5365 negative error code. */
5366 static int from_buffer(struct osst_buffer
*st_bp
, char __user
*ubp
, int do_count
)
5368 int i
, cnt
, res
, offset
;
5370 for (i
=0, offset
=st_bp
->read_pointer
;
5371 i
< st_bp
->sg_segs
&& offset
>= st_bp
->sg
[i
].length
; i
++)
5372 offset
-= st_bp
->sg
[i
].length
;
5373 if (i
== st_bp
->sg_segs
) { /* Should never happen */
5374 printk(KERN_WARNING
"osst :A: From_buffer offset overflow.\n");
5377 for ( ; i
< st_bp
->sg_segs
&& do_count
> 0; i
++) {
5378 cnt
= st_bp
->sg
[i
].length
- offset
< do_count
?
5379 st_bp
->sg
[i
].length
- offset
: do_count
;
5380 res
= copy_to_user(ubp
, page_address(st_bp
->sg
[i
].page
) + offset
, cnt
);
5384 st_bp
->buffer_bytes
-= cnt
;
5385 st_bp
->read_pointer
+= cnt
;
5389 if (do_count
) { /* Should never happen */
5390 printk(KERN_WARNING
"osst :A: From_buffer overflow (left %d).\n", do_count
);
5396 /* Sets the tail of the buffer after fill point to zero.
5397 Returns zero (success) or negative error code. */
5398 static int osst_zero_buffer_tail(struct osst_buffer
*st_bp
)
5400 int i
, offset
, do_count
, cnt
;
5402 for (i
= 0, offset
= st_bp
->buffer_bytes
;
5403 i
< st_bp
->sg_segs
&& offset
>= st_bp
->sg
[i
].length
; i
++)
5404 offset
-= st_bp
->sg
[i
].length
;
5405 if (i
== st_bp
->sg_segs
) { /* Should never happen */
5406 printk(KERN_WARNING
"osst :A: Zero_buffer offset overflow.\n");
5409 for (do_count
= OS_DATA_SIZE
- st_bp
->buffer_bytes
;
5410 i
< st_bp
->sg_segs
&& do_count
> 0; i
++) {
5411 cnt
= st_bp
->sg
[i
].length
- offset
< do_count
?
5412 st_bp
->sg
[i
].length
- offset
: do_count
;
5413 memset(page_address(st_bp
->sg
[i
].page
) + offset
, 0, cnt
);
5417 if (do_count
) { /* Should never happen */
5418 printk(KERN_WARNING
"osst :A: Zero_buffer overflow (left %d).\n", do_count
);
5424 /* Copy a osst 32K chunk of memory into the buffer.
5425 Returns zero (success) or negative error code. */
5426 static int osst_copy_to_buffer(struct osst_buffer
*st_bp
, unsigned char *ptr
)
5428 int i
, cnt
, do_count
= OS_DATA_SIZE
;
5430 for (i
= 0; i
< st_bp
->sg_segs
&& do_count
> 0; i
++) {
5431 cnt
= st_bp
->sg
[i
].length
< do_count
?
5432 st_bp
->sg
[i
].length
: do_count
;
5433 memcpy(page_address(st_bp
->sg
[i
].page
), ptr
, cnt
);
5437 if (do_count
|| i
!= st_bp
->sg_segs
-1) { /* Should never happen */
5438 printk(KERN_WARNING
"osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5445 /* Copy a osst 32K chunk of memory from the buffer.
5446 Returns zero (success) or negative error code. */
5447 static int osst_copy_from_buffer(struct osst_buffer
*st_bp
, unsigned char *ptr
)
5449 int i
, cnt
, do_count
= OS_DATA_SIZE
;
5451 for (i
= 0; i
< st_bp
->sg_segs
&& do_count
> 0; i
++) {
5452 cnt
= st_bp
->sg
[i
].length
< do_count
?
5453 st_bp
->sg
[i
].length
: do_count
;
5454 memcpy(ptr
, page_address(st_bp
->sg
[i
].page
), cnt
);
5458 if (do_count
|| i
!= st_bp
->sg_segs
-1) { /* Should never happen */
5459 printk(KERN_WARNING
"osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5467 /* Module housekeeping */
5469 static void validate_options (void)
5472 osst_max_dev
= max_dev
;
5473 if (write_threshold_kbs
> 0)
5474 osst_write_threshold
= write_threshold_kbs
* ST_KILOBYTE
;
5475 if (osst_write_threshold
> osst_buffer_size
)
5476 osst_write_threshold
= osst_buffer_size
;
5477 if (max_sg_segs
>= OSST_FIRST_SG
)
5478 osst_max_sg_segs
= max_sg_segs
;
5480 printk(OSST_DEB_MSG
"osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5481 osst_max_dev
, osst_write_threshold
, osst_max_sg_segs
);
5486 /* Set the boot options. Syntax: osst=xxx,yyy,...
5487 where xxx is write threshold in 1024 byte blocks,
5488 and yyy is number of s/g segments to use. */
5489 static int __init
osst_setup (char *str
)
5494 stp
= get_options(str
, ARRAY_SIZE(ints
), ints
);
5497 for (i
= 0; i
< ints
[0] && i
< ARRAY_SIZE(parms
); i
++)
5498 *parms
[i
].val
= ints
[i
+ 1];
5500 while (stp
!= NULL
) {
5501 for (i
= 0; i
< ARRAY_SIZE(parms
); i
++) {
5502 int len
= strlen(parms
[i
].name
);
5503 if (!strncmp(stp
, parms
[i
].name
, len
) &&
5504 (*(stp
+ len
) == ':' || *(stp
+ len
) == '=')) {
5506 simple_strtoul(stp
+ len
+ 1, NULL
, 0);
5510 if (i
>= ARRAY_SIZE(parms
))
5511 printk(KERN_INFO
"osst :I: Illegal parameter in '%s'\n",
5513 stp
= strchr(stp
, ',');
5522 __setup("osst=", osst_setup
);
5526 static const struct file_operations osst_fops
= {
5527 .owner
= THIS_MODULE
,
5529 .write
= osst_write
,
5530 .ioctl
= osst_ioctl
,
5531 #ifdef CONFIG_COMPAT
5532 .compat_ioctl
= osst_compat_ioctl
,
5534 .open
= os_scsi_tape_open
,
5535 .flush
= os_scsi_tape_flush
,
5536 .release
= os_scsi_tape_close
,
5539 static int osst_supports(struct scsi_device
* SDp
)
5541 struct osst_support_data
{
5545 char *driver_hint
; /* Name of the correct driver, NULL if unknown */
5548 static struct osst_support_data support_list
[] = {
5549 /* {"XXX", "Yy-", "", NULL}, example */
5553 struct osst_support_data
*rp
;
5555 /* We are willing to drive OnStream SC-x0 as well as the
5556 * * IDE, ParPort, FireWire, USB variants, if accessible by
5557 * * emulation layer (ide-scsi, usb-storage, ...) */
5559 for (rp
=&(support_list
[0]); rp
->vendor
!= NULL
; rp
++)
5560 if (!strncmp(rp
->vendor
, SDp
->vendor
, strlen(rp
->vendor
)) &&
5561 !strncmp(rp
->model
, SDp
->model
, strlen(rp
->model
)) &&
5562 !strncmp(rp
->rev
, SDp
->rev
, strlen(rp
->rev
)))
5568 * sysfs support for osst driver parameter information
5571 static ssize_t
osst_version_show(struct device_driver
*ddd
, char *buf
)
5573 return snprintf(buf
, PAGE_SIZE
, "%s\n", osst_version
);
5576 static DRIVER_ATTR(version
, S_IRUGO
, osst_version_show
, NULL
);
5578 static int osst_create_sysfs_files(struct device_driver
*sysfs
)
5580 return driver_create_file(sysfs
, &driver_attr_version
);
5583 static void osst_remove_sysfs_files(struct device_driver
*sysfs
)
5585 driver_remove_file(sysfs
, &driver_attr_version
);
5589 * sysfs support for accessing ADR header information
5592 static ssize_t
osst_adr_rev_show(struct class_device
*class_dev
, char *buf
)
5594 struct osst_tape
* STp
= (struct osst_tape
*) class_get_devdata (class_dev
);
5597 if (STp
&& STp
->header_ok
&& STp
->linux_media
)
5598 l
= snprintf(buf
, PAGE_SIZE
, "%d.%d\n", STp
->header_cache
->major_rev
, STp
->header_cache
->minor_rev
);
5602 CLASS_DEVICE_ATTR(ADR_rev
, S_IRUGO
, osst_adr_rev_show
, NULL
);
5604 static ssize_t
osst_linux_media_version_show(struct class_device
*class_dev
, char *buf
)
5606 struct osst_tape
* STp
= (struct osst_tape
*) class_get_devdata (class_dev
);
5609 if (STp
&& STp
->header_ok
&& STp
->linux_media
)
5610 l
= snprintf(buf
, PAGE_SIZE
, "LIN%d\n", STp
->linux_media_version
);
5614 CLASS_DEVICE_ATTR(media_version
, S_IRUGO
, osst_linux_media_version_show
, NULL
);
5616 static ssize_t
osst_capacity_show(struct class_device
*class_dev
, char *buf
)
5618 struct osst_tape
* STp
= (struct osst_tape
*) class_get_devdata (class_dev
);
5621 if (STp
&& STp
->header_ok
&& STp
->linux_media
)
5622 l
= snprintf(buf
, PAGE_SIZE
, "%d\n", STp
->capacity
);
5626 CLASS_DEVICE_ATTR(capacity
, S_IRUGO
, osst_capacity_show
, NULL
);
5628 static ssize_t
osst_first_data_ppos_show(struct class_device
*class_dev
, char *buf
)
5630 struct osst_tape
* STp
= (struct osst_tape
*) class_get_devdata (class_dev
);
5633 if (STp
&& STp
->header_ok
&& STp
->linux_media
)
5634 l
= snprintf(buf
, PAGE_SIZE
, "%d\n", STp
->first_data_ppos
);
5638 CLASS_DEVICE_ATTR(BOT_frame
, S_IRUGO
, osst_first_data_ppos_show
, NULL
);
5640 static ssize_t
osst_eod_frame_ppos_show(struct class_device
*class_dev
, char *buf
)
5642 struct osst_tape
* STp
= (struct osst_tape
*) class_get_devdata (class_dev
);
5645 if (STp
&& STp
->header_ok
&& STp
->linux_media
)
5646 l
= snprintf(buf
, PAGE_SIZE
, "%d\n", STp
->eod_frame_ppos
);
5650 CLASS_DEVICE_ATTR(EOD_frame
, S_IRUGO
, osst_eod_frame_ppos_show
, NULL
);
5652 static ssize_t
osst_filemark_cnt_show(struct class_device
*class_dev
, char *buf
)
5654 struct osst_tape
* STp
= (struct osst_tape
*) class_get_devdata (class_dev
);
5657 if (STp
&& STp
->header_ok
&& STp
->linux_media
)
5658 l
= snprintf(buf
, PAGE_SIZE
, "%d\n", STp
->filemark_cnt
);
5662 CLASS_DEVICE_ATTR(file_count
, S_IRUGO
, osst_filemark_cnt_show
, NULL
);
5664 static struct class *osst_sysfs_class
;
5666 static int osst_sysfs_init(void)
5668 osst_sysfs_class
= class_create(THIS_MODULE
, "onstream_tape");
5669 if (IS_ERR(osst_sysfs_class
)) {
5670 printk(KERN_ERR
"osst :W: Unable to register sysfs class\n");
5671 return PTR_ERR(osst_sysfs_class
);
5677 static void osst_sysfs_destroy(dev_t dev
)
5679 class_device_destroy(osst_sysfs_class
, dev
);
5682 static int osst_sysfs_add(dev_t dev
, struct device
*device
, struct osst_tape
* STp
, char * name
)
5684 struct class_device
*osst_class_member
;
5687 osst_class_member
= class_device_create(osst_sysfs_class
, NULL
, dev
,
5688 device
, "%s", name
);
5689 if (IS_ERR(osst_class_member
)) {
5690 printk(KERN_WARNING
"osst :W: Unable to add sysfs class member %s\n", name
);
5691 return PTR_ERR(osst_class_member
);
5694 class_set_devdata(osst_class_member
, STp
);
5695 err
= class_device_create_file(osst_class_member
,
5696 &class_device_attr_ADR_rev
);
5699 err
= class_device_create_file(osst_class_member
,
5700 &class_device_attr_media_version
);
5703 err
= class_device_create_file(osst_class_member
,
5704 &class_device_attr_capacity
);
5707 err
= class_device_create_file(osst_class_member
,
5708 &class_device_attr_BOT_frame
);
5711 err
= class_device_create_file(osst_class_member
,
5712 &class_device_attr_EOD_frame
);
5715 err
= class_device_create_file(osst_class_member
,
5716 &class_device_attr_file_count
);
5723 osst_sysfs_destroy(dev
);
5727 static void osst_sysfs_cleanup(void)
5729 class_destroy(osst_sysfs_class
);
5733 * osst startup / cleanup code
5736 static int osst_probe(struct device
*dev
)
5738 struct scsi_device
* SDp
= to_scsi_device(dev
);
5739 struct osst_tape
* tpnt
;
5740 struct st_modedef
* STm
;
5741 struct st_partstat
* STps
;
5742 struct osst_buffer
* buffer
;
5743 struct gendisk
* drive
;
5744 int i
, dev_num
, err
= -ENODEV
;
5746 if (SDp
->type
!= TYPE_TAPE
|| !osst_supports(SDp
))
5749 drive
= alloc_disk(1);
5751 printk(KERN_ERR
"osst :E: Out of memory. Device not attached.\n");
5755 /* if this is the first attach, build the infrastructure */
5756 write_lock(&os_scsi_tapes_lock
);
5757 if (os_scsi_tapes
== NULL
) {
5759 (struct osst_tape
**)kmalloc(osst_max_dev
* sizeof(struct osst_tape
*),
5761 if (os_scsi_tapes
== NULL
) {
5762 write_unlock(&os_scsi_tapes_lock
);
5763 printk(KERN_ERR
"osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5766 for (i
=0; i
< osst_max_dev
; ++i
) os_scsi_tapes
[i
] = NULL
;
5769 if (osst_nr_dev
>= osst_max_dev
) {
5770 write_unlock(&os_scsi_tapes_lock
);
5771 printk(KERN_ERR
"osst :E: Too many tape devices (max. %d).\n", osst_max_dev
);
5775 /* find a free minor number */
5776 for (i
=0; os_scsi_tapes
[i
] && i
<osst_max_dev
; i
++);
5777 if(i
>= osst_max_dev
) panic ("Scsi_devices corrupt (osst)");
5780 /* allocate a struct osst_tape for this device */
5781 tpnt
= kzalloc(sizeof(struct osst_tape
), GFP_ATOMIC
);
5783 write_unlock(&os_scsi_tapes_lock
);
5784 printk(KERN_ERR
"osst :E: Can't allocate device descriptor, device not attached.\n");
5788 /* allocate a buffer for this device */
5789 i
= SDp
->host
->sg_tablesize
;
5790 if (osst_max_sg_segs
< i
)
5791 i
= osst_max_sg_segs
;
5792 buffer
= new_tape_buffer(1, SDp
->host
->unchecked_isa_dma
, i
);
5793 if (buffer
== NULL
) {
5794 write_unlock(&os_scsi_tapes_lock
);
5795 printk(KERN_ERR
"osst :E: Unable to allocate a tape buffer, device not attached.\n");
5799 os_scsi_tapes
[dev_num
] = tpnt
;
5800 tpnt
->buffer
= buffer
;
5802 drive
->private_data
= &tpnt
->driver
;
5803 sprintf(drive
->disk_name
, "osst%d", dev_num
);
5804 tpnt
->driver
= &osst_template
;
5805 tpnt
->drive
= drive
;
5807 tpnt
->capacity
= 0xfffff;
5809 tpnt
->drv_buffer
= 1; /* Try buffering if no mode sense */
5810 tpnt
->restr_dma
= (SDp
->host
)->unchecked_isa_dma
;
5812 tpnt
->do_auto_lock
= OSST_AUTO_LOCK
;
5813 tpnt
->can_bsr
= OSST_IN_FILE_POS
;
5814 tpnt
->can_partitions
= 0;
5815 tpnt
->two_fm
= OSST_TWO_FM
;
5816 tpnt
->fast_mteom
= OSST_FAST_MTEOM
;
5817 tpnt
->scsi2_logical
= OSST_SCSI2LOGICAL
; /* FIXME */
5818 tpnt
->write_threshold
= osst_write_threshold
;
5819 tpnt
->default_drvbuffer
= 0xff; /* No forced buffering */
5820 tpnt
->partition
= 0;
5821 tpnt
->new_partition
= 0;
5822 tpnt
->nbr_partitions
= 0;
5823 tpnt
->min_block
= 512;
5824 tpnt
->max_block
= OS_DATA_SIZE
;
5825 tpnt
->timeout
= OSST_TIMEOUT
;
5826 tpnt
->long_timeout
= OSST_LONG_TIMEOUT
;
5828 /* Recognize OnStream tapes */
5829 /* We don't need to test for OnStream, as this has been done in detect () */
5830 tpnt
->os_fw_rev
= osst_parse_firmware_rev (SDp
->rev
);
5831 tpnt
->omit_blklims
= 1;
5833 tpnt
->poll
= (strncmp(SDp
->model
, "DI-", 3) == 0) ||
5834 (strncmp(SDp
->model
, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt
->os_fw_rev
,SDp
);
5835 tpnt
->frame_in_buffer
= 0;
5836 tpnt
->header_ok
= 0;
5837 tpnt
->linux_media
= 0;
5838 tpnt
->header_cache
= NULL
;
5840 for (i
=0; i
< ST_NBR_MODES
; i
++) {
5841 STm
= &(tpnt
->modes
[i
]);
5843 STm
->sysv
= OSST_SYSV
;
5844 STm
->defaults_for_writes
= 0;
5845 STm
->do_async_writes
= OSST_ASYNC_WRITES
;
5846 STm
->do_buffer_writes
= OSST_BUFFER_WRITES
;
5847 STm
->do_read_ahead
= OSST_READ_AHEAD
;
5848 STm
->default_compression
= ST_DONT_TOUCH
;
5849 STm
->default_blksize
= 512;
5850 STm
->default_density
= (-1); /* No forced density */
5853 for (i
=0; i
< ST_NBR_PARTITIONS
; i
++) {
5854 STps
= &(tpnt
->ps
[i
]);
5856 STps
->eof
= ST_NOEOF
;
5858 STps
->last_block_valid
= 0;
5859 STps
->drv_block
= (-1);
5860 STps
->drv_file
= (-1);
5863 tpnt
->current_mode
= 0;
5864 tpnt
->modes
[0].defined
= 1;
5865 tpnt
->modes
[2].defined
= 1;
5866 tpnt
->density_changed
= tpnt
->compression_changed
= tpnt
->blksize_changed
= 0;
5868 mutex_init(&tpnt
->lock
);
5870 write_unlock(&os_scsi_tapes_lock
);
5876 err
= osst_sysfs_add(MKDEV(OSST_MAJOR
, dev_num
), dev
, tpnt
, tape_name(tpnt
));
5878 goto out_free_buffer
;
5880 /* No-rewind entry */
5881 snprintf(name
, 8, "%s%s", "n", tape_name(tpnt
));
5882 err
= osst_sysfs_add(MKDEV(OSST_MAJOR
, dev_num
+ 128), dev
, tpnt
, name
);
5884 goto out_free_sysfs1
;
5887 sdev_printk(KERN_INFO
, SDp
,
5888 "osst :I: Attached OnStream %.5s tape as %s\n",
5889 SDp
->model
, tape_name(tpnt
));
5894 osst_sysfs_destroy(MKDEV(OSST_MAJOR
, dev_num
));
5902 static int osst_remove(struct device
*dev
)
5904 struct scsi_device
* SDp
= to_scsi_device(dev
);
5905 struct osst_tape
* tpnt
;
5908 if ((SDp
->type
!= TYPE_TAPE
) || (osst_nr_dev
<= 0))
5911 write_lock(&os_scsi_tapes_lock
);
5912 for(i
=0; i
< osst_max_dev
; i
++) {
5913 if((tpnt
= os_scsi_tapes
[i
]) && (tpnt
->device
== SDp
)) {
5914 osst_sysfs_destroy(MKDEV(OSST_MAJOR
, i
));
5915 osst_sysfs_destroy(MKDEV(OSST_MAJOR
, i
+128));
5916 tpnt
->device
= NULL
;
5917 put_disk(tpnt
->drive
);
5918 os_scsi_tapes
[i
] = NULL
;
5920 write_unlock(&os_scsi_tapes_lock
);
5921 vfree(tpnt
->header_cache
);
5923 normalize_buffer(tpnt
->buffer
);
5924 kfree(tpnt
->buffer
);
5930 write_unlock(&os_scsi_tapes_lock
);
5934 static int __init
init_osst(void)
5938 printk(KERN_INFO
"osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version
, cvsid
);
5942 err
= osst_sysfs_init();
5946 err
= register_chrdev(OSST_MAJOR
, "osst", &osst_fops
);
5948 printk(KERN_ERR
"osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR
);
5952 err
= scsi_register_driver(&osst_template
.gendrv
);
5954 goto err_out_chrdev
;
5956 err
= osst_create_sysfs_files(&osst_template
.gendrv
);
5958 goto err_out_scsidrv
;
5963 scsi_unregister_driver(&osst_template
.gendrv
);
5965 unregister_chrdev(OSST_MAJOR
, "osst");
5967 osst_sysfs_cleanup();
5971 static void __exit
exit_osst (void)
5974 struct osst_tape
* STp
;
5976 osst_remove_sysfs_files(&osst_template
.gendrv
);
5977 scsi_unregister_driver(&osst_template
.gendrv
);
5978 unregister_chrdev(OSST_MAJOR
, "osst");
5979 osst_sysfs_cleanup();
5981 if (os_scsi_tapes
) {
5982 for (i
=0; i
< osst_max_dev
; ++i
) {
5983 if (!(STp
= os_scsi_tapes
[i
])) continue;
5984 /* This is defensive, supposed to happen during detach */
5985 vfree(STp
->header_cache
);
5987 normalize_buffer(STp
->buffer
);
5990 put_disk(STp
->drive
);
5993 kfree(os_scsi_tapes
);
5995 printk(KERN_INFO
"osst :I: Unloaded.\n");
5998 module_init(init_osst
);
5999 module_exit(exit_osst
);