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";
30 #define OSST_FW_NEED_POLL_MIN 10601
31 #define OSST_FW_NEED_POLL_MAX 10704
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>
41 #include <linux/slab.h>
43 #include <linux/string.h>
44 #include <linux/errno.h>
47 #include <linux/fcntl.h>
55 #include <asm/uaccess.h>
65 #define OSST_DEB_MSG KERN_NOTICE
67 #include <scsi/scsi.h>
75 #define ST_KILOBYTE 1024
83 static int max_dev = 0;
84 static int write_threshold_kbs = 0;
85 static int max_sg_segs = 0;
95 MODULE_PARM_DESC(max_dev,
"Maximum number of OnStream Tape Drives to attach (4)");
98 MODULE_PARM_DESC(write_threshold_kbs,
"Asynchronous write threshold (KB; 32)");
101 MODULE_PARM_DESC(max_sg_segs,
"Maximum number of scatter/gather segments to use (9)");
103 static struct osst_dev_parm {
107 {
"max_dev", &max_dev },
108 {
"write_threshold_kbs", &write_threshold_kbs },
109 {
"max_sg_segs", &max_sg_segs }
114 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
115 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
119 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
120 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
124 static int debugging = 1;
131 #define MAX_RETRIES 0
133 #define NO_TAPE NOT_READY
135 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
136 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
137 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
139 #define OSST_TIMEOUT (200 * HZ)
140 #define OSST_LONG_TIMEOUT (1800 * HZ)
142 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
143 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
144 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
145 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
149 #define SET_DENS_AND_BLK 0x10001
155 static int osst_nr_dev;
160 static int modes_defined = 0;
162 static struct osst_buffer *new_tape_buffer(
int,
int,
int);
163 static int enlarge_buffer(
struct osst_buffer *,
int);
164 static void normalize_buffer(
struct osst_buffer *);
165 static int append_to_buffer(
const char __user *,
struct osst_buffer *,
int);
166 static int from_buffer(
struct osst_buffer *,
char __user *,
int);
167 static int osst_zero_buffer_tail(
struct osst_buffer *);
168 static int osst_copy_to_buffer(
struct osst_buffer *,
unsigned char *);
169 static int osst_copy_from_buffer(
struct osst_buffer *,
unsigned char *);
171 static int osst_probe(
struct device *);
172 static int osst_remove(
struct device *);
179 .remove = osst_remove,
184 unsigned int cmd_in,
unsigned long arg);
192 static int osst_write_error_recovery(
struct osst_tape * STp,
struct osst_request ** aSRpnt,
int pending);
194 static inline char *tape_name(
struct osst_tape *tape)
196 return tape->
drive->disk_name;
216 switch (sense[0] & 0x7f) {
221 s->
flags = sense[2] & 0xe0;
228 s->
flags = ucp ? (ucp[3] & 0xe0) : 0;
237 char *
name = tape_name(STp);
239 u8 * sense = SRpnt->
sense, scode;
248 cmdstatp = &STp->
buffer->cmdstat;
249 osst_analyze_sense(SRpnt, cmdstatp);
252 scode = STp->
buffer->cmdstat.sense_hdr.sense_key;
259 SRpnt->
cmd[0], SRpnt->
cmd[1], SRpnt->
cmd[2],
260 SRpnt->
cmd[3], SRpnt->
cmd[4], SRpnt->
cmd[5]);
262 name, scode, sense[12], sense[13]);
281 static int notyetprinted = 1;
284 "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n",
290 "%s:I: This warning may be caused by your scsi controller,\n", name);
292 "%s:I: it has been reported with some Buslogic cards.\n", name);
313 if ((sense[2] & 0xe0) == 0)
325 struct rq_map_data *mdata = &SRpnt->
stp->buffer->map_data;
327 STp->
buffer->cmdstat.midlevel_result = SRpnt->
result = req->errors;
329 STp->write_pending = 0;
353 static int osst_execute(
struct osst_request *SRpnt,
const unsigned char *
cmd,
355 int use_sg,
int timeout,
int retries)
359 struct rq_map_data *mdata = &SRpnt->
stp->buffer->map_data;
368 req->cmd_type = REQ_TYPE_BLOCK_PC;
382 pages[i] = sg_page(sg);
384 mdata->null_mapped = 1;
396 SRpnt->
bio = req->bio;
397 mdata->pages =
pages;
399 }
else if (bufflen) {
406 memset(req->cmd, 0, BLK_MAX_CDB);
407 memcpy(req->cmd, cmd, req->cmd_len);
408 req->sense = SRpnt->
sense;
410 req->timeout = timeout;
412 req->end_io_data = SRpnt;
425 unsigned char *cmd,
int bytes,
int direction,
int timeout,
int retries,
int do_wait)
428 unsigned short use_sg;
429 #ifdef OSST_INJECT_ERRORS
430 static int inject = 0;
431 static int repeat = 0;
436 if (!do_wait && ((STp->
buffer)->last_SRpnt)) {
447 SRpnt = osst_allocate_request();
463 (STp->
buffer)->last_SRpnt = SRpnt;
465 waiting = &STp->
wait;
466 init_completion(waiting);
469 use_sg = (bytes > STp->
buffer->sg[0].length) ? STp->
buffer->use_sg : 0;
471 bp = (
char *)&(STp->
buffer->sg[0]);
472 if (STp->
buffer->sg_segs < use_sg)
473 use_sg = STp->
buffer->sg_segs;
476 bp = (STp->
buffer)->b_data;
479 STp->
buffer->cmdstat.have_sense = 0;
480 STp->
buffer->syscall_result = 0;
482 if (osst_execute(SRpnt, cmd,
COMMAND_SIZE(cmd[0]), direction, bp, bytes,
483 use_sg, timeout, retries))
489 STp->
buffer->syscall_result = osst_chk_result(STp, SRpnt);
490 #ifdef OSST_INJECT_ERRORS
491 if (STp->
buffer->syscall_result == 0 &&
494 ( (++ inject % 83) == 29 ||
499 STp->
buffer->last_result_fatal = 1;
508 static void osst_write_behind_check(
struct osst_tape *STp)
515 if (STp->write_pending)
523 STp->
buffer->syscall_result = osst_chk_result(STp, STp->
buffer->last_SRpnt);
525 if (STp->
buffer->syscall_result)
526 STp->
buffer->syscall_result =
527 osst_write_error_recovery(STp, &(STp->
buffer->last_SRpnt), 1);
531 osst_release_request(STp->
buffer->last_SRpnt);
550 int logical_blk_num,
int blk_sz,
int blk_cnt)
556 if (STp->
raw)
return;
558 memset(aux, 0,
sizeof(*aux));
564 switch (frame_type) {
611 static int osst_verify_frame(
struct osst_tape * STp,
int frame_seq_number,
int quiet)
613 char * name = tape_name(STp);
620 if (STp->
buffer->syscall_result) {
621 for (i=0; i < STp->
buffer->sg_segs; i++)
623 0, STp->
buffer->sg[i].length);
629 if (STp->
buffer->syscall_result) {
718 STp->
buffer->buffer_bytes = blk_cnt * blk_sz;
719 STp->
buffer->read_pointer = 0;
723 if (STp->
block_size != blk_sz && blk_sz > 0) {
725 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
726 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?
'b':
'k',
748 unsigned timeout,
int initial_delay)
752 unsigned long startwait =
jiffies;
755 char * name = tape_name(STp);
760 if (initial_delay > 0)
768 if (!SRpnt)
return (-
EBUSY);
771 (( SRpnt->
sense[2] == 2 && SRpnt->
sense[12] == 4 &&
772 (SRpnt->
sense[13] == 1 || SRpnt->
sense[13] == 8) ) ||
773 ( SRpnt->
sense[2] == 6 && SRpnt->
sense[12] == 0x28 &&
774 SRpnt->
sense[13] == 0 ) )) {
793 if ( STp->
buffer->syscall_result &&
794 osst_write_error_recovery(STp, aSRpnt, 0) ) {
797 printk(
OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
812 static int osst_wait_for_medium(
struct osst_tape * STp,
struct osst_request ** aSRpnt,
unsigned timeout)
816 unsigned long startwait =
jiffies;
819 char * name = tape_name(STp);
829 if (!SRpnt)
return (-
EBUSY);
831 while ( STp->
buffer->syscall_result &&
time_before(jiffies, startwait + timeout*HZ) &&
832 SRpnt->
sense[2] == 2 && SRpnt->
sense[12] == 0x3a && SRpnt->
sense[13] == 0 ) {
851 if ( STp->
buffer->syscall_result && SRpnt->
sense[2] != 2 &&
852 SRpnt->
sense[12] != 4 && SRpnt->
sense[13] == 1) {
855 printk(
OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
871 osst_wait_ready(STp, aSRpnt, 15 * 60, 0);
872 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
873 if (retval)
return (retval);
875 return (osst_get_frame_position(STp, aSRpnt));
888 char * name = tape_name(STp);
890 printk(
OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
899 if (!SRpnt)
return (-
EBUSY);
900 if (STp->
buffer->syscall_result) {
901 if ((SRpnt->
sense[2] & 0x0f) == 2 && SRpnt->
sense[12] == 4) {
902 if (SRpnt->
sense[13] == 8) {
906 result = osst_write_error_recovery(STp, aSRpnt, 0);
908 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
914 #define OSST_POLL_PER_SEC 10
917 unsigned long startwait =
jiffies;
918 char * name = tape_name(STp);
920 char notyetprinted = 1;
923 printk(
KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
928 result = osst_get_frame_position(STp, aSRpnt);
930 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
932 if (result < 0)
break;
942 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
945 result, (
jiffies-startwait)/HZ,
946 (((
jiffies-startwait)%HZ)*10)/HZ);
970 static int osst_recover_wait_frame(
struct osst_tape * STp,
struct osst_request ** aSRpnt,
int writing)
974 unsigned long startwait =
jiffies;
976 char * name = tape_name(STp);
980 char * olddata = STp->
buffer->b_data;
981 int oldsize = STp->
buffer->buffer_size;
991 while (retval &&
time_before (jiffies, startwait + 5*60*HZ)) {
993 if (STp->
buffer->syscall_result && (SRpnt->
sense[2] & 0x0f) != 2) {
996 retval = osst_write_error_recovery(STp, aSRpnt, 0);
1001 STp->
buffer->b_data = mybuf; STp->
buffer->buffer_size = 24;
1008 retval = ( STp->
buffer->syscall_result || (STp->
buffer)->b_data[15] > 25 );
1009 STp->
buffer->b_data = olddata; STp->
buffer->buffer_size = oldsize;
1012 printk(
KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
1015 if (STp->
buffer->syscall_result)
1017 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
1018 (*aSRpnt)->sense[ 2] & 0x0f,
1019 (*aSRpnt)->sense[12],
1020 (*aSRpnt)->sense[13]);
1035 char * name = tape_name(STp);
1040 retval = osst_recover_wait_frame(STp, aSRpnt, 0);
1057 if ((STp->
buffer)->syscall_result) {
1084 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
1091 printk(
OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
1093 printk(
OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
1105 char * name = tape_name(STp);
1110 osst_flush_write_buffer(STp, aSRpnt);
1111 osst_flush_drive_buffer(STp, aSRpnt);
1129 if ((retval = STp->
buffer->syscall_result))
1137 int frame_seq_number,
int quiet)
1140 char * name = tape_name(STp);
1161 printk(
KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1162 name, frame_seq_number);
1177 name, frame_seq_number, cnt);
1179 if ( osst_initiate_read(STp, aSRpnt)
1180 || ( (!STp->
frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1183 position = osst_get_frame_position(STp, aSRpnt);
1184 if (position >= 0xbae && position < 0xbb8)
1198 osst_set_frame_position(STp, aSRpnt, position, 0);
1201 if (osst_verify_frame(STp, frame_seq_number, quiet))
1203 if (osst_verify_frame(STp, -1, quiet)) {
1207 "%s:W: Found logical frame %d instead of %d after fast open\n",
1208 name,
x, frame_seq_number);
1213 if (
x > frame_seq_number) {
1219 position = osst_get_frame_position(STp, aSRpnt)
1220 + frame_seq_number -
x - 1;
1227 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1228 name, x, frame_seq_number,
1231 osst_set_frame_position(STp, aSRpnt, position, 0);
1237 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1241 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1255 if (debugging || STps->
eof)
1257 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1265 static int osst_seek_logical_blk(
struct osst_tape * STp,
struct osst_request ** aSRpnt,
int logical_blk_num)
1268 char * name = tape_name(STp);
1270 int frame_seq_estimate, ppos_estimate, move;
1272 if (logical_blk_num < 0) logical_blk_num = 0;
1288 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1289 else ppos_estimate = frame_seq_estimate + 20;
1290 while (++retries < 10) {
1295 if (frame_seq_estimate < 0) {
1296 frame_seq_estimate = 0;
1299 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1300 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1302 if (logical_blk_num < STp->logical_blk_num ||
1314 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1318 frame_seq_estimate += move;
1319 ppos_estimate += move;
1323 STp->
buffer->buffer_bytes -= STp->
buffer->read_pointer;
1327 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1346 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1350 printk(
OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1360 printk(
KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1370 #define OSST_FRAME_SHIFT 6
1371 #define OSST_SECTOR_SHIFT 9
1372 #define OSST_SECTOR_MASK 0x03F
1378 char * name = tape_name(STp);
1381 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1397 sector = osst_get_frame_position(STp, aSRpnt);
1411 char * name = tape_name(STp);
1414 name, sector, frame, offset);
1420 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1422 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1423 if (
r < 0)
return r;
1425 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1426 if (
r < 0)
return r;
1428 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame))
return (-
EIO);
1438 STp->
buffer->buffer_bytes = STp->
buffer->read_pointer = 0;
1453 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1468 unsigned int frame,
unsigned int skip,
int pending)
1473 int flag, new_frame,
i;
1475 int blks_per_frame =
ntohs(STp->
buffer->aux->dat.dat_list[0].blk_cnt);
1476 int frame_seq_number =
ntohl(STp->
buffer->aux->frame_seq_num)
1477 - (nframes + pending - 1);
1478 int logical_blk_num =
ntohl(STp->
buffer->aux->logical_blk_num)
1479 - (nframes + pending - 1) * blks_per_frame;
1480 char * name = tape_name(STp);
1481 unsigned long startwait =
jiffies;
1483 int dbg = debugging;
1489 printk(
KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1490 name, nframes, pending?
" and one that was pending":
"");
1494 if (pending && debugging)
1496 name, frame_seq_number + nframes,
1497 logical_blk_num + nframes * blks_per_frame,
1498 p[0], p[1], p[2], p[3]);
1500 for (i = 0, p = buffer; i < nframes; i++, p +=
OS_DATA_SIZE) {
1505 cmd[7] = 32768 >> 8;
1506 cmd[8] = 32768 & 0xff;
1511 if ((STp->
buffer)->syscall_result || !SRpnt) {
1512 printk(
KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1517 osst_copy_from_buffer(STp->
buffer, p);
1521 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1525 osst_get_frame_position(STp, aSRpnt);
1533 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1540 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1546 name, new_frame+i, frame_seq_number+i);
1548 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1550 osst_get_frame_position(STp, aSRpnt);
1553 if (new_frame > frame + 1000) {
1554 printk(
KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1558 if ( i >= nframes + pending )
break;
1561 osst_copy_to_buffer(STp->
buffer, p);
1565 osst_init_aux(STp, STp->
buffer->aux->frame_type, frame_seq_number+i,
1566 logical_blk_num + i*blks_per_frame,
1567 ntohl(STp->
buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1576 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1577 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1578 p[0], p[1], p[2], p[3]);
1583 if (STp->
buffer->syscall_result)
1589 if ( i == nframes + pending ) {
1596 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0,
DMA_NONE,
1605 flag = STp->
buffer->syscall_result;
1606 while ( !flag &&
time_before(jiffies, startwait + 60*HZ) ) {
1614 if (SRpnt->
sense[2] == 2 && SRpnt->
sense[12] == 4 &&
1615 (SRpnt->
sense[13] == 1 || SRpnt->
sense[13] == 8)) {
1620 if (STp->
buffer->syscall_result)
1632 if ((SRpnt->
sense[ 2] & 0x0f) == 13 &&
1633 SRpnt->
sense[12] == 0 &&
1634 SRpnt->
sense[13] == 2) {
1635 printk(
KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1639 i = ((SRpnt->
sense[3] << 24) |
1640 (SRpnt->
sense[4] << 16) |
1641 (SRpnt->
sense[5] << 8) |
1642 SRpnt->
sense[6] ) - new_frame;
1647 osst_get_frame_position(STp, aSRpnt);
1649 printk(
OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1656 printk(
KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1660 osst_copy_to_buffer(STp->
buffer, p);
1666 unsigned int frame,
unsigned int skip,
int pending)
1670 char * name = tape_name(STp);
1672 int attempts = 1000 /
skip;
1674 unsigned long startwait =
jiffies;
1676 int dbg = debugging;
1679 while (attempts &&
time_before(jiffies, startwait + 60*HZ)) {
1686 expected = frame+skip+STp->
cur_frames+pending;
1691 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1696 if (osst_get_frame_position(STp, aSRpnt) < 0) {
1720 if (STp->
buffer->syscall_result) {
1721 if ((SRpnt->
sense[ 2] & 0x0f) == 13 &&
1722 SRpnt->
sense[12] == 0 &&
1723 SRpnt->
sense[13] == 2) {
1725 "%s:E: Volume overflow in write error recovery\n",
1757 printk(
KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1768 static int osst_write_error_recovery(
struct osst_tape * STp,
struct osst_request ** aSRpnt,
int pending)
1772 char * name = tape_name(STp);
1777 rw_state = STps->
rw;
1779 if ((SRpnt->
sense[ 2] & 0x0f) != 3
1780 || SRpnt->
sense[12] != 12
1781 || SRpnt->
sense[13] != 0) {
1783 printk(
OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1788 frame = (SRpnt->
sense[3] << 24) |
1789 (SRpnt->
sense[4] << 16) |
1790 (SRpnt->
sense[5] << 8) |
1792 skip = SRpnt->
sense[9];
1795 printk(
OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1797 osst_get_frame_position(STp, aSRpnt);
1807 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1808 name, STp->
cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1810 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1812 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1815 retval?
"" :
"Don't worry, ",
1816 retval?
" not ":
" ");
1819 printk(
KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1820 osst_set_frame_position(STp, aSRpnt, frame + STp->
cur_frames + pending, 0);
1825 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1829 osst_set_frame_position(STp, aSRpnt, frame + STp->
cur_frames + pending, 0);
1831 osst_get_frame_position(STp, aSRpnt);
1833 printk(
OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1843 STps->
rw = rw_state;
1847 static int osst_space_over_filemarks_backward(
struct osst_tape * STp,
struct osst_request ** aSRpnt,
1848 int mt_op,
int mt_count)
1850 char * name = tape_name(STp);
1852 int last_mark_ppos = -1;
1855 printk(
OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1857 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1859 printk(
OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1870 (cnt - mt_count) >= 0 &&
1883 ((cnt == -1 &&
ntohl(STp->
buffer->aux->last_mark_ppos) == -1) ||
1885 STp->
buffer->aux->last_mark_ppos))?
"match":
"error",
1886 mt_count, last_mark_ppos);
1888 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1889 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1890 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1893 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1899 name, last_mark_ppos);
1909 while (cnt != mt_count) {
1910 last_mark_ppos =
ntohl(STp->
buffer->aux->last_mark_ppos);
1911 if (last_mark_ppos == -1)
1916 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1918 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1920 printk(
OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1926 name, last_mark_ppos);
1934 STp->
buffer->buffer_bytes = 0;
1935 STp->
buffer->read_pointer = 0;
1946 static int osst_space_over_filemarks_forward_slow(
struct osst_tape * STp,
struct osst_request ** aSRpnt,
1947 int mt_op,
int mt_count)
1951 char * name = tape_name(STp);
1953 printk(
OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1955 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1957 printk(
OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1962 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1964 printk(
OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1983 if (cnt == mt_count)
1987 if (mt_op ==
MTFSF) {
1990 STp->
buffer->buffer_bytes = 0;
1991 STp->
buffer->read_pointer = 0;
2000 static int osst_space_over_filemarks_forward_fast(
struct osst_tape * STp,
struct osst_request ** aSRpnt,
2001 int mt_op,
int mt_count)
2003 char * name = tape_name(STp);
2005 next_mark_ppos = -1;
2008 printk(
OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
2010 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2012 printk(
OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
2026 ((cnt == -1 &&
ntohl(STp->
buffer->aux->last_mark_ppos) == -1) ||
2037 ((cnt == -1 &&
ntohl(STp->
buffer->aux->last_mark_ppos) == -1) ||
2039 STp->
buffer->aux->last_mark_ppos))?
"match":
"error",
2040 mt_count, next_mark_ppos);
2042 if (next_mark_ppos <= 10 || next_mark_ppos > STp->
eod_frame_ppos) {
2046 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2048 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2049 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2058 name, next_mark_ppos);
2061 if (
ntohl(STp->
buffer->aux->filemark_cnt) != cnt + mt_count) {
2063 name, cnt+mt_count, next_mark_ppos,
2086 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2089 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2092 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2103 if (osst_space_over_filemarks_backward(STp, aSRpnt,
MTBSF, 1) < 0)
2109 while (cnt != mt_count) {
2110 next_mark_ppos =
ntohl(STp->
buffer->aux->next_mark_ppos);
2115 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
2118 else printk(
OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
2120 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2122 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2131 name, next_mark_ppos);
2136 if (mt_op ==
MTFSF) {
2139 STp->
buffer->buffer_bytes = 0;
2140 STp->
buffer->read_pointer = 0;
2155 char * name = tape_name(STp);
2162 (STp->
buffer)->b_data[0] = cmd[4] - 1;
2163 (STp->
buffer)->b_data[1] = 0;
2164 (STp->
buffer)->b_data[2] = 0;
2165 (STp->
buffer)->b_data[3] = 0;
2167 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2168 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2169 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2172 printk(
OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2177 if ((STp->
buffer)->syscall_result)
2178 printk (
KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2189 char * name = tape_name(STp);
2192 if (STp->
raw)
return 0;
2200 result = osst_flush_write_buffer(STp, aSRpnt);
2201 result |= osst_flush_drive_buffer(STp, aSRpnt);
2215 char * name = tape_name(STp);
2218 if (STp->
raw)
return 0;
2228 result = osst_flush_write_buffer(STp, aSRpnt);
2229 result |= osst_flush_drive_buffer(STp, aSRpnt);
2236 char * name = tape_name(STp);
2241 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2242 osst_set_frame_position(STp, aSRpnt, where, 0);
2246 STp->
buffer->buffer_bytes = 6;
2248 if (osst_flush_write_buffer(STp, aSRpnt)) {
2256 return osst_flush_drive_buffer(STp, aSRpnt);
2259 static int __osst_write_header(
struct osst_tape * STp,
struct osst_request ** aSRpnt,
int where,
int count)
2261 char * name = tape_name(STp);
2267 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2268 osst_set_frame_position(STp, aSRpnt, where, 0);
2274 if (osst_flush_write_buffer(STp, aSRpnt)) {
2279 result = osst_flush_drive_buffer(STp, aSRpnt);
2281 printk(
OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?
"failed":
"done");
2290 char * name = tape_name(STp);
2295 if (STp->
raw)
return 0;
2299 printk(
KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2338 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2340 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2341 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2370 return osst_write_header(STp, aSRpnt, 1);
2375 char * name = tape_name(STp);
2379 int linux_media_version,
2385 if (ppos == 5 || ppos == 0xbae || STp->
buffer->syscall_result) {
2386 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2388 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2389 if (osst_initiate_read (STp, aSRpnt)) {
2394 if (osst_read_frame(STp, aSRpnt, 180)) {
2425 printk(
OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2430 if (update_frame_cntr < STp->update_frame_cntr) {
2441 header->
minor_rev > 4 )?
"Invalid" :
"Warning:",
2454 if (
memcmp(id_string,
"LIN", 3) == 0) {
2456 linux_media_version = id_string[3] -
'0';
2457 if (linux_media_version != 4)
2458 printk(
KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2459 name, linux_media_version);
2464 if (linux_media_version < STp->linux_media_version) {
2467 name, ppos, linux_media_version);
2474 name, ppos, linux_media_version);
2483 name, ppos, update_frame_cntr);
2487 printk(
KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2507 printk(
OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2509 printk(
OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2555 char * name = tape_name(STp);
2557 position = osst_get_frame_position(STp, aSRpnt);
2575 first = position==10?0xbae: 5;
2576 last = position==10?0xbb3:10;
2578 for (ppos = first; ppos < last; ppos++)
2579 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2582 first = position==10? 5:0xbae;
2583 last = position==10?10:0xbb3;
2585 for (ppos = first; ppos < last; ppos++)
2586 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2590 printk(
KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2592 osst_set_frame_position(STp, aSRpnt, 10, 0);
2595 if (position <= STp->first_data_ppos) {
2599 osst_set_frame_position(STp, aSRpnt, position, 0);
2611 int read_pointer = STp->
buffer->read_pointer;
2612 int prev_mark_ppos = -1;
2613 int actual_mark_ppos,
i,
n;
2615 char * name = tape_name(STp);
2617 printk(
OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2619 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2620 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2622 printk(
OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2631 prev_mark_ppos = frame_position - 1;
2633 frame_position - 1 :
ntohl(STp->
buffer->aux->last_mark_ppos);
2636 prev_mark_ppos != actual_mark_ppos ) {
2638 printk(
OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2641 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2645 if (halfway_frame) {
2647 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2648 STp->
buffer->buffer_bytes = read_pointer;
2664 static unsigned int osst_parse_firmware_rev (
const char *
str)
2666 if (str[1] ==
'.') {
2667 return (str[0]-
'0')*10000
2671 return (str[0]-
'0')*10000
2673 +(str[2]-
'0')*100 - 100
2684 char * name = tape_name(STp);
2690 int drive_buffer_size;
2701 printk(
KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2715 if (SRpnt ==
NULL) {
2722 if ((STp->
buffer)->syscall_result != 0) {
2723 printk (
KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2732 printk(
OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ?
"Yes" :
"No");
2734 printk(
OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ?
"Yes" :
"No");
2753 if ((STp->
buffer)->syscall_result != 0) {
2754 printk (
KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2764 osst_set_retries(STp, aSRpnt, 0);
2783 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2784 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 2] =
'L';
2785 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 3] =
'I';
2786 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 4] =
'N';
2787 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 5] =
'4';
2788 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2789 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2794 if ((STp->
buffer)->syscall_result != 0) {
2796 (
char *) ((STp->
buffer)->b_data + MODE_HEADER_LENGTH + 2));
2809 if ((STp->
buffer)->syscall_result != 0) {
2829 if ((STp->
buffer)->syscall_result != 0) {
2841 printk(
OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2855 char * name = tape_name(STp);
2860 name, forward ?
"forward" :
"backward");
2865 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt,
MTFSF, 1);
2869 result = osst_seek_logical_blk(STp, aSRpnt, STp->
logical_blk_num - 1);
2873 name, forward ?
"forward" :
"backward");
2886 char * name = tape_name(STp);
2891 char * olddata = STp->
buffer->b_data;
2892 int oldsize = STp->
buffer->buffer_size;
2899 STp->
buffer->b_data = mybuf; STp->
buffer->buffer_size = 24;
2903 STp->
buffer->b_data = olddata; STp->
buffer->buffer_size = oldsize;
2908 if (STp->
buffer->syscall_result)
2914 if (result == -
EIO) {
2915 unsigned char mysense[16];
2919 STp->
buffer->b_data = mybuf; STp->
buffer->buffer_size = 24;
2923 printk(
OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2924 name, mysense[2], mysense[12], mysense[13], STp->
buffer->syscall_result?
"":
"ok:",
2927 if (!STp->
buffer->syscall_result)
2933 + ((STp->
buffer)->b_data[5] << 16)
2934 + ((STp->
buffer)->b_data[6] << 8)
2935 + (STp->
buffer)->b_data[7];
2937 + ((STp->
buffer)->b_data[ 9] << 16)
2938 + ((STp->
buffer)->b_data[10] << 8)
2939 + (STp->
buffer)->b_data[11];
2945 ((STp->
buffer)->b_data[0]&0x80)?
" (BOP)":
2946 ((STp->
buffer)->b_data[0]&0x40)?
" (EOP)":
"",
2958 STp->
buffer->b_data = olddata; STp->
buffer->buffer_size = oldsize;
2965 static int osst_set_frame_position(
struct osst_tape *STp,
struct osst_request ** aSRpnt,
int ppos,
int skip)
2971 int pp = (ppos == 3000 && !
skip)? 0 : ppos;
2972 char * name = tape_name(STp);
2978 if (ppos < 0 || ppos > STp->
capacity) {
2980 pp = ppos = ppos < 0 ? 0 : (STp->
capacity - 1);
2992 scmd[3] = (pp >> 24);
2993 scmd[4] = (pp >> 16);
2994 scmd[5] = (pp >> 8);
3005 if ((STp->
buffer)->syscall_result != 0) {
3014 }
while ((pp != ppos) && (pp = ppos));
3023 static int osst_write_trailer(
struct osst_tape *STp,
struct osst_request ** aSRpnt,
int leave_at_EOT)
3030 result = osst_flush_drive_buffer(STp, aSRpnt);
3031 if (result < 0)
goto out;
3032 result = osst_write_filemark(STp, aSRpnt);
3033 if (result < 0)
goto out;
3039 result = osst_write_eod(STp, aSRpnt);
3040 osst_write_header(STp, aSRpnt, leave_at_EOT);
3052 int offset, transfer, blks = 0;
3057 char * name = tape_name(STp);
3059 if ((STp->
buffer)->writing) {
3060 if (SRpnt == (STp->
buffer)->last_SRpnt)
3063 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name);
3065 *aSRpnt = SRpnt =
NULL;
3069 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name);
3071 osst_write_behind_check(STp);
3072 if ((STp->
buffer)->syscall_result) {
3076 name, (STp->
buffer)->midlevel_result);
3085 if (STp->
dirty == 1) {
3090 offset = STp->
buffer->buffer_bytes;
3095 osst_zero_buffer_tail(STp->
buffer);
3099 result = osst_recover_wait_frame(STp, aSRpnt, 1);
3133 printk(
OSST_DEB_MSG "%s:D: Flushing %d bytes, Transferring %d bytes in %d lblocks.\n",
3134 name, offset, transfer, blks);
3137 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer,
DMA_TO_DEVICE,
3143 if ((STp->
buffer)->syscall_result != 0) {
3146 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3150 if ((SRpnt->
sense[0] & 0x70) == 0x70 &&
3151 (SRpnt->
sense[2] & 0x40) &&
3154 (STp->
buffer)->buffer_bytes = 0;
3158 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3168 (STp->
buffer)->buffer_bytes = 0;
3183 int backspace = 0, result = 0;
3185 char * name = tape_name(STp);
3201 return osst_flush_write_buffer(STp, aSRpnt);
3213 (STp->
buffer)->buffer_bytes = 0;
3214 (STp->
buffer)->read_pointer = 0;
3220 result = cross_eof(STp, aSRpnt, 0);
3229 if (!result && backspace > 0)
3230 result = osst_seek_logical_blk(STp, aSRpnt, STp->
logical_blk_num - backspace);
3248 char * name = tape_name(STp);
3255 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3259 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3263 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3269 if (osst_recover_wait_frame(STp, aSRpnt, 1))
3284 printk(
OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3292 STp->write_pending = 1;
3301 if (STp->
buffer->syscall_result != 0) {
3306 if ((SRpnt->
sense[0] & 0x70) == 0x70 &&
3307 (SRpnt->
sense[2] & 0x40)) {
3312 if (osst_write_error_recovery(STp, aSRpnt, 1))
3326 static int do_door_lock(
struct osst_tape * STp,
int do_lock)
3332 printk(
OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ?
"L" :
"Unl");
3345 static void reset_state(
struct osst_tape *STp)
3352 STps = &(STp->
ps[
i]);
3366 static ssize_t osst_write(
struct file * filp,
const char __user *
buf,
size_t count, loff_t *ppos)
3369 ssize_t i, do_count, blks, transfer;
3370 int write_threshold;
3371 int doing_write = 0;
3372 const char __user * b_point;
3377 char * name = tape_name(STp);
3433 printk(
KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3441 printk(
KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3454 printk(
OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3457 retval = osst_flush_buffer(STp, &SRpnt, 0);
3472 osst_reset_header(STp, &SRpnt);
3477 if ((STp->
fast_open && osst_verify_position(STp, &SRpnt)) ||
3487 "%s:D: Cannot write at indeterminate position.\n", name);
3498 "%s:W: Overwriting file %d with old write pass counter %d\n",
3501 "%s:W: may lead to stale data being accepted on reading back!\n",
3505 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3520 if ((STp->
buffer)->writing) {
3521 if (SRpnt)
printk(
KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3522 osst_write_behind_check(STp);
3523 if ((STp->
buffer)->syscall_result) {
3527 (STp->
buffer)->midlevel_result);
3553 write_threshold = 1;
3563 printk(
OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3568 while ((STp->
buffer)->buffer_bytes + count > write_threshold)
3572 (STp->
buffer)->buffer_bytes;
3573 if (do_count > count)
3576 i = append_to_buffer(b_point, STp->
buffer, do_count);
3585 i = osst_write_frame(STp, &SRpnt, 1);
3588 transfer = STp->
buffer->writing;
3589 if (transfer <= do_count) {
3590 *ppos += do_count - transfer;
3591 count -= do_count - transfer;
3600 name, (
int) transfer);
3617 if (SRpnt !=
NULL) {
3618 osst_release_request(SRpnt);
3621 STp->
buffer->buffer_bytes = 0;
3624 retval = total -
count;
3629 b_point += do_count;
3634 STp->
buffer->buffer_bytes = 0;
3640 i = append_to_buffer(b_point, STp->
buffer, count);
3654 if (doing_write && (STp->
buffer)->syscall_result != 0) {
3655 retval = (STp->
buffer)->syscall_result;
3661 (STp->
buffer)->writing = ((STp->
buffer)->buffer_bytes /
3664 (STp->
buffer)->buffer_bytes);
3666 i = osst_write_frame(STp, &SRpnt, 0);
3673 STps->
at_sm &= (total == 0);
3680 if (SRpnt !=
NULL) osst_release_request(SRpnt);
3689 static ssize_t osst_read(
struct file * filp,
char __user * buf,
size_t count, loff_t *ppos)
3698 char * name = tape_name(STp);
3745 retval = osst_flush_buffer(STp, &SRpnt, 0);
3754 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3761 STps->
eof, (STp->
buffer)->buffer_bytes);
3763 if ((STp->
buffer)->buffer_bytes == 0 &&
3785 for (total = 0, special = 0; total < count - STp->
block_size + 1 && !special; ) {
3788 if ((STp->
buffer)->buffer_bytes == 0) {
3800 if ((STp->
buffer)->buffer_bytes > 0) {
3804 STps->
eof, (STp->
buffer)->buffer_bytes, (
int) (count - total));
3807 transfer = (((STp->
buffer)->buffer_bytes < count - total ?
3808 (STp->
buffer)->buffer_bytes : count - total)/
3811 if (transfer == 0) {
3813 "%s:W: Nothing can be transferred, requested %Zd, tape block size (%d%c).\n",
3819 i = from_buffer(STp->
buffer, buf, transfer);
3831 if ((STp->
buffer)->buffer_bytes == 0) {
3865 if (SRpnt !=
NULL) osst_release_request(SRpnt);
3877 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3881 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3884 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3888 "%s:I: sysv: %d\n", name, STm->
sysv);
3891 "%s:D: debugging: %d\n",
3902 char * name = tape_name(STp);
3933 osst_log_options(STp, STm, name);
3966 osst_log_options(STp, STm, name);
3970 if (value < 1 || value > osst_buffer_size) {
3980 value = (options & ~MT_ST_OPTIONS);
3981 if (value == ~MT_ST_OPTIONS) {
3997 value = (options & ~MT_ST_OPTIONS);
3999 STp->
long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
4001 (value & ~MT_ST_SET_LONG_TIMEOUT));
4005 printk(
KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
4054 unsigned int cmd_in,
unsigned long arg)
4058 int i, ioctl_result;
4063 int fileno, blkno,
at_sm, frame_seq_numbr, logical_blk_num;
4065 char * name = tape_name(STp);
4077 at_sm = STps->
at_sm;
4089 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
4091 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
4095 at_sm &= (arg == 0);
4103 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
4107 at_sm &= (arg == 0);
4115 name, arg, cmd_in==
MTFSR?
"forward":
"backward", logical_blk_num);
4117 if (cmd_in ==
MTFSR) {
4118 logical_blk_num +=
arg;
4119 if (blkno >= 0) blkno +=
arg;
4122 logical_blk_num -=
arg;
4123 if (blkno >= 0) blkno -=
arg;
4125 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
4128 at_sm &= (arg == 0);
4134 cmd[2] = (arg >> 16);
4135 cmd[3] = (arg >> 8);
4140 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4143 blkno = fileno = (-1);
4151 cmd[2] = (ltmp >> 16);
4152 cmd[3] = (ltmp >> 8);
4158 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4164 blkno = fileno = (-1);
4171 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4178 for (i=0; i<
arg; i++)
4179 ioctl_result |= osst_write_filemark(STp, &SRpnt);
4180 if (fileno >= 0) fileno +=
arg;
4181 if (blkno >= 0) blkno = 0;
4190 if (cmd_in ==
MTWSM)
4192 cmd[2] = (arg >> 16);
4193 cmd[3] = (arg >> 8);
4199 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4204 at_sm = (cmd_in ==
MTWSM);
4241 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4255 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->
eod_frame_ppos) < 0) ||
4256 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4257 ioctl_result = -
EIO;
4264 ioctl_result = -
EIO;
4267 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->
eod_frame_ppos, 0);
4275 ioctl_result = osst_reset_header(STp, &SRpnt);
4276 i = osst_write_eod(STp, &SRpnt);
4277 if (i < ioctl_result) ioctl_result =
i;
4278 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->
eod_frame_ppos);
4279 if (i < ioctl_result) ioctl_result =
i;
4280 fileno = blkno = at_sm = 0 ;
4290 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4296 ((STp->
buffer)->buffer_bytes == 0) &&
4315 if (STp->
dirty || (STp->
buffer)->buffer_bytes != 0)
4318 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4319 (arg & MT_ST_BLKSIZE_MASK) != STp->
block_size ) {
4321 name, (
int)(arg & MT_ST_BLKSIZE_MASK),
4322 (
OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?
"":
" now");
4331 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout,
MAX_RETRIES, 1);
4333 ioctl_result = (STp->
buffer)->syscall_result;
4339 return ioctl_result;
4342 if (!ioctl_result) {
4353 if (!ioctl_result) {
4367 if (cmd_in ==
MTEOM)
4370 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->
logical_blk_num-1);
4375 STp->
buffer->read_pointer = 0;
4377 else if (cmd_in ==
MTFSF)
4384 else if (cmd_in ==
MTLOAD) {
4387 STp->
ps[
i].last_block_valid = 0;
4392 if (cmd_in ==
MTREW) {
4393 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->
first_data_ppos);
4394 if (ioctl_result > 0)
4398 }
else if (cmd_in ==
MTBSF || cmd_in ==
MTBSFM ) {
4399 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->
first_data_ppos) < 0)
4405 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->
eod_frame_ppos) < 0)
4416 }
else if (cmd_in ==
MTERASE) {
4419 if (SRpnt->
sense[2] & 0x40) {
4429 if (cmd_in ==
MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4434 return ioctl_result;
4439 static int __os_scsi_tape_open(
struct inode *
inode,
struct file * filp)
4441 unsigned short flags;
4442 int i, b_size, new_session = 0, retval = 0;
4460 if (dev >= osst_max_dev || os_scsi_tapes ==
NULL ||
4461 (STp = os_scsi_tapes[dev]) ==
NULL || !STp->
device) {
4466 name = tape_name(STp);
4511 printk(
KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4516 for (i = 0, b_size = 0;
4518 b_size += STp->
buffer->sg[i++].length);
4532 STp->
buffer->writing = 0;
4533 STp->
buffer->syscall_result = 0;
4536 STps = &(STp->
ps[
i]);
4541 STp->nbr_waits = STp->nbr_finished = 0;
4549 retval = (STp->
buffer)->syscall_result;
4552 if ((SRpnt->
sense[0] & 0x70) == 0x70 &&
4554 SRpnt->
sense[12] == 4 ) {
4562 if (SRpnt->
sense[13] == 2) {
4567 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0,
DMA_NONE,
4570 osst_wait_ready(STp, &SRpnt, (SRpnt->
sense[13]==1?15:3) * 60, 0);
4572 if ((SRpnt->
sense[0] & 0x70) == 0x70 &&
4579 for (i=0; i < 10; i++) {
4584 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0,
DMA_NONE,
4586 if ((SRpnt->
sense[0] & 0x70) != 0x70 ||
4596 STps = &(STp->
ps[
i]);
4623 if (STp->
buffer->syscall_result ||
4624 STp->
buffer->b_data[MODE_HEADER_LENGTH + 2] !=
'L' ||
4625 STp->
buffer->b_data[MODE_HEADER_LENGTH + 3] !=
'I' ||
4626 STp->
buffer->b_data[MODE_HEADER_LENGTH + 4] !=
'N' ||
4627 STp->
buffer->b_data[MODE_HEADER_LENGTH + 5] !=
'4' ) {
4630 STp->
buffer->b_data[MODE_HEADER_LENGTH + 2],
4631 STp->
buffer->b_data[MODE_HEADER_LENGTH + 3],
4632 STp->
buffer->b_data[MODE_HEADER_LENGTH + 4],
4633 STp->
buffer->b_data[MODE_HEADER_LENGTH + 5]);
4638 if (STp->
header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4640 if (do_door_lock(STp, 1))
4648 STp->
buffer->buffer_bytes = STp->
buffer->read_pointer = 0;
4652 osst_release_request(SRpnt);
4664 if ((STp->
buffer)->syscall_result != 0 &&
4665 (SRpnt->
sense[2] != 2 || SRpnt->
sense[12] != 0x3A) ) {
4672 (STp->
buffer)->b_data[0] = cmd[4] - 1;
4673 (STp->
buffer)->b_data[1] = 0;
4674 (STp->
buffer)->b_data[2] = 0;
4675 (STp->
buffer)->b_data[3] = 0;
4676 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4677 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4678 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4679 (STp->
buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4688 for (i=0; i < 10; i++) {
4693 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0,
DMA_NONE,
4695 if ((SRpnt->
sense[0] & 0x70) != 0x70 ||
4707 STps = &(STp->
ps[
j]);
4720 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0))
4721 printk(
KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4723 if ((STp->
buffer)->syscall_result != 0) {
4725 (SRpnt->
sense[0] & 0x70) == 0x70 &&
4727 SRpnt->
sense[12] == 0x3a) {
4731 osst_release_request(SRpnt);
4736 STp->
ps[0].drv_file = STp->
ps[0].drv_block = (-1);
4742 osst_configure_onstream(STp, &SRpnt);
4747 STp->
buffer->buffer_bytes =
4748 STp->
buffer->read_pointer =
4753 printk(
OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4755 (STp->
buffer)->buffer_blocks);
4783 if (do_door_lock(STp, 1))
4789 osst_analyze_headers(STp, &SRpnt);
4791 osst_release_request(SRpnt);
4798 osst_release_request(SRpnt);
4799 normalize_buffer(STp->
buffer);
4808 static int os_scsi_tape_open(
struct inode * inode,
struct file * filp)
4813 ret = __os_scsi_tape_open(inode, filp);
4823 int result = 0, result2;
4828 char * name = tape_name(STp);
4835 result = osst_flush_write_buffer(STp, &SRpnt);
4836 if (result != 0 && result != (-
ENOSPC))
4844 name, (
long)(filp->
f_pos));
4846 name, STp->nbr_waits, STp->nbr_finished);
4849 result = osst_write_trailer(STp, &SRpnt, !(STp->
rew_at_close));
4860 result = osst_flush_buffer(STp, &SRpnt, 0);
4862 result = cross_eof(STp, &SRpnt, 0);
4874 !(result = cross_eof(STp, &SRpnt, 1))) ||
4885 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->
first_data_ppos);
4887 if (result == 0 && result2 < 0)
4890 if (SRpnt) osst_release_request(SRpnt);
4914 static int os_scsi_tape_close(
struct inode * inode,
struct file * filp)
4920 do_door_lock(STp, 0);
4925 normalize_buffer(STp->
buffer);
4937 static long osst_ioctl(
struct file *
file,
4938 unsigned int cmd_in,
unsigned long arg)
4940 int i, cmd_nr, cmd_type,
blk, retval = 0;
4945 char * name = tape_name(STp);
4955 if (debugging && !STp->
in_use) {
4979 cmd_type, cmd_nr, STp->
raw?
"raw":
"normal");
5015 else if (mtc.mt_op ==
MTBSF || mtc.mt_op ==
MTBSFM) {
5022 if (mtc.mt_op ==
MTSEEK) {
5034 i = osst_flush_buffer(STp, &SRpnt, i);
5046 if(mtc.mt_op !=
MTREW &&
5051 mtc.mt_op !=
MTEOM) {
5057 STp->
device->was_reset = 0;
5073 printk(
KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
5081 i = osst_write_trailer(STp, &SRpnt,
5084 printk(
KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
5097 do_door_lock(STp, 0);
5100 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
5101 retval = osst_set_options(STp, mtc.mt_count);
5120 if ((i = osst_int_ioctl(STp, &SRpnt,
MTREW, 0)) < 0
5127 STp->
ps[
i].at_sm = 0;
5128 STp->
ps[
i].last_block_valid = 0;
5137 if (mtc.mt_op ==
MTSEEK) {
5139 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
5141 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
5149 retval = do_door_lock(STp, (mtc.mt_op ==
MTLOCK));
5154 cross_eof(STp, &SRpnt, 0);
5161 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5170 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5176 struct mtget mt_status;
5185 mt_status.mt_dsreg =
5189 mt_status.mt_fileno = STps->
drv_file;
5194 mt_status.mt_blkno -= ((STp->
buffer)->buffer_bytes +
5198 mt_status.mt_gstat = 0;
5201 if (mt_status.mt_blkno == 0) {
5202 if (mt_status.mt_fileno == 0)
5203 mt_status.mt_gstat |=
GMT_BOT(0xffffffff);
5205 mt_status.mt_gstat |=
GMT_EOF(0xffffffff);
5209 mt_status.mt_gstat |=
GMT_EOT(0xffffffff);
5211 mt_status.mt_gstat |=
GMT_EOD(0xffffffff);
5213 mt_status.mt_gstat |=
GMT_D_800(0xffffffff);
5215 mt_status.mt_gstat |=
GMT_D_1600(0xffffffff);
5217 mt_status.mt_gstat |=
GMT_D_6250(0xffffffff);
5219 mt_status.mt_gstat |=
GMT_ONLINE(0xffffffff);
5223 mt_status.mt_gstat |=
GMT_SM(0xffffffff);
5240 struct mtpos mt_pos;
5247 blk = osst_get_frame_position(STp, &SRpnt);
5249 blk = osst_get_sector(STp, &SRpnt);
5254 mt_pos.mt_blkno =
blk;
5260 if (SRpnt) osst_release_request(SRpnt);
5269 if (SRpnt) osst_release_request(SRpnt);
5277 #ifdef CONFIG_COMPAT
5278 static long osst_compat_ioctl(
struct file * file,
unsigned int cmd_in,
unsigned long arg)
5283 if (sdev->
host->hostt->compat_ioctl) {
5285 ret = sdev->
host->hostt->compat_ioctl(sdev, cmd_in, (
void __user *)arg);
5297 static struct osst_buffer * new_tape_buffer(
int from_initialization,
int need_dma,
int max_sg )
5303 if (from_initialization)
5309 tb = kzalloc(i, priority);
5323 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5324 i, max_sg, need_dma);
5330 static int enlarge_buffer(
struct osst_buffer *STbuffer,
int need_dma)
5332 int segs, nbr, max_segs, b_size,
order, got;
5340 normalize_buffer(STbuffer);
5343 nbr = max_segs = STbuffer->
use_sg;
5356 STbuffer->
sg[0].offset = 0;
5358 sg_set_page(&STbuffer->
sg[0], page, b_size, 0);
5363 if (sg_page(&STbuffer->
sg[0]) ==
NULL) {
5368 for (segs=STbuffer->
sg_segs=1, got=b_size;
5371 STbuffer->
sg[segs].offset = 0;
5378 normalize_buffer(STbuffer);
5382 got += STbuffer->
sg[segs].length;
5389 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5392 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5403 static void normalize_buffer(
struct osst_buffer *STbuffer)
5407 for (i=0; i < STbuffer->
sg_segs; i++) {
5410 b_size < STbuffer->
sg[
i].length;
5411 b_size *= 2, order++);
5427 static int append_to_buffer(
const char __user *ubp,
struct osst_buffer *st_bp,
int do_count)
5432 i < st_bp->sg_segs && offset >= st_bp->
sg[i].length; i++)
5433 offset -= st_bp->
sg[
i].length;
5438 for ( ; i < st_bp->
sg_segs && do_count > 0; i++) {
5439 cnt = st_bp->
sg[
i].length - offset < do_count ?
5440 st_bp->
sg[
i].length - offset : do_count;
5460 static int from_buffer(
struct osst_buffer *st_bp,
char __user *ubp,
int do_count)
5465 i < st_bp->sg_segs && offset >= st_bp->
sg[i].length; i++)
5466 offset -= st_bp->
sg[
i].length;
5471 for ( ; i < st_bp->
sg_segs && do_count > 0; i++) {
5472 cnt = st_bp->
sg[
i].length - offset < do_count ?
5473 st_bp->
sg[
i].length - offset : do_count;
5492 static int osst_zero_buffer_tail(
struct osst_buffer *st_bp)
5497 i < st_bp->sg_segs && offset >= st_bp->
sg[i].length; i++)
5498 offset -= st_bp->
sg[
i].length;
5504 i < st_bp->sg_segs && do_count > 0; i++) {
5505 cnt = st_bp->
sg[
i].length - offset < do_count ?
5506 st_bp->
sg[
i].length - offset : do_count ;
5520 static int osst_copy_to_buffer(
struct osst_buffer *st_bp,
unsigned char *
ptr)
5524 for (i = 0; i < st_bp->
sg_segs && do_count > 0; i++) {
5525 cnt = st_bp->
sg[
i].length < do_count ?
5526 st_bp->
sg[
i].length : do_count ;
5531 if (do_count || i != st_bp->
sg_segs-1) {
5541 static int osst_copy_from_buffer(
struct osst_buffer *st_bp,
unsigned char *ptr)
5545 for (i = 0; i < st_bp->
sg_segs && do_count > 0; i++) {
5546 cnt = st_bp->
sg[
i].length < do_count ?
5547 st_bp->
sg[
i].length : do_count ;
5552 if (do_count || i != st_bp->
sg_segs-1) {
5563 static void validate_options (
void)
5566 osst_max_dev = max_dev;
5567 if (write_threshold_kbs > 0)
5568 osst_write_threshold = write_threshold_kbs *
ST_KILOBYTE;
5569 if (osst_write_threshold > osst_buffer_size)
5570 osst_write_threshold = osst_buffer_size;
5572 osst_max_sg_segs = max_sg_segs;
5575 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5583 static int __init osst_setup (
char *str)
5594 while (stp !=
NULL) {
5598 (*(stp + len) ==
':' || *(stp + len) ==
'=')) {
5623 .write = osst_write,
5624 .unlocked_ioctl = osst_ioctl,
5625 #ifdef CONFIG_COMPAT
5626 .compat_ioctl = osst_compat_ioctl,
5628 .open = os_scsi_tape_open,
5629 .flush = os_scsi_tape_flush,
5630 .release = os_scsi_tape_close,
5634 static int osst_supports(
struct scsi_device * SDp)
5636 struct osst_support_data {
5643 static struct osst_support_data support_list[] = {
5648 struct osst_support_data *
rp;
5654 for (rp=&(support_list[0]); rp->vendor !=
NULL; rp++)
5673 static int osst_create_sysfs_files(
struct device_driver *sysfs)
5678 static void osst_remove_sysfs_files(
struct device_driver *sysfs)
5700 static ssize_t osst_linux_media_version_show(
struct device *dev,
5727 static ssize_t osst_first_data_ppos_show(
struct device *dev,
5768 static struct class *osst_sysfs_class;
5770 static int osst_sysfs_init(
void)
5773 if (IS_ERR(osst_sysfs_class)) {
5775 return PTR_ERR(osst_sysfs_class);
5781 static void osst_sysfs_destroy(
dev_t dev)
5788 struct device *osst_member;
5791 osst_member =
device_create(osst_sysfs_class, device, dev, STp,
5793 if (IS_ERR(osst_member)) {
5795 return PTR_ERR(osst_member);
5820 osst_sysfs_destroy(dev);
5824 static void osst_sysfs_cleanup(
void)
5833 static int osst_probe(
struct device *dev)
5840 struct gendisk * drive;
5841 int i, dev_num, err = -
ENODEV;
5848 printk(
KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5854 if (os_scsi_tapes ==
NULL) {
5856 if (os_scsi_tapes ==
NULL) {
5858 printk(
KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5861 for (i=0; i < osst_max_dev; ++
i) os_scsi_tapes[i] =
NULL;
5864 if (osst_nr_dev >= osst_max_dev) {
5866 printk(
KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5871 for (i = 0; i < osst_max_dev && os_scsi_tapes[
i]; i++)
5873 if(i >= osst_max_dev)
panic (
"Scsi_devices corrupt (osst)");
5880 printk(
KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5885 i = SDp->
host->sg_tablesize;
5886 if (osst_max_sg_segs < i)
5887 i = osst_max_sg_segs;
5888 buffer = new_tape_buffer(1, SDp->
host->unchecked_isa_dma, i);
5889 if (buffer ==
NULL) {
5891 printk(
KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5895 os_scsi_tapes[dev_num] = tpnt;
5898 drive->private_data = &tpnt->
driver;
5899 sprintf(drive->disk_name,
"osst%d", dev_num);
5900 tpnt->
driver = &osst_template;
5901 tpnt->
drive = drive;
5950 STps = &(tpnt->
ps[
i]);
5960 tpnt->
modes[0].defined = 1;
5961 tpnt->
modes[2].defined = 1;
5972 err = osst_sysfs_add(
MKDEV(
OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5974 goto out_free_buffer;
5977 snprintf(name, 8,
"%s%s",
"n", tape_name(tpnt));
5978 err = osst_sysfs_add(
MKDEV(
OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5980 goto out_free_sysfs1;
5984 "osst :I: Attached OnStream %.5s tape as %s\n",
5985 SDp->
model, tape_name(tpnt));
5998 static int osst_remove(
struct device *dev)
6008 for(i=0; i < osst_max_dev; i++) {
6009 if((tpnt = os_scsi_tapes[i]) && (tpnt->
device == SDp)) {
6014 os_scsi_tapes[
i] =
NULL;
6019 normalize_buffer(tpnt->
buffer);
6030 static int __init init_osst(
void)
6034 printk(
KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
6038 err = osst_sysfs_init();
6042 err = register_chrdev(
OSST_MAJOR,
"osst", &osst_fops);
6050 goto err_out_chrdev;
6052 err = osst_create_sysfs_files(&osst_template.
gendrv);
6054 goto err_out_scsidrv;
6063 osst_sysfs_cleanup();
6067 static void __exit exit_osst (
void)
6072 osst_remove_sysfs_files(&osst_template.
gendrv);
6075 osst_sysfs_cleanup();
6077 if (os_scsi_tapes) {
6078 for (i=0; i < osst_max_dev; ++
i) {
6079 if (!(STp = os_scsi_tapes[i]))
continue;
6083 normalize_buffer(STp->
buffer);
6089 kfree(os_scsi_tapes);