Commit 6e2037b0fd4d4ad9be941a3520d21945bc031a20

Authored by Andrew Morton
Committed by James Bottomley
1 parent a061f57d66

[SCSI] osst: fix warning

drivers/scsi/osst.c: In function '__os_scsi_tape_open':
drivers/scsi/osst.c:4705: warning: ISO C90 forbids mixed declarations and code

Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: James Bottomley <jbottomley@parallels.com>

Showing 1 changed file with 2 additions and 1 deletions Inline Diff

1 /* 1 /*
2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying 2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
3 file Documentation/scsi/st.txt for more information. 3 file Documentation/scsi/st.txt for more information.
4 4
5 History: 5 History:
6 6
7 OnStream SCSI Tape support (osst) cloned from st.c by 7 OnStream SCSI Tape support (osst) cloned from st.c by
8 Willem Riede (osst@riede.org) Feb 2000 8 Willem Riede (osst@riede.org) Feb 2000
9 Fixes ... Kurt Garloff <garloff@suse.de> Mar 2000 9 Fixes ... Kurt Garloff <garloff@suse.de> Mar 2000
10 10
11 Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara. 11 Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
12 Contribution and ideas from several people including (in alphabetical 12 Contribution and ideas from several people including (in alphabetical
13 order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer, 13 order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
14 Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale. 14 Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
15 15
16 Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede 16 Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede
17 email osst@riede.org 17 email osst@riede.org
18 18
19 $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $ 19 $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
20 20
21 Microscopic alterations - Rik Ling, 2000/12/21 21 Microscopic alterations - Rik Ling, 2000/12/21
22 Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara 22 Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
23 Some small formal changes - aeb, 950809 23 Some small formal changes - aeb, 950809
24 */ 24 */
25 25
26 static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $"; 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"; 27 static const char * osst_version = "0.99.4";
28 28
29 /* The "failure to reconnect" firmware bug */ 29 /* The "failure to reconnect" firmware bug */
30 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/ 30 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
31 #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/ 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) 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)
33 33
34 #include <linux/module.h> 34 #include <linux/module.h>
35 35
36 #include <linux/fs.h> 36 #include <linux/fs.h>
37 #include <linux/kernel.h> 37 #include <linux/kernel.h>
38 #include <linux/sched.h> 38 #include <linux/sched.h>
39 #include <linux/proc_fs.h> 39 #include <linux/proc_fs.h>
40 #include <linux/mm.h> 40 #include <linux/mm.h>
41 #include <linux/slab.h> 41 #include <linux/slab.h>
42 #include <linux/init.h> 42 #include <linux/init.h>
43 #include <linux/string.h> 43 #include <linux/string.h>
44 #include <linux/errno.h> 44 #include <linux/errno.h>
45 #include <linux/mtio.h> 45 #include <linux/mtio.h>
46 #include <linux/ioctl.h> 46 #include <linux/ioctl.h>
47 #include <linux/fcntl.h> 47 #include <linux/fcntl.h>
48 #include <linux/spinlock.h> 48 #include <linux/spinlock.h>
49 #include <linux/vmalloc.h> 49 #include <linux/vmalloc.h>
50 #include <linux/blkdev.h> 50 #include <linux/blkdev.h>
51 #include <linux/moduleparam.h> 51 #include <linux/moduleparam.h>
52 #include <linux/delay.h> 52 #include <linux/delay.h>
53 #include <linux/jiffies.h> 53 #include <linux/jiffies.h>
54 #include <linux/mutex.h> 54 #include <linux/mutex.h>
55 #include <asm/uaccess.h> 55 #include <asm/uaccess.h>
56 #include <asm/dma.h> 56 #include <asm/dma.h>
57 #include <asm/system.h> 57 #include <asm/system.h>
58 58
59 /* The driver prints some debugging information on the console if DEBUG 59 /* The driver prints some debugging information on the console if DEBUG
60 is defined and non-zero. */ 60 is defined and non-zero. */
61 #define DEBUG 0 61 #define DEBUG 0
62 62
63 /* The message level for the debug messages is currently set to KERN_NOTICE 63 /* The message level for the debug messages is currently set to KERN_NOTICE
64 so that people can easily see the messages. Later when the debugging messages 64 so that people can easily see the messages. Later when the debugging messages
65 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */ 65 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
66 #define OSST_DEB_MSG KERN_NOTICE 66 #define OSST_DEB_MSG KERN_NOTICE
67 67
68 #include <scsi/scsi.h> 68 #include <scsi/scsi.h>
69 #include <scsi/scsi_dbg.h> 69 #include <scsi/scsi_dbg.h>
70 #include <scsi/scsi_device.h> 70 #include <scsi/scsi_device.h>
71 #include <scsi/scsi_driver.h> 71 #include <scsi/scsi_driver.h>
72 #include <scsi/scsi_eh.h> 72 #include <scsi/scsi_eh.h>
73 #include <scsi/scsi_host.h> 73 #include <scsi/scsi_host.h>
74 #include <scsi/scsi_ioctl.h> 74 #include <scsi/scsi_ioctl.h>
75 75
76 #define ST_KILOBYTE 1024 76 #define ST_KILOBYTE 1024
77 77
78 #include "st.h" 78 #include "st.h"
79 #include "osst.h" 79 #include "osst.h"
80 #include "osst_options.h" 80 #include "osst_options.h"
81 #include "osst_detect.h" 81 #include "osst_detect.h"
82 82
83 static DEFINE_MUTEX(osst_int_mutex); 83 static DEFINE_MUTEX(osst_int_mutex);
84 static int max_dev = 0; 84 static int max_dev = 0;
85 static int write_threshold_kbs = 0; 85 static int write_threshold_kbs = 0;
86 static int max_sg_segs = 0; 86 static int max_sg_segs = 0;
87 87
88 #ifdef MODULE 88 #ifdef MODULE
89 MODULE_AUTHOR("Willem Riede"); 89 MODULE_AUTHOR("Willem Riede");
90 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver"); 90 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
91 MODULE_LICENSE("GPL"); 91 MODULE_LICENSE("GPL");
92 MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR); 92 MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR);
93 MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE); 93 MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
94 94
95 module_param(max_dev, int, 0444); 95 module_param(max_dev, int, 0444);
96 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)"); 96 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
97 97
98 module_param(write_threshold_kbs, int, 0644); 98 module_param(write_threshold_kbs, int, 0644);
99 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)"); 99 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
100 100
101 module_param(max_sg_segs, int, 0644); 101 module_param(max_sg_segs, int, 0644);
102 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)"); 102 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
103 #else 103 #else
104 static struct osst_dev_parm { 104 static struct osst_dev_parm {
105 char *name; 105 char *name;
106 int *val; 106 int *val;
107 } parms[] __initdata = { 107 } parms[] __initdata = {
108 { "max_dev", &max_dev }, 108 { "max_dev", &max_dev },
109 { "write_threshold_kbs", &write_threshold_kbs }, 109 { "write_threshold_kbs", &write_threshold_kbs },
110 { "max_sg_segs", &max_sg_segs } 110 { "max_sg_segs", &max_sg_segs }
111 }; 111 };
112 #endif 112 #endif
113 113
114 /* Some default definitions have been moved to osst_options.h */ 114 /* Some default definitions have been moved to osst_options.h */
115 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE) 115 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
116 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE) 116 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
117 117
118 /* The buffer size should fit into the 24 bits for length in the 118 /* The buffer size should fit into the 24 bits for length in the
119 6-byte SCSI read and write commands. */ 119 6-byte SCSI read and write commands. */
120 #if OSST_BUFFER_SIZE >= (2 << 24 - 1) 120 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
121 #error "Buffer size should not exceed (2 << 24 - 1) bytes!" 121 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
122 #endif 122 #endif
123 123
124 #if DEBUG 124 #if DEBUG
125 static int debugging = 1; 125 static int debugging = 1;
126 /* uncomment define below to test error recovery */ 126 /* uncomment define below to test error recovery */
127 // #define OSST_INJECT_ERRORS 1 127 // #define OSST_INJECT_ERRORS 1
128 #endif 128 #endif
129 129
130 /* Do not retry! The drive firmware already retries when appropriate, 130 /* Do not retry! The drive firmware already retries when appropriate,
131 and when it tries to tell us something, we had better listen... */ 131 and when it tries to tell us something, we had better listen... */
132 #define MAX_RETRIES 0 132 #define MAX_RETRIES 0
133 133
134 #define NO_TAPE NOT_READY 134 #define NO_TAPE NOT_READY
135 135
136 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1) 136 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
137 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12) 137 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
138 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2) 138 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
139 139
140 #define OSST_TIMEOUT (200 * HZ) 140 #define OSST_TIMEOUT (200 * HZ)
141 #define OSST_LONG_TIMEOUT (1800 * HZ) 141 #define OSST_LONG_TIMEOUT (1800 * HZ)
142 142
143 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT)) 143 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
144 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT) 144 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
145 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0) 145 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
146 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1)) 146 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
147 147
148 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower 148 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
149 24 bits) */ 149 24 bits) */
150 #define SET_DENS_AND_BLK 0x10001 150 #define SET_DENS_AND_BLK 0x10001
151 151
152 static int osst_buffer_size = OSST_BUFFER_SIZE; 152 static int osst_buffer_size = OSST_BUFFER_SIZE;
153 static int osst_write_threshold = OSST_WRITE_THRESHOLD; 153 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
154 static int osst_max_sg_segs = OSST_MAX_SG; 154 static int osst_max_sg_segs = OSST_MAX_SG;
155 static int osst_max_dev = OSST_MAX_TAPES; 155 static int osst_max_dev = OSST_MAX_TAPES;
156 static int osst_nr_dev; 156 static int osst_nr_dev;
157 157
158 static struct osst_tape **os_scsi_tapes = NULL; 158 static struct osst_tape **os_scsi_tapes = NULL;
159 static DEFINE_RWLOCK(os_scsi_tapes_lock); 159 static DEFINE_RWLOCK(os_scsi_tapes_lock);
160 160
161 static int modes_defined = 0; 161 static int modes_defined = 0;
162 162
163 static struct osst_buffer *new_tape_buffer(int, int, int); 163 static struct osst_buffer *new_tape_buffer(int, int, int);
164 static int enlarge_buffer(struct osst_buffer *, int); 164 static int enlarge_buffer(struct osst_buffer *, int);
165 static void normalize_buffer(struct osst_buffer *); 165 static void normalize_buffer(struct osst_buffer *);
166 static int append_to_buffer(const char __user *, struct osst_buffer *, int); 166 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
167 static int from_buffer(struct osst_buffer *, char __user *, int); 167 static int from_buffer(struct osst_buffer *, char __user *, int);
168 static int osst_zero_buffer_tail(struct osst_buffer *); 168 static int osst_zero_buffer_tail(struct osst_buffer *);
169 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *); 169 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
170 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *); 170 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
171 171
172 static int osst_probe(struct device *); 172 static int osst_probe(struct device *);
173 static int osst_remove(struct device *); 173 static int osst_remove(struct device *);
174 174
175 static struct scsi_driver osst_template = { 175 static struct scsi_driver osst_template = {
176 .owner = THIS_MODULE, 176 .owner = THIS_MODULE,
177 .gendrv = { 177 .gendrv = {
178 .name = "osst", 178 .name = "osst",
179 .probe = osst_probe, 179 .probe = osst_probe,
180 .remove = osst_remove, 180 .remove = osst_remove,
181 } 181 }
182 }; 182 };
183 183
184 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt, 184 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt,
185 unsigned int cmd_in, unsigned long arg); 185 unsigned int cmd_in, unsigned long arg);
186 186
187 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip); 187 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip);
188 188
189 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt); 189 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt);
190 190
191 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt); 191 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt);
192 192
193 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending); 193 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending);
194 194
195 static inline char *tape_name(struct osst_tape *tape) 195 static inline char *tape_name(struct osst_tape *tape)
196 { 196 {
197 return tape->drive->disk_name; 197 return tape->drive->disk_name;
198 } 198 }
199 199
200 /* Routines that handle the interaction with mid-layer SCSI routines */ 200 /* Routines that handle the interaction with mid-layer SCSI routines */
201 201
202 202
203 /* Normalize Sense */ 203 /* Normalize Sense */
204 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s) 204 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s)
205 { 205 {
206 const u8 *ucp; 206 const u8 *ucp;
207 const u8 *sense = SRpnt->sense; 207 const u8 *sense = SRpnt->sense;
208 208
209 s->have_sense = scsi_normalize_sense(SRpnt->sense, 209 s->have_sense = scsi_normalize_sense(SRpnt->sense,
210 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr); 210 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
211 s->flags = 0; 211 s->flags = 0;
212 212
213 if (s->have_sense) { 213 if (s->have_sense) {
214 s->deferred = 0; 214 s->deferred = 0;
215 s->remainder_valid = 215 s->remainder_valid =
216 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64); 216 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
217 switch (sense[0] & 0x7f) { 217 switch (sense[0] & 0x7f) {
218 case 0x71: 218 case 0x71:
219 s->deferred = 1; 219 s->deferred = 1;
220 case 0x70: 220 case 0x70:
221 s->fixed_format = 1; 221 s->fixed_format = 1;
222 s->flags = sense[2] & 0xe0; 222 s->flags = sense[2] & 0xe0;
223 break; 223 break;
224 case 0x73: 224 case 0x73:
225 s->deferred = 1; 225 s->deferred = 1;
226 case 0x72: 226 case 0x72:
227 s->fixed_format = 0; 227 s->fixed_format = 0;
228 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4); 228 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
229 s->flags = ucp ? (ucp[3] & 0xe0) : 0; 229 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
230 break; 230 break;
231 } 231 }
232 } 232 }
233 } 233 }
234 234
235 /* Convert the result to success code */ 235 /* Convert the result to success code */
236 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt) 236 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
237 { 237 {
238 char *name = tape_name(STp); 238 char *name = tape_name(STp);
239 int result = SRpnt->result; 239 int result = SRpnt->result;
240 u8 * sense = SRpnt->sense, scode; 240 u8 * sense = SRpnt->sense, scode;
241 #if DEBUG 241 #if DEBUG
242 const char *stp; 242 const char *stp;
243 #endif 243 #endif
244 struct st_cmdstatus *cmdstatp; 244 struct st_cmdstatus *cmdstatp;
245 245
246 if (!result) 246 if (!result)
247 return 0; 247 return 0;
248 248
249 cmdstatp = &STp->buffer->cmdstat; 249 cmdstatp = &STp->buffer->cmdstat;
250 osst_analyze_sense(SRpnt, cmdstatp); 250 osst_analyze_sense(SRpnt, cmdstatp);
251 251
252 if (cmdstatp->have_sense) 252 if (cmdstatp->have_sense)
253 scode = STp->buffer->cmdstat.sense_hdr.sense_key; 253 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
254 else 254 else
255 scode = 0; 255 scode = 0;
256 #if DEBUG 256 #if DEBUG
257 if (debugging) { 257 if (debugging) {
258 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n", 258 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
259 name, result, 259 name, result,
260 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2], 260 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
261 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]); 261 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
262 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n", 262 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
263 name, scode, sense[12], sense[13]); 263 name, scode, sense[12], sense[13]);
264 if (cmdstatp->have_sense) 264 if (cmdstatp->have_sense)
265 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); 265 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
266 } 266 }
267 else 267 else
268 #endif 268 #endif
269 if (cmdstatp->have_sense && ( 269 if (cmdstatp->have_sense && (
270 scode != NO_SENSE && 270 scode != NO_SENSE &&
271 scode != RECOVERED_ERROR && 271 scode != RECOVERED_ERROR &&
272 /* scode != UNIT_ATTENTION && */ 272 /* scode != UNIT_ATTENTION && */
273 scode != BLANK_CHECK && 273 scode != BLANK_CHECK &&
274 scode != VOLUME_OVERFLOW && 274 scode != VOLUME_OVERFLOW &&
275 SRpnt->cmd[0] != MODE_SENSE && 275 SRpnt->cmd[0] != MODE_SENSE &&
276 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */ 276 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
277 if (cmdstatp->have_sense) { 277 if (cmdstatp->have_sense) {
278 printk(KERN_WARNING "%s:W: Command with sense data:\n", name); 278 printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
279 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); 279 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
280 } 280 }
281 else { 281 else {
282 static int notyetprinted = 1; 282 static int notyetprinted = 1;
283 283
284 printk(KERN_WARNING 284 printk(KERN_WARNING
285 "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n", 285 "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n",
286 name, result, driver_byte(result), 286 name, result, driver_byte(result),
287 host_byte(result)); 287 host_byte(result));
288 if (notyetprinted) { 288 if (notyetprinted) {
289 notyetprinted = 0; 289 notyetprinted = 0;
290 printk(KERN_INFO 290 printk(KERN_INFO
291 "%s:I: This warning may be caused by your scsi controller,\n", name); 291 "%s:I: This warning may be caused by your scsi controller,\n", name);
292 printk(KERN_INFO 292 printk(KERN_INFO
293 "%s:I: it has been reported with some Buslogic cards.\n", name); 293 "%s:I: it has been reported with some Buslogic cards.\n", name);
294 } 294 }
295 } 295 }
296 } 296 }
297 STp->pos_unknown |= STp->device->was_reset; 297 STp->pos_unknown |= STp->device->was_reset;
298 298
299 if (cmdstatp->have_sense && scode == RECOVERED_ERROR) { 299 if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
300 STp->recover_count++; 300 STp->recover_count++;
301 STp->recover_erreg++; 301 STp->recover_erreg++;
302 #if DEBUG 302 #if DEBUG
303 if (debugging) { 303 if (debugging) {
304 if (SRpnt->cmd[0] == READ_6) 304 if (SRpnt->cmd[0] == READ_6)
305 stp = "read"; 305 stp = "read";
306 else if (SRpnt->cmd[0] == WRITE_6) 306 else if (SRpnt->cmd[0] == WRITE_6)
307 stp = "write"; 307 stp = "write";
308 else 308 else
309 stp = "ioctl"; 309 stp = "ioctl";
310 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp, 310 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
311 STp->recover_count); 311 STp->recover_count);
312 } 312 }
313 #endif 313 #endif
314 if ((sense[2] & 0xe0) == 0) 314 if ((sense[2] & 0xe0) == 0)
315 return 0; 315 return 0;
316 } 316 }
317 return (-EIO); 317 return (-EIO);
318 } 318 }
319 319
320 320
321 /* Wakeup from interrupt */ 321 /* Wakeup from interrupt */
322 static void osst_end_async(struct request *req, int update) 322 static void osst_end_async(struct request *req, int update)
323 { 323 {
324 struct osst_request *SRpnt = req->end_io_data; 324 struct osst_request *SRpnt = req->end_io_data;
325 struct osst_tape *STp = SRpnt->stp; 325 struct osst_tape *STp = SRpnt->stp;
326 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; 326 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
327 327
328 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors; 328 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
329 #if DEBUG 329 #if DEBUG
330 STp->write_pending = 0; 330 STp->write_pending = 0;
331 #endif 331 #endif
332 if (SRpnt->waiting) 332 if (SRpnt->waiting)
333 complete(SRpnt->waiting); 333 complete(SRpnt->waiting);
334 334
335 if (SRpnt->bio) { 335 if (SRpnt->bio) {
336 kfree(mdata->pages); 336 kfree(mdata->pages);
337 blk_rq_unmap_user(SRpnt->bio); 337 blk_rq_unmap_user(SRpnt->bio);
338 } 338 }
339 339
340 __blk_put_request(req->q, req); 340 __blk_put_request(req->q, req);
341 } 341 }
342 342
343 /* osst_request memory management */ 343 /* osst_request memory management */
344 static struct osst_request *osst_allocate_request(void) 344 static struct osst_request *osst_allocate_request(void)
345 { 345 {
346 return kzalloc(sizeof(struct osst_request), GFP_KERNEL); 346 return kzalloc(sizeof(struct osst_request), GFP_KERNEL);
347 } 347 }
348 348
349 static void osst_release_request(struct osst_request *streq) 349 static void osst_release_request(struct osst_request *streq)
350 { 350 {
351 kfree(streq); 351 kfree(streq);
352 } 352 }
353 353
354 static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd, 354 static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
355 int cmd_len, int data_direction, void *buffer, unsigned bufflen, 355 int cmd_len, int data_direction, void *buffer, unsigned bufflen,
356 int use_sg, int timeout, int retries) 356 int use_sg, int timeout, int retries)
357 { 357 {
358 struct request *req; 358 struct request *req;
359 struct page **pages = NULL; 359 struct page **pages = NULL;
360 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; 360 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
361 361
362 int err = 0; 362 int err = 0;
363 int write = (data_direction == DMA_TO_DEVICE); 363 int write = (data_direction == DMA_TO_DEVICE);
364 364
365 req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL); 365 req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL);
366 if (!req) 366 if (!req)
367 return DRIVER_ERROR << 24; 367 return DRIVER_ERROR << 24;
368 368
369 req->cmd_type = REQ_TYPE_BLOCK_PC; 369 req->cmd_type = REQ_TYPE_BLOCK_PC;
370 req->cmd_flags |= REQ_QUIET; 370 req->cmd_flags |= REQ_QUIET;
371 371
372 SRpnt->bio = NULL; 372 SRpnt->bio = NULL;
373 373
374 if (use_sg) { 374 if (use_sg) {
375 struct scatterlist *sg, *sgl = (struct scatterlist *)buffer; 375 struct scatterlist *sg, *sgl = (struct scatterlist *)buffer;
376 int i; 376 int i;
377 377
378 pages = kzalloc(use_sg * sizeof(struct page *), GFP_KERNEL); 378 pages = kzalloc(use_sg * sizeof(struct page *), GFP_KERNEL);
379 if (!pages) 379 if (!pages)
380 goto free_req; 380 goto free_req;
381 381
382 for_each_sg(sgl, sg, use_sg, i) 382 for_each_sg(sgl, sg, use_sg, i)
383 pages[i] = sg_page(sg); 383 pages[i] = sg_page(sg);
384 384
385 mdata->null_mapped = 1; 385 mdata->null_mapped = 1;
386 386
387 mdata->page_order = get_order(sgl[0].length); 387 mdata->page_order = get_order(sgl[0].length);
388 mdata->nr_entries = 388 mdata->nr_entries =
389 DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order); 389 DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order);
390 mdata->offset = 0; 390 mdata->offset = 0;
391 391
392 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL); 392 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
393 if (err) { 393 if (err) {
394 kfree(pages); 394 kfree(pages);
395 goto free_req; 395 goto free_req;
396 } 396 }
397 SRpnt->bio = req->bio; 397 SRpnt->bio = req->bio;
398 mdata->pages = pages; 398 mdata->pages = pages;
399 399
400 } else if (bufflen) { 400 } else if (bufflen) {
401 err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL); 401 err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL);
402 if (err) 402 if (err)
403 goto free_req; 403 goto free_req;
404 } 404 }
405 405
406 req->cmd_len = cmd_len; 406 req->cmd_len = cmd_len;
407 memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ 407 memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
408 memcpy(req->cmd, cmd, req->cmd_len); 408 memcpy(req->cmd, cmd, req->cmd_len);
409 req->sense = SRpnt->sense; 409 req->sense = SRpnt->sense;
410 req->sense_len = 0; 410 req->sense_len = 0;
411 req->timeout = timeout; 411 req->timeout = timeout;
412 req->retries = retries; 412 req->retries = retries;
413 req->end_io_data = SRpnt; 413 req->end_io_data = SRpnt;
414 414
415 blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async); 415 blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async);
416 return 0; 416 return 0;
417 free_req: 417 free_req:
418 blk_put_request(req); 418 blk_put_request(req);
419 return DRIVER_ERROR << 24; 419 return DRIVER_ERROR << 24;
420 } 420 }
421 421
422 /* Do the scsi command. Waits until command performed if do_wait is true. 422 /* Do the scsi command. Waits until command performed if do_wait is true.
423 Otherwise osst_write_behind_check() is used to check that the command 423 Otherwise osst_write_behind_check() is used to check that the command
424 has finished. */ 424 has finished. */
425 static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp, 425 static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp,
426 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait) 426 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
427 { 427 {
428 unsigned char *bp; 428 unsigned char *bp;
429 unsigned short use_sg; 429 unsigned short use_sg;
430 #ifdef OSST_INJECT_ERRORS 430 #ifdef OSST_INJECT_ERRORS
431 static int inject = 0; 431 static int inject = 0;
432 static int repeat = 0; 432 static int repeat = 0;
433 #endif 433 #endif
434 struct completion *waiting; 434 struct completion *waiting;
435 435
436 /* if async, make sure there's no command outstanding */ 436 /* if async, make sure there's no command outstanding */
437 if (!do_wait && ((STp->buffer)->last_SRpnt)) { 437 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
438 printk(KERN_ERR "%s: Async command already active.\n", 438 printk(KERN_ERR "%s: Async command already active.\n",
439 tape_name(STp)); 439 tape_name(STp));
440 if (signal_pending(current)) 440 if (signal_pending(current))
441 (STp->buffer)->syscall_result = (-EINTR); 441 (STp->buffer)->syscall_result = (-EINTR);
442 else 442 else
443 (STp->buffer)->syscall_result = (-EBUSY); 443 (STp->buffer)->syscall_result = (-EBUSY);
444 return NULL; 444 return NULL;
445 } 445 }
446 446
447 if (SRpnt == NULL) { 447 if (SRpnt == NULL) {
448 SRpnt = osst_allocate_request(); 448 SRpnt = osst_allocate_request();
449 if (SRpnt == NULL) { 449 if (SRpnt == NULL) {
450 printk(KERN_ERR "%s: Can't allocate SCSI request.\n", 450 printk(KERN_ERR "%s: Can't allocate SCSI request.\n",
451 tape_name(STp)); 451 tape_name(STp));
452 if (signal_pending(current)) 452 if (signal_pending(current))
453 (STp->buffer)->syscall_result = (-EINTR); 453 (STp->buffer)->syscall_result = (-EINTR);
454 else 454 else
455 (STp->buffer)->syscall_result = (-EBUSY); 455 (STp->buffer)->syscall_result = (-EBUSY);
456 return NULL; 456 return NULL;
457 } 457 }
458 SRpnt->stp = STp; 458 SRpnt->stp = STp;
459 } 459 }
460 460
461 /* If async IO, set last_SRpnt. This ptr tells write_behind_check 461 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
462 which IO is outstanding. It's nulled out when the IO completes. */ 462 which IO is outstanding. It's nulled out when the IO completes. */
463 if (!do_wait) 463 if (!do_wait)
464 (STp->buffer)->last_SRpnt = SRpnt; 464 (STp->buffer)->last_SRpnt = SRpnt;
465 465
466 waiting = &STp->wait; 466 waiting = &STp->wait;
467 init_completion(waiting); 467 init_completion(waiting);
468 SRpnt->waiting = waiting; 468 SRpnt->waiting = waiting;
469 469
470 use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0; 470 use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0;
471 if (use_sg) { 471 if (use_sg) {
472 bp = (char *)&(STp->buffer->sg[0]); 472 bp = (char *)&(STp->buffer->sg[0]);
473 if (STp->buffer->sg_segs < use_sg) 473 if (STp->buffer->sg_segs < use_sg)
474 use_sg = STp->buffer->sg_segs; 474 use_sg = STp->buffer->sg_segs;
475 } 475 }
476 else 476 else
477 bp = (STp->buffer)->b_data; 477 bp = (STp->buffer)->b_data;
478 478
479 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd)); 479 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
480 STp->buffer->cmdstat.have_sense = 0; 480 STp->buffer->cmdstat.have_sense = 0;
481 STp->buffer->syscall_result = 0; 481 STp->buffer->syscall_result = 0;
482 482
483 if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes, 483 if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
484 use_sg, timeout, retries)) 484 use_sg, timeout, retries))
485 /* could not allocate the buffer or request was too large */ 485 /* could not allocate the buffer or request was too large */
486 (STp->buffer)->syscall_result = (-EBUSY); 486 (STp->buffer)->syscall_result = (-EBUSY);
487 else if (do_wait) { 487 else if (do_wait) {
488 wait_for_completion(waiting); 488 wait_for_completion(waiting);
489 SRpnt->waiting = NULL; 489 SRpnt->waiting = NULL;
490 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt); 490 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
491 #ifdef OSST_INJECT_ERRORS 491 #ifdef OSST_INJECT_ERRORS
492 if (STp->buffer->syscall_result == 0 && 492 if (STp->buffer->syscall_result == 0 &&
493 cmd[0] == READ_6 && 493 cmd[0] == READ_6 &&
494 cmd[4] && 494 cmd[4] &&
495 ( (++ inject % 83) == 29 || 495 ( (++ inject % 83) == 29 ||
496 (STp->first_frame_position == 240 496 (STp->first_frame_position == 240
497 /* or STp->read_error_frame to fail again on the block calculated above */ && 497 /* or STp->read_error_frame to fail again on the block calculated above */ &&
498 ++repeat < 3))) { 498 ++repeat < 3))) {
499 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp)); 499 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
500 STp->buffer->last_result_fatal = 1; 500 STp->buffer->last_result_fatal = 1;
501 } 501 }
502 #endif 502 #endif
503 } 503 }
504 return SRpnt; 504 return SRpnt;
505 } 505 }
506 506
507 507
508 /* Handle the write-behind checking (downs the semaphore) */ 508 /* Handle the write-behind checking (downs the semaphore) */
509 static void osst_write_behind_check(struct osst_tape *STp) 509 static void osst_write_behind_check(struct osst_tape *STp)
510 { 510 {
511 struct osst_buffer * STbuffer; 511 struct osst_buffer * STbuffer;
512 512
513 STbuffer = STp->buffer; 513 STbuffer = STp->buffer;
514 514
515 #if DEBUG 515 #if DEBUG
516 if (STp->write_pending) 516 if (STp->write_pending)
517 STp->nbr_waits++; 517 STp->nbr_waits++;
518 else 518 else
519 STp->nbr_finished++; 519 STp->nbr_finished++;
520 #endif 520 #endif
521 wait_for_completion(&(STp->wait)); 521 wait_for_completion(&(STp->wait));
522 STp->buffer->last_SRpnt->waiting = NULL; 522 STp->buffer->last_SRpnt->waiting = NULL;
523 523
524 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt); 524 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
525 525
526 if (STp->buffer->syscall_result) 526 if (STp->buffer->syscall_result)
527 STp->buffer->syscall_result = 527 STp->buffer->syscall_result =
528 osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1); 528 osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1);
529 else 529 else
530 STp->first_frame_position++; 530 STp->first_frame_position++;
531 531
532 osst_release_request(STp->buffer->last_SRpnt); 532 osst_release_request(STp->buffer->last_SRpnt);
533 533
534 if (STbuffer->writing < STbuffer->buffer_bytes) 534 if (STbuffer->writing < STbuffer->buffer_bytes)
535 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n"); 535 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
536 536
537 STbuffer->last_SRpnt = NULL; 537 STbuffer->last_SRpnt = NULL;
538 STbuffer->buffer_bytes -= STbuffer->writing; 538 STbuffer->buffer_bytes -= STbuffer->writing;
539 STbuffer->writing = 0; 539 STbuffer->writing = 0;
540 540
541 return; 541 return;
542 } 542 }
543 543
544 544
545 545
546 /* Onstream specific Routines */ 546 /* Onstream specific Routines */
547 /* 547 /*
548 * Initialize the OnStream AUX 548 * Initialize the OnStream AUX
549 */ 549 */
550 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number, 550 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
551 int logical_blk_num, int blk_sz, int blk_cnt) 551 int logical_blk_num, int blk_sz, int blk_cnt)
552 { 552 {
553 os_aux_t *aux = STp->buffer->aux; 553 os_aux_t *aux = STp->buffer->aux;
554 os_partition_t *par = &aux->partition; 554 os_partition_t *par = &aux->partition;
555 os_dat_t *dat = &aux->dat; 555 os_dat_t *dat = &aux->dat;
556 556
557 if (STp->raw) return; 557 if (STp->raw) return;
558 558
559 memset(aux, 0, sizeof(*aux)); 559 memset(aux, 0, sizeof(*aux));
560 aux->format_id = htonl(0); 560 aux->format_id = htonl(0);
561 memcpy(aux->application_sig, "LIN4", 4); 561 memcpy(aux->application_sig, "LIN4", 4);
562 aux->hdwr = htonl(0); 562 aux->hdwr = htonl(0);
563 aux->frame_type = frame_type; 563 aux->frame_type = frame_type;
564 564
565 switch (frame_type) { 565 switch (frame_type) {
566 case OS_FRAME_TYPE_HEADER: 566 case OS_FRAME_TYPE_HEADER:
567 aux->update_frame_cntr = htonl(STp->update_frame_cntr); 567 aux->update_frame_cntr = htonl(STp->update_frame_cntr);
568 par->partition_num = OS_CONFIG_PARTITION; 568 par->partition_num = OS_CONFIG_PARTITION;
569 par->par_desc_ver = OS_PARTITION_VERSION; 569 par->par_desc_ver = OS_PARTITION_VERSION;
570 par->wrt_pass_cntr = htons(0xffff); 570 par->wrt_pass_cntr = htons(0xffff);
571 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */ 571 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
572 par->first_frame_ppos = htonl(0); 572 par->first_frame_ppos = htonl(0);
573 par->last_frame_ppos = htonl(0xbb7); 573 par->last_frame_ppos = htonl(0xbb7);
574 aux->frame_seq_num = htonl(0); 574 aux->frame_seq_num = htonl(0);
575 aux->logical_blk_num_high = htonl(0); 575 aux->logical_blk_num_high = htonl(0);
576 aux->logical_blk_num = htonl(0); 576 aux->logical_blk_num = htonl(0);
577 aux->next_mark_ppos = htonl(STp->first_mark_ppos); 577 aux->next_mark_ppos = htonl(STp->first_mark_ppos);
578 break; 578 break;
579 case OS_FRAME_TYPE_DATA: 579 case OS_FRAME_TYPE_DATA:
580 case OS_FRAME_TYPE_MARKER: 580 case OS_FRAME_TYPE_MARKER:
581 dat->dat_sz = 8; 581 dat->dat_sz = 8;
582 dat->reserved1 = 0; 582 dat->reserved1 = 0;
583 dat->entry_cnt = 1; 583 dat->entry_cnt = 1;
584 dat->reserved3 = 0; 584 dat->reserved3 = 0;
585 dat->dat_list[0].blk_sz = htonl(blk_sz); 585 dat->dat_list[0].blk_sz = htonl(blk_sz);
586 dat->dat_list[0].blk_cnt = htons(blk_cnt); 586 dat->dat_list[0].blk_cnt = htons(blk_cnt);
587 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER? 587 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
588 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA; 588 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
589 dat->dat_list[0].reserved = 0; 589 dat->dat_list[0].reserved = 0;
590 case OS_FRAME_TYPE_EOD: 590 case OS_FRAME_TYPE_EOD:
591 aux->update_frame_cntr = htonl(0); 591 aux->update_frame_cntr = htonl(0);
592 par->partition_num = OS_DATA_PARTITION; 592 par->partition_num = OS_DATA_PARTITION;
593 par->par_desc_ver = OS_PARTITION_VERSION; 593 par->par_desc_ver = OS_PARTITION_VERSION;
594 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr); 594 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
595 par->first_frame_ppos = htonl(STp->first_data_ppos); 595 par->first_frame_ppos = htonl(STp->first_data_ppos);
596 par->last_frame_ppos = htonl(STp->capacity); 596 par->last_frame_ppos = htonl(STp->capacity);
597 aux->frame_seq_num = htonl(frame_seq_number); 597 aux->frame_seq_num = htonl(frame_seq_number);
598 aux->logical_blk_num_high = htonl(0); 598 aux->logical_blk_num_high = htonl(0);
599 aux->logical_blk_num = htonl(logical_blk_num); 599 aux->logical_blk_num = htonl(logical_blk_num);
600 break; 600 break;
601 default: ; /* probably FILL */ 601 default: ; /* probably FILL */
602 } 602 }
603 aux->filemark_cnt = htonl(STp->filemark_cnt); 603 aux->filemark_cnt = htonl(STp->filemark_cnt);
604 aux->phys_fm = htonl(0xffffffff); 604 aux->phys_fm = htonl(0xffffffff);
605 aux->last_mark_ppos = htonl(STp->last_mark_ppos); 605 aux->last_mark_ppos = htonl(STp->last_mark_ppos);
606 aux->last_mark_lbn = htonl(STp->last_mark_lbn); 606 aux->last_mark_lbn = htonl(STp->last_mark_lbn);
607 } 607 }
608 608
609 /* 609 /*
610 * Verify that we have the correct tape frame 610 * Verify that we have the correct tape frame
611 */ 611 */
612 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet) 612 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
613 { 613 {
614 char * name = tape_name(STp); 614 char * name = tape_name(STp);
615 os_aux_t * aux = STp->buffer->aux; 615 os_aux_t * aux = STp->buffer->aux;
616 os_partition_t * par = &(aux->partition); 616 os_partition_t * par = &(aux->partition);
617 struct st_partstat * STps = &(STp->ps[STp->partition]); 617 struct st_partstat * STps = &(STp->ps[STp->partition]);
618 int blk_cnt, blk_sz, i; 618 int blk_cnt, blk_sz, i;
619 619
620 if (STp->raw) { 620 if (STp->raw) {
621 if (STp->buffer->syscall_result) { 621 if (STp->buffer->syscall_result) {
622 for (i=0; i < STp->buffer->sg_segs; i++) 622 for (i=0; i < STp->buffer->sg_segs; i++)
623 memset(page_address(sg_page(&STp->buffer->sg[i])), 623 memset(page_address(sg_page(&STp->buffer->sg[i])),
624 0, STp->buffer->sg[i].length); 624 0, STp->buffer->sg[i].length);
625 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME"); 625 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
626 } else 626 } else
627 STp->buffer->buffer_bytes = OS_FRAME_SIZE; 627 STp->buffer->buffer_bytes = OS_FRAME_SIZE;
628 return 1; 628 return 1;
629 } 629 }
630 if (STp->buffer->syscall_result) { 630 if (STp->buffer->syscall_result) {
631 #if DEBUG 631 #if DEBUG
632 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name); 632 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
633 #endif 633 #endif
634 return 0; 634 return 0;
635 } 635 }
636 if (ntohl(aux->format_id) != 0) { 636 if (ntohl(aux->format_id) != 0) {
637 #if DEBUG 637 #if DEBUG
638 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id)); 638 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
639 #endif 639 #endif
640 goto err_out; 640 goto err_out;
641 } 641 }
642 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 && 642 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
643 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) { 643 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
644 #if DEBUG 644 #if DEBUG
645 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name); 645 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
646 #endif 646 #endif
647 goto err_out; 647 goto err_out;
648 } 648 }
649 if (par->partition_num != OS_DATA_PARTITION) { 649 if (par->partition_num != OS_DATA_PARTITION) {
650 if (!STp->linux_media || STp->linux_media_version != 2) { 650 if (!STp->linux_media || STp->linux_media_version != 2) {
651 #if DEBUG 651 #if DEBUG
652 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n", 652 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
653 name, par->partition_num); 653 name, par->partition_num);
654 #endif 654 #endif
655 goto err_out; 655 goto err_out;
656 } 656 }
657 } 657 }
658 if (par->par_desc_ver != OS_PARTITION_VERSION) { 658 if (par->par_desc_ver != OS_PARTITION_VERSION) {
659 #if DEBUG 659 #if DEBUG
660 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver); 660 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
661 #endif 661 #endif
662 goto err_out; 662 goto err_out;
663 } 663 }
664 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) { 664 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
665 #if DEBUG 665 #if DEBUG
666 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n", 666 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
667 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr); 667 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
668 #endif 668 #endif
669 goto err_out; 669 goto err_out;
670 } 670 }
671 if (aux->frame_type != OS_FRAME_TYPE_DATA && 671 if (aux->frame_type != OS_FRAME_TYPE_DATA &&
672 aux->frame_type != OS_FRAME_TYPE_EOD && 672 aux->frame_type != OS_FRAME_TYPE_EOD &&
673 aux->frame_type != OS_FRAME_TYPE_MARKER) { 673 aux->frame_type != OS_FRAME_TYPE_MARKER) {
674 if (!quiet) { 674 if (!quiet) {
675 #if DEBUG 675 #if DEBUG
676 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type); 676 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
677 #endif 677 #endif
678 } 678 }
679 goto err_out; 679 goto err_out;
680 } 680 }
681 if (aux->frame_type == OS_FRAME_TYPE_EOD && 681 if (aux->frame_type == OS_FRAME_TYPE_EOD &&
682 STp->first_frame_position < STp->eod_frame_ppos) { 682 STp->first_frame_position < STp->eod_frame_ppos) {
683 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name, 683 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
684 STp->first_frame_position); 684 STp->first_frame_position);
685 goto err_out; 685 goto err_out;
686 } 686 }
687 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) { 687 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
688 if (!quiet) { 688 if (!quiet) {
689 #if DEBUG 689 #if DEBUG
690 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n", 690 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
691 name, ntohl(aux->frame_seq_num), frame_seq_number); 691 name, ntohl(aux->frame_seq_num), frame_seq_number);
692 #endif 692 #endif
693 } 693 }
694 goto err_out; 694 goto err_out;
695 } 695 }
696 if (aux->frame_type == OS_FRAME_TYPE_MARKER) { 696 if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
697 STps->eof = ST_FM_HIT; 697 STps->eof = ST_FM_HIT;
698 698
699 i = ntohl(aux->filemark_cnt); 699 i = ntohl(aux->filemark_cnt);
700 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt || 700 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
701 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) { 701 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
702 #if DEBUG 702 #if DEBUG
703 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name, 703 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
704 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected", 704 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
705 i, STp->first_frame_position - 1); 705 i, STp->first_frame_position - 1);
706 #endif 706 #endif
707 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1); 707 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
708 if (i >= STp->filemark_cnt) 708 if (i >= STp->filemark_cnt)
709 STp->filemark_cnt = i+1; 709 STp->filemark_cnt = i+1;
710 } 710 }
711 } 711 }
712 if (aux->frame_type == OS_FRAME_TYPE_EOD) { 712 if (aux->frame_type == OS_FRAME_TYPE_EOD) {
713 STps->eof = ST_EOD_1; 713 STps->eof = ST_EOD_1;
714 STp->frame_in_buffer = 1; 714 STp->frame_in_buffer = 1;
715 } 715 }
716 if (aux->frame_type == OS_FRAME_TYPE_DATA) { 716 if (aux->frame_type == OS_FRAME_TYPE_DATA) {
717 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt); 717 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
718 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz); 718 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
719 STp->buffer->buffer_bytes = blk_cnt * blk_sz; 719 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
720 STp->buffer->read_pointer = 0; 720 STp->buffer->read_pointer = 0;
721 STp->frame_in_buffer = 1; 721 STp->frame_in_buffer = 1;
722 722
723 /* See what block size was used to write file */ 723 /* See what block size was used to write file */
724 if (STp->block_size != blk_sz && blk_sz > 0) { 724 if (STp->block_size != blk_sz && blk_sz > 0) {
725 printk(KERN_INFO 725 printk(KERN_INFO
726 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n", 726 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
727 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k', 727 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
728 STp->block_size<1024?STp->block_size:STp->block_size/1024, 728 STp->block_size<1024?STp->block_size:STp->block_size/1024,
729 STp->block_size<1024?'b':'k'); 729 STp->block_size<1024?'b':'k');
730 STp->block_size = blk_sz; 730 STp->block_size = blk_sz;
731 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz; 731 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
732 } 732 }
733 STps->eof = ST_NOEOF; 733 STps->eof = ST_NOEOF;
734 } 734 }
735 STp->frame_seq_number = ntohl(aux->frame_seq_num); 735 STp->frame_seq_number = ntohl(aux->frame_seq_num);
736 STp->logical_blk_num = ntohl(aux->logical_blk_num); 736 STp->logical_blk_num = ntohl(aux->logical_blk_num);
737 return 1; 737 return 1;
738 738
739 err_out: 739 err_out:
740 if (STp->read_error_frame == 0) 740 if (STp->read_error_frame == 0)
741 STp->read_error_frame = STp->first_frame_position - 1; 741 STp->read_error_frame = STp->first_frame_position - 1;
742 return 0; 742 return 0;
743 } 743 }
744 744
745 /* 745 /*
746 * Wait for the unit to become Ready 746 * Wait for the unit to become Ready
747 */ 747 */
748 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt, 748 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
749 unsigned timeout, int initial_delay) 749 unsigned timeout, int initial_delay)
750 { 750 {
751 unsigned char cmd[MAX_COMMAND_SIZE]; 751 unsigned char cmd[MAX_COMMAND_SIZE];
752 struct osst_request * SRpnt; 752 struct osst_request * SRpnt;
753 unsigned long startwait = jiffies; 753 unsigned long startwait = jiffies;
754 #if DEBUG 754 #if DEBUG
755 int dbg = debugging; 755 int dbg = debugging;
756 char * name = tape_name(STp); 756 char * name = tape_name(STp);
757 757
758 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name); 758 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
759 #endif 759 #endif
760 760
761 if (initial_delay > 0) 761 if (initial_delay > 0)
762 msleep(jiffies_to_msecs(initial_delay)); 762 msleep(jiffies_to_msecs(initial_delay));
763 763
764 memset(cmd, 0, MAX_COMMAND_SIZE); 764 memset(cmd, 0, MAX_COMMAND_SIZE);
765 cmd[0] = TEST_UNIT_READY; 765 cmd[0] = TEST_UNIT_READY;
766 766
767 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 767 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
768 *aSRpnt = SRpnt; 768 *aSRpnt = SRpnt;
769 if (!SRpnt) return (-EBUSY); 769 if (!SRpnt) return (-EBUSY);
770 770
771 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) && 771 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
772 (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 && 772 (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
773 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) || 773 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) ||
774 ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 && 774 ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 &&
775 SRpnt->sense[13] == 0 ) )) { 775 SRpnt->sense[13] == 0 ) )) {
776 #if DEBUG 776 #if DEBUG
777 if (debugging) { 777 if (debugging) {
778 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name); 778 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
779 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 779 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
780 debugging = 0; 780 debugging = 0;
781 } 781 }
782 #endif 782 #endif
783 msleep(100); 783 msleep(100);
784 784
785 memset(cmd, 0, MAX_COMMAND_SIZE); 785 memset(cmd, 0, MAX_COMMAND_SIZE);
786 cmd[0] = TEST_UNIT_READY; 786 cmd[0] = TEST_UNIT_READY;
787 787
788 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 788 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
789 } 789 }
790 *aSRpnt = SRpnt; 790 *aSRpnt = SRpnt;
791 #if DEBUG 791 #if DEBUG
792 debugging = dbg; 792 debugging = dbg;
793 #endif 793 #endif
794 if ( STp->buffer->syscall_result && 794 if ( STp->buffer->syscall_result &&
795 osst_write_error_recovery(STp, aSRpnt, 0) ) { 795 osst_write_error_recovery(STp, aSRpnt, 0) ) {
796 #if DEBUG 796 #if DEBUG
797 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name); 797 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
798 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name, 798 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
799 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2], 799 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
800 SRpnt->sense[12], SRpnt->sense[13]); 800 SRpnt->sense[12], SRpnt->sense[13]);
801 #endif 801 #endif
802 return (-EIO); 802 return (-EIO);
803 } 803 }
804 #if DEBUG 804 #if DEBUG
805 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name); 805 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
806 #endif 806 #endif
807 return 0; 807 return 0;
808 } 808 }
809 809
810 /* 810 /*
811 * Wait for a tape to be inserted in the unit 811 * Wait for a tape to be inserted in the unit
812 */ 812 */
813 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout) 813 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
814 { 814 {
815 unsigned char cmd[MAX_COMMAND_SIZE]; 815 unsigned char cmd[MAX_COMMAND_SIZE];
816 struct osst_request * SRpnt; 816 struct osst_request * SRpnt;
817 unsigned long startwait = jiffies; 817 unsigned long startwait = jiffies;
818 #if DEBUG 818 #if DEBUG
819 int dbg = debugging; 819 int dbg = debugging;
820 char * name = tape_name(STp); 820 char * name = tape_name(STp);
821 821
822 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name); 822 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
823 #endif 823 #endif
824 824
825 memset(cmd, 0, MAX_COMMAND_SIZE); 825 memset(cmd, 0, MAX_COMMAND_SIZE);
826 cmd[0] = TEST_UNIT_READY; 826 cmd[0] = TEST_UNIT_READY;
827 827
828 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 828 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
829 *aSRpnt = SRpnt; 829 *aSRpnt = SRpnt;
830 if (!SRpnt) return (-EBUSY); 830 if (!SRpnt) return (-EBUSY);
831 831
832 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) && 832 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
833 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) { 833 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) {
834 #if DEBUG 834 #if DEBUG
835 if (debugging) { 835 if (debugging) {
836 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name); 836 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
837 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 837 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
838 debugging = 0; 838 debugging = 0;
839 } 839 }
840 #endif 840 #endif
841 msleep(100); 841 msleep(100);
842 842
843 memset(cmd, 0, MAX_COMMAND_SIZE); 843 memset(cmd, 0, MAX_COMMAND_SIZE);
844 cmd[0] = TEST_UNIT_READY; 844 cmd[0] = TEST_UNIT_READY;
845 845
846 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 846 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
847 } 847 }
848 *aSRpnt = SRpnt; 848 *aSRpnt = SRpnt;
849 #if DEBUG 849 #if DEBUG
850 debugging = dbg; 850 debugging = dbg;
851 #endif 851 #endif
852 if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 && 852 if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 &&
853 SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) { 853 SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) {
854 #if DEBUG 854 #if DEBUG
855 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name); 855 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
856 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name, 856 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
857 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2], 857 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
858 SRpnt->sense[12], SRpnt->sense[13]); 858 SRpnt->sense[12], SRpnt->sense[13]);
859 #endif 859 #endif
860 return 0; 860 return 0;
861 } 861 }
862 #if DEBUG 862 #if DEBUG
863 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name); 863 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
864 #endif 864 #endif
865 return 1; 865 return 1;
866 } 866 }
867 867
868 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame) 868 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame)
869 { 869 {
870 int retval; 870 int retval;
871 871
872 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */ 872 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
873 retval = osst_set_frame_position(STp, aSRpnt, frame, 0); 873 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
874 if (retval) return (retval); 874 if (retval) return (retval);
875 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE); 875 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
876 return (osst_get_frame_position(STp, aSRpnt)); 876 return (osst_get_frame_position(STp, aSRpnt));
877 } 877 }
878 878
879 /* 879 /*
880 * Wait for write(s) to complete 880 * Wait for write(s) to complete
881 */ 881 */
882 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt) 882 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
883 { 883 {
884 unsigned char cmd[MAX_COMMAND_SIZE]; 884 unsigned char cmd[MAX_COMMAND_SIZE];
885 struct osst_request * SRpnt; 885 struct osst_request * SRpnt;
886 int result = 0; 886 int result = 0;
887 int delay = OSST_WAIT_WRITE_COMPLETE; 887 int delay = OSST_WAIT_WRITE_COMPLETE;
888 #if DEBUG 888 #if DEBUG
889 char * name = tape_name(STp); 889 char * name = tape_name(STp);
890 890
891 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name); 891 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
892 #endif 892 #endif
893 893
894 memset(cmd, 0, MAX_COMMAND_SIZE); 894 memset(cmd, 0, MAX_COMMAND_SIZE);
895 cmd[0] = WRITE_FILEMARKS; 895 cmd[0] = WRITE_FILEMARKS;
896 cmd[1] = 1; 896 cmd[1] = 1;
897 897
898 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 898 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
899 *aSRpnt = SRpnt; 899 *aSRpnt = SRpnt;
900 if (!SRpnt) return (-EBUSY); 900 if (!SRpnt) return (-EBUSY);
901 if (STp->buffer->syscall_result) { 901 if (STp->buffer->syscall_result) {
902 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) { 902 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) {
903 if (SRpnt->sense[13] == 8) { 903 if (SRpnt->sense[13] == 8) {
904 delay = OSST_WAIT_LONG_WRITE_COMPLETE; 904 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
905 } 905 }
906 } else 906 } else
907 result = osst_write_error_recovery(STp, aSRpnt, 0); 907 result = osst_write_error_recovery(STp, aSRpnt, 0);
908 } 908 }
909 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay); 909 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
910 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE; 910 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
911 911
912 return (result); 912 return (result);
913 } 913 }
914 914
915 #define OSST_POLL_PER_SEC 10 915 #define OSST_POLL_PER_SEC 10
916 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to) 916 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to)
917 { 917 {
918 unsigned long startwait = jiffies; 918 unsigned long startwait = jiffies;
919 char * name = tape_name(STp); 919 char * name = tape_name(STp);
920 #if DEBUG 920 #if DEBUG
921 char notyetprinted = 1; 921 char notyetprinted = 1;
922 #endif 922 #endif
923 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING) 923 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
924 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name); 924 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
925 925
926 while (time_before (jiffies, startwait + to*HZ)) 926 while (time_before (jiffies, startwait + to*HZ))
927 { 927 {
928 int result; 928 int result;
929 result = osst_get_frame_position(STp, aSRpnt); 929 result = osst_get_frame_position(STp, aSRpnt);
930 if (result == -EIO) 930 if (result == -EIO)
931 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0) 931 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
932 return 0; /* successful recovery leaves drive ready for frame */ 932 return 0; /* successful recovery leaves drive ready for frame */
933 if (result < 0) break; 933 if (result < 0) break;
934 if (STp->first_frame_position == curr && 934 if (STp->first_frame_position == curr &&
935 ((minlast < 0 && 935 ((minlast < 0 &&
936 (signed)STp->last_frame_position > (signed)curr + minlast) || 936 (signed)STp->last_frame_position > (signed)curr + minlast) ||
937 (minlast >= 0 && STp->cur_frames > minlast) 937 (minlast >= 0 && STp->cur_frames > minlast)
938 ) && result >= 0) 938 ) && result >= 0)
939 { 939 {
940 #if DEBUG 940 #if DEBUG
941 if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC)) 941 if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC))
942 printk (OSST_DEB_MSG 942 printk (OSST_DEB_MSG
943 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n", 943 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
944 name, curr, curr+minlast, STp->first_frame_position, 944 name, curr, curr+minlast, STp->first_frame_position,
945 STp->last_frame_position, STp->cur_frames, 945 STp->last_frame_position, STp->cur_frames,
946 result, (jiffies-startwait)/HZ, 946 result, (jiffies-startwait)/HZ,
947 (((jiffies-startwait)%HZ)*10)/HZ); 947 (((jiffies-startwait)%HZ)*10)/HZ);
948 #endif 948 #endif
949 return 0; 949 return 0;
950 } 950 }
951 #if DEBUG 951 #if DEBUG
952 if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted) 952 if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted)
953 { 953 {
954 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n", 954 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
955 name, curr, curr+minlast, STp->first_frame_position, 955 name, curr, curr+minlast, STp->first_frame_position,
956 STp->last_frame_position, STp->cur_frames, result); 956 STp->last_frame_position, STp->cur_frames, result);
957 notyetprinted--; 957 notyetprinted--;
958 } 958 }
959 #endif 959 #endif
960 msleep(1000 / OSST_POLL_PER_SEC); 960 msleep(1000 / OSST_POLL_PER_SEC);
961 } 961 }
962 #if DEBUG 962 #if DEBUG
963 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n", 963 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
964 name, curr, curr+minlast, STp->first_frame_position, 964 name, curr, curr+minlast, STp->first_frame_position,
965 STp->last_frame_position, STp->cur_frames, 965 STp->last_frame_position, STp->cur_frames,
966 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ); 966 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
967 #endif 967 #endif
968 return -EBUSY; 968 return -EBUSY;
969 } 969 }
970 970
971 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing) 971 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
972 { 972 {
973 struct osst_request * SRpnt; 973 struct osst_request * SRpnt;
974 unsigned char cmd[MAX_COMMAND_SIZE]; 974 unsigned char cmd[MAX_COMMAND_SIZE];
975 unsigned long startwait = jiffies; 975 unsigned long startwait = jiffies;
976 int retval = 1; 976 int retval = 1;
977 char * name = tape_name(STp); 977 char * name = tape_name(STp);
978 978
979 if (writing) { 979 if (writing) {
980 char mybuf[24]; 980 char mybuf[24];
981 char * olddata = STp->buffer->b_data; 981 char * olddata = STp->buffer->b_data;
982 int oldsize = STp->buffer->buffer_size; 982 int oldsize = STp->buffer->buffer_size;
983 983
984 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */ 984 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
985 985
986 memset(cmd, 0, MAX_COMMAND_SIZE); 986 memset(cmd, 0, MAX_COMMAND_SIZE);
987 cmd[0] = WRITE_FILEMARKS; 987 cmd[0] = WRITE_FILEMARKS;
988 cmd[1] = 1; 988 cmd[1] = 1;
989 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, 989 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
990 MAX_RETRIES, 1); 990 MAX_RETRIES, 1);
991 991
992 while (retval && time_before (jiffies, startwait + 5*60*HZ)) { 992 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
993 993
994 if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) { 994 if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) {
995 995
996 /* some failure - not just not-ready */ 996 /* some failure - not just not-ready */
997 retval = osst_write_error_recovery(STp, aSRpnt, 0); 997 retval = osst_write_error_recovery(STp, aSRpnt, 0);
998 break; 998 break;
999 } 999 }
1000 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC); 1000 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
1001 1001
1002 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; 1002 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
1003 memset(cmd, 0, MAX_COMMAND_SIZE); 1003 memset(cmd, 0, MAX_COMMAND_SIZE);
1004 cmd[0] = READ_POSITION; 1004 cmd[0] = READ_POSITION;
1005 1005
1006 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout, 1006 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
1007 MAX_RETRIES, 1); 1007 MAX_RETRIES, 1);
1008 1008
1009 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 ); 1009 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
1010 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; 1010 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
1011 } 1011 }
1012 if (retval) 1012 if (retval)
1013 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name); 1013 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
1014 } else 1014 } else
1015 /* TODO - figure out which error conditions can be handled */ 1015 /* TODO - figure out which error conditions can be handled */
1016 if (STp->buffer->syscall_result) 1016 if (STp->buffer->syscall_result)
1017 printk(KERN_WARNING 1017 printk(KERN_WARNING
1018 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name, 1018 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
1019 (*aSRpnt)->sense[ 2] & 0x0f, 1019 (*aSRpnt)->sense[ 2] & 0x0f,
1020 (*aSRpnt)->sense[12], 1020 (*aSRpnt)->sense[12],
1021 (*aSRpnt)->sense[13]); 1021 (*aSRpnt)->sense[13]);
1022 1022
1023 return retval; 1023 return retval;
1024 } 1024 }
1025 1025
1026 /* 1026 /*
1027 * Read the next OnStream tape frame at the current location 1027 * Read the next OnStream tape frame at the current location
1028 */ 1028 */
1029 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout) 1029 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
1030 { 1030 {
1031 unsigned char cmd[MAX_COMMAND_SIZE]; 1031 unsigned char cmd[MAX_COMMAND_SIZE];
1032 struct osst_request * SRpnt; 1032 struct osst_request * SRpnt;
1033 int retval = 0; 1033 int retval = 0;
1034 #if DEBUG 1034 #if DEBUG
1035 os_aux_t * aux = STp->buffer->aux; 1035 os_aux_t * aux = STp->buffer->aux;
1036 char * name = tape_name(STp); 1036 char * name = tape_name(STp);
1037 #endif 1037 #endif
1038 1038
1039 if (STp->poll) 1039 if (STp->poll)
1040 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout)) 1040 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
1041 retval = osst_recover_wait_frame(STp, aSRpnt, 0); 1041 retval = osst_recover_wait_frame(STp, aSRpnt, 0);
1042 1042
1043 memset(cmd, 0, MAX_COMMAND_SIZE); 1043 memset(cmd, 0, MAX_COMMAND_SIZE);
1044 cmd[0] = READ_6; 1044 cmd[0] = READ_6;
1045 cmd[1] = 1; 1045 cmd[1] = 1;
1046 cmd[4] = 1; 1046 cmd[4] = 1;
1047 1047
1048 #if DEBUG 1048 #if DEBUG
1049 if (debugging) 1049 if (debugging)
1050 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name); 1050 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
1051 #endif 1051 #endif
1052 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE, 1052 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1053 STp->timeout, MAX_RETRIES, 1); 1053 STp->timeout, MAX_RETRIES, 1);
1054 *aSRpnt = SRpnt; 1054 *aSRpnt = SRpnt;
1055 if (!SRpnt) 1055 if (!SRpnt)
1056 return (-EBUSY); 1056 return (-EBUSY);
1057 1057
1058 if ((STp->buffer)->syscall_result) { 1058 if ((STp->buffer)->syscall_result) {
1059 retval = 1; 1059 retval = 1;
1060 if (STp->read_error_frame == 0) { 1060 if (STp->read_error_frame == 0) {
1061 STp->read_error_frame = STp->first_frame_position; 1061 STp->read_error_frame = STp->first_frame_position;
1062 #if DEBUG 1062 #if DEBUG
1063 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame); 1063 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
1064 #endif 1064 #endif
1065 } 1065 }
1066 #if DEBUG 1066 #if DEBUG
1067 if (debugging) 1067 if (debugging)
1068 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", 1068 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1069 name, 1069 name,
1070 SRpnt->sense[0], SRpnt->sense[1], 1070 SRpnt->sense[0], SRpnt->sense[1],
1071 SRpnt->sense[2], SRpnt->sense[3], 1071 SRpnt->sense[2], SRpnt->sense[3],
1072 SRpnt->sense[4], SRpnt->sense[5], 1072 SRpnt->sense[4], SRpnt->sense[5],
1073 SRpnt->sense[6], SRpnt->sense[7]); 1073 SRpnt->sense[6], SRpnt->sense[7]);
1074 #endif 1074 #endif
1075 } 1075 }
1076 else 1076 else
1077 STp->first_frame_position++; 1077 STp->first_frame_position++;
1078 #if DEBUG 1078 #if DEBUG
1079 if (debugging) { 1079 if (debugging) {
1080 char sig[8]; int i; 1080 char sig[8]; int i;
1081 for (i=0;i<4;i++) 1081 for (i=0;i<4;i++)
1082 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i]; 1082 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
1083 sig[4] = '\0'; 1083 sig[4] = '\0';
1084 printk(OSST_DEB_MSG 1084 printk(OSST_DEB_MSG
1085 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig, 1085 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
1086 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr), 1086 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
1087 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK": 1087 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
1088 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL", 1088 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
1089 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num), 1089 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
1090 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) ); 1090 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
1091 if (aux->frame_type==2) 1091 if (aux->frame_type==2)
1092 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name, 1092 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
1093 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn)); 1093 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
1094 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval); 1094 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
1095 } 1095 }
1096 #endif 1096 #endif
1097 return (retval); 1097 return (retval);
1098 } 1098 }
1099 1099
1100 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt) 1100 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
1101 { 1101 {
1102 struct st_partstat * STps = &(STp->ps[STp->partition]); 1102 struct st_partstat * STps = &(STp->ps[STp->partition]);
1103 struct osst_request * SRpnt ; 1103 struct osst_request * SRpnt ;
1104 unsigned char cmd[MAX_COMMAND_SIZE]; 1104 unsigned char cmd[MAX_COMMAND_SIZE];
1105 int retval = 0; 1105 int retval = 0;
1106 char * name = tape_name(STp); 1106 char * name = tape_name(STp);
1107 1107
1108 if (STps->rw != ST_READING) { /* Initialize read operation */ 1108 if (STps->rw != ST_READING) { /* Initialize read operation */
1109 if (STps->rw == ST_WRITING || STp->dirty) { 1109 if (STps->rw == ST_WRITING || STp->dirty) {
1110 STp->write_type = OS_WRITE_DATA; 1110 STp->write_type = OS_WRITE_DATA;
1111 osst_flush_write_buffer(STp, aSRpnt); 1111 osst_flush_write_buffer(STp, aSRpnt);
1112 osst_flush_drive_buffer(STp, aSRpnt); 1112 osst_flush_drive_buffer(STp, aSRpnt);
1113 } 1113 }
1114 STps->rw = ST_READING; 1114 STps->rw = ST_READING;
1115 STp->frame_in_buffer = 0; 1115 STp->frame_in_buffer = 0;
1116 1116
1117 /* 1117 /*
1118 * Issue a read 0 command to get the OnStream drive 1118 * Issue a read 0 command to get the OnStream drive
1119 * read frames into its buffer. 1119 * read frames into its buffer.
1120 */ 1120 */
1121 memset(cmd, 0, MAX_COMMAND_SIZE); 1121 memset(cmd, 0, MAX_COMMAND_SIZE);
1122 cmd[0] = READ_6; 1122 cmd[0] = READ_6;
1123 cmd[1] = 1; 1123 cmd[1] = 1;
1124 1124
1125 #if DEBUG 1125 #if DEBUG
1126 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name); 1126 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
1127 #endif 1127 #endif
1128 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 1128 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
1129 *aSRpnt = SRpnt; 1129 *aSRpnt = SRpnt;
1130 if ((retval = STp->buffer->syscall_result)) 1130 if ((retval = STp->buffer->syscall_result))
1131 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name); 1131 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
1132 } 1132 }
1133 1133
1134 return retval; 1134 return retval;
1135 } 1135 }
1136 1136
1137 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, 1137 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt,
1138 int frame_seq_number, int quiet) 1138 int frame_seq_number, int quiet)
1139 { 1139 {
1140 struct st_partstat * STps = &(STp->ps[STp->partition]); 1140 struct st_partstat * STps = &(STp->ps[STp->partition]);
1141 char * name = tape_name(STp); 1141 char * name = tape_name(STp);
1142 int cnt = 0, 1142 int cnt = 0,
1143 bad = 0, 1143 bad = 0,
1144 past = 0, 1144 past = 0,
1145 x, 1145 x,
1146 position; 1146 position;
1147 1147
1148 /* 1148 /*
1149 * If we want just any frame (-1) and there is a frame in the buffer, return it 1149 * If we want just any frame (-1) and there is a frame in the buffer, return it
1150 */ 1150 */
1151 if (frame_seq_number == -1 && STp->frame_in_buffer) { 1151 if (frame_seq_number == -1 && STp->frame_in_buffer) {
1152 #if DEBUG 1152 #if DEBUG
1153 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number); 1153 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1154 #endif 1154 #endif
1155 return (STps->eof); 1155 return (STps->eof);
1156 } 1156 }
1157 /* 1157 /*
1158 * Search and wait for the next logical tape frame 1158 * Search and wait for the next logical tape frame
1159 */ 1159 */
1160 while (1) { 1160 while (1) {
1161 if (cnt++ > 400) { 1161 if (cnt++ > 400) {
1162 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n", 1162 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1163 name, frame_seq_number); 1163 name, frame_seq_number);
1164 if (STp->read_error_frame) { 1164 if (STp->read_error_frame) {
1165 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0); 1165 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1166 #if DEBUG 1166 #if DEBUG
1167 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n", 1167 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1168 name, STp->read_error_frame); 1168 name, STp->read_error_frame);
1169 #endif 1169 #endif
1170 STp->read_error_frame = 0; 1170 STp->read_error_frame = 0;
1171 STp->abort_count++; 1171 STp->abort_count++;
1172 } 1172 }
1173 return (-EIO); 1173 return (-EIO);
1174 } 1174 }
1175 #if DEBUG 1175 #if DEBUG
1176 if (debugging) 1176 if (debugging)
1177 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n", 1177 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1178 name, frame_seq_number, cnt); 1178 name, frame_seq_number, cnt);
1179 #endif 1179 #endif
1180 if ( osst_initiate_read(STp, aSRpnt) 1180 if ( osst_initiate_read(STp, aSRpnt)
1181 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) { 1181 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1182 if (STp->raw) 1182 if (STp->raw)
1183 return (-EIO); 1183 return (-EIO);
1184 position = osst_get_frame_position(STp, aSRpnt); 1184 position = osst_get_frame_position(STp, aSRpnt);
1185 if (position >= 0xbae && position < 0xbb8) 1185 if (position >= 0xbae && position < 0xbb8)
1186 position = 0xbb8; 1186 position = 0xbb8;
1187 else if (position > STp->eod_frame_ppos || ++bad == 10) { 1187 else if (position > STp->eod_frame_ppos || ++bad == 10) {
1188 position = STp->read_error_frame - 1; 1188 position = STp->read_error_frame - 1;
1189 bad = 0; 1189 bad = 0;
1190 } 1190 }
1191 else { 1191 else {
1192 position += 29; 1192 position += 29;
1193 cnt += 19; 1193 cnt += 19;
1194 } 1194 }
1195 #if DEBUG 1195 #if DEBUG
1196 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n", 1196 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1197 name, position); 1197 name, position);
1198 #endif 1198 #endif
1199 osst_set_frame_position(STp, aSRpnt, position, 0); 1199 osst_set_frame_position(STp, aSRpnt, position, 0);
1200 continue; 1200 continue;
1201 } 1201 }
1202 if (osst_verify_frame(STp, frame_seq_number, quiet)) 1202 if (osst_verify_frame(STp, frame_seq_number, quiet))
1203 break; 1203 break;
1204 if (osst_verify_frame(STp, -1, quiet)) { 1204 if (osst_verify_frame(STp, -1, quiet)) {
1205 x = ntohl(STp->buffer->aux->frame_seq_num); 1205 x = ntohl(STp->buffer->aux->frame_seq_num);
1206 if (STp->fast_open) { 1206 if (STp->fast_open) {
1207 printk(KERN_WARNING 1207 printk(KERN_WARNING
1208 "%s:W: Found logical frame %d instead of %d after fast open\n", 1208 "%s:W: Found logical frame %d instead of %d after fast open\n",
1209 name, x, frame_seq_number); 1209 name, x, frame_seq_number);
1210 STp->header_ok = 0; 1210 STp->header_ok = 0;
1211 STp->read_error_frame = 0; 1211 STp->read_error_frame = 0;
1212 return (-EIO); 1212 return (-EIO);
1213 } 1213 }
1214 if (x > frame_seq_number) { 1214 if (x > frame_seq_number) {
1215 if (++past > 3) { 1215 if (++past > 3) {
1216 /* positioning backwards did not bring us to the desired frame */ 1216 /* positioning backwards did not bring us to the desired frame */
1217 position = STp->read_error_frame - 1; 1217 position = STp->read_error_frame - 1;
1218 } 1218 }
1219 else { 1219 else {
1220 position = osst_get_frame_position(STp, aSRpnt) 1220 position = osst_get_frame_position(STp, aSRpnt)
1221 + frame_seq_number - x - 1; 1221 + frame_seq_number - x - 1;
1222 1222
1223 if (STp->first_frame_position >= 3000 && position < 3000) 1223 if (STp->first_frame_position >= 3000 && position < 3000)
1224 position -= 10; 1224 position -= 10;
1225 } 1225 }
1226 #if DEBUG 1226 #if DEBUG
1227 printk(OSST_DEB_MSG 1227 printk(OSST_DEB_MSG
1228 "%s:D: Found logical frame %d while looking for %d: back up %d\n", 1228 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1229 name, x, frame_seq_number, 1229 name, x, frame_seq_number,
1230 STp->first_frame_position - position); 1230 STp->first_frame_position - position);
1231 #endif 1231 #endif
1232 osst_set_frame_position(STp, aSRpnt, position, 0); 1232 osst_set_frame_position(STp, aSRpnt, position, 0);
1233 cnt += 10; 1233 cnt += 10;
1234 } 1234 }
1235 else 1235 else
1236 past = 0; 1236 past = 0;
1237 } 1237 }
1238 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) { 1238 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1239 #if DEBUG 1239 #if DEBUG
1240 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name); 1240 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1241 #endif 1241 #endif
1242 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0); 1242 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1243 cnt--; 1243 cnt--;
1244 } 1244 }
1245 STp->frame_in_buffer = 0; 1245 STp->frame_in_buffer = 0;
1246 } 1246 }
1247 if (cnt > 1) { 1247 if (cnt > 1) {
1248 STp->recover_count++; 1248 STp->recover_count++;
1249 STp->recover_erreg++; 1249 STp->recover_erreg++;
1250 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n", 1250 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1251 name, STp->read_error_frame); 1251 name, STp->read_error_frame);
1252 } 1252 }
1253 STp->read_count++; 1253 STp->read_count++;
1254 1254
1255 #if DEBUG 1255 #if DEBUG
1256 if (debugging || STps->eof) 1256 if (debugging || STps->eof)
1257 printk(OSST_DEB_MSG 1257 printk(OSST_DEB_MSG
1258 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n", 1258 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1259 name, frame_seq_number, STp->frame_seq_number, STps->eof); 1259 name, frame_seq_number, STp->frame_seq_number, STps->eof);
1260 #endif 1260 #endif
1261 STp->fast_open = 0; 1261 STp->fast_open = 0;
1262 STp->read_error_frame = 0; 1262 STp->read_error_frame = 0;
1263 return (STps->eof); 1263 return (STps->eof);
1264 } 1264 }
1265 1265
1266 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num) 1266 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num)
1267 { 1267 {
1268 struct st_partstat * STps = &(STp->ps[STp->partition]); 1268 struct st_partstat * STps = &(STp->ps[STp->partition]);
1269 char * name = tape_name(STp); 1269 char * name = tape_name(STp);
1270 int retries = 0; 1270 int retries = 0;
1271 int frame_seq_estimate, ppos_estimate, move; 1271 int frame_seq_estimate, ppos_estimate, move;
1272 1272
1273 if (logical_blk_num < 0) logical_blk_num = 0; 1273 if (logical_blk_num < 0) logical_blk_num = 0;
1274 #if DEBUG 1274 #if DEBUG
1275 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n", 1275 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1276 name, logical_blk_num, STp->logical_blk_num, 1276 name, logical_blk_num, STp->logical_blk_num,
1277 STp->block_size<1024?STp->block_size:STp->block_size/1024, 1277 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1278 STp->block_size<1024?'b':'k'); 1278 STp->block_size<1024?'b':'k');
1279 #endif 1279 #endif
1280 /* Do we know where we are? */ 1280 /* Do we know where we are? */
1281 if (STps->drv_block >= 0) { 1281 if (STps->drv_block >= 0) {
1282 move = logical_blk_num - STp->logical_blk_num; 1282 move = logical_blk_num - STp->logical_blk_num;
1283 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; 1283 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1284 move /= (OS_DATA_SIZE / STp->block_size); 1284 move /= (OS_DATA_SIZE / STp->block_size);
1285 frame_seq_estimate = STp->frame_seq_number + move; 1285 frame_seq_estimate = STp->frame_seq_number + move;
1286 } else 1286 } else
1287 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE; 1287 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1288 1288
1289 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10; 1289 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1290 else ppos_estimate = frame_seq_estimate + 20; 1290 else ppos_estimate = frame_seq_estimate + 20;
1291 while (++retries < 10) { 1291 while (++retries < 10) {
1292 if (ppos_estimate > STp->eod_frame_ppos-2) { 1292 if (ppos_estimate > STp->eod_frame_ppos-2) {
1293 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate; 1293 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1294 ppos_estimate = STp->eod_frame_ppos - 2; 1294 ppos_estimate = STp->eod_frame_ppos - 2;
1295 } 1295 }
1296 if (frame_seq_estimate < 0) { 1296 if (frame_seq_estimate < 0) {
1297 frame_seq_estimate = 0; 1297 frame_seq_estimate = 0;
1298 ppos_estimate = 10; 1298 ppos_estimate = 10;
1299 } 1299 }
1300 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0); 1300 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1301 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) { 1301 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1302 /* we've located the estimated frame, now does it have our block? */ 1302 /* we've located the estimated frame, now does it have our block? */
1303 if (logical_blk_num < STp->logical_blk_num || 1303 if (logical_blk_num < STp->logical_blk_num ||
1304 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) { 1304 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1305 if (STps->eof == ST_FM_HIT) 1305 if (STps->eof == ST_FM_HIT)
1306 move = logical_blk_num < STp->logical_blk_num? -2 : 1; 1306 move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1307 else { 1307 else {
1308 move = logical_blk_num - STp->logical_blk_num; 1308 move = logical_blk_num - STp->logical_blk_num;
1309 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; 1309 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1310 move /= (OS_DATA_SIZE / STp->block_size); 1310 move /= (OS_DATA_SIZE / STp->block_size);
1311 } 1311 }
1312 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1; 1312 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1313 #if DEBUG 1313 #if DEBUG
1314 printk(OSST_DEB_MSG 1314 printk(OSST_DEB_MSG
1315 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n", 1315 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1316 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 1316 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1317 STp->logical_blk_num, logical_blk_num, move); 1317 STp->logical_blk_num, logical_blk_num, move);
1318 #endif 1318 #endif
1319 frame_seq_estimate += move; 1319 frame_seq_estimate += move;
1320 ppos_estimate += move; 1320 ppos_estimate += move;
1321 continue; 1321 continue;
1322 } else { 1322 } else {
1323 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size; 1323 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1324 STp->buffer->buffer_bytes -= STp->buffer->read_pointer; 1324 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1325 STp->logical_blk_num = logical_blk_num; 1325 STp->logical_blk_num = logical_blk_num;
1326 #if DEBUG 1326 #if DEBUG
1327 printk(OSST_DEB_MSG 1327 printk(OSST_DEB_MSG
1328 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n", 1328 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1329 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer, 1329 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1330 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size, 1330 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1331 STp->block_size); 1331 STp->block_size);
1332 #endif 1332 #endif
1333 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt); 1333 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1334 if (STps->eof == ST_FM_HIT) { 1334 if (STps->eof == ST_FM_HIT) {
1335 STps->drv_file++; 1335 STps->drv_file++;
1336 STps->drv_block = 0; 1336 STps->drv_block = 0;
1337 } else { 1337 } else {
1338 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)? 1338 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1339 STp->logical_blk_num - 1339 STp->logical_blk_num -
1340 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0): 1340 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1341 -1; 1341 -1;
1342 } 1342 }
1343 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF; 1343 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1344 return 0; 1344 return 0;
1345 } 1345 }
1346 } 1346 }
1347 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0) 1347 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1348 goto error; 1348 goto error;
1349 /* we are not yet at the estimated frame, adjust our estimate of its physical position */ 1349 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1350 #if DEBUG 1350 #if DEBUG
1351 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n", 1351 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1352 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 1352 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1353 STp->logical_blk_num, logical_blk_num); 1353 STp->logical_blk_num, logical_blk_num);
1354 #endif 1354 #endif
1355 if (frame_seq_estimate != STp->frame_seq_number) 1355 if (frame_seq_estimate != STp->frame_seq_number)
1356 ppos_estimate += frame_seq_estimate - STp->frame_seq_number; 1356 ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1357 else 1357 else
1358 break; 1358 break;
1359 } 1359 }
1360 error: 1360 error:
1361 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n", 1361 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1362 name, logical_blk_num, STp->logical_blk_num, retries); 1362 name, logical_blk_num, STp->logical_blk_num, retries);
1363 return (-EIO); 1363 return (-EIO);
1364 } 1364 }
1365 1365
1366 /* The values below are based on the OnStream frame payload size of 32K == 2**15, 1366 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1367 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block 1367 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1368 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions 1368 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1369 * inside each frame. Finally, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1. 1369 * inside each frame. Finally, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1370 */ 1370 */
1371 #define OSST_FRAME_SHIFT 6 1371 #define OSST_FRAME_SHIFT 6
1372 #define OSST_SECTOR_SHIFT 9 1372 #define OSST_SECTOR_SHIFT 9
1373 #define OSST_SECTOR_MASK 0x03F 1373 #define OSST_SECTOR_MASK 0x03F
1374 1374
1375 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt) 1375 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt)
1376 { 1376 {
1377 int sector; 1377 int sector;
1378 #if DEBUG 1378 #if DEBUG
1379 char * name = tape_name(STp); 1379 char * name = tape_name(STp);
1380 1380
1381 printk(OSST_DEB_MSG 1381 printk(OSST_DEB_MSG
1382 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n", 1382 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1383 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num, 1383 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1384 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block, 1384 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1385 STp->ps[STp->partition].rw == ST_WRITING?'w':'r', 1385 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1386 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes: 1386 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1387 STp->buffer->read_pointer, STp->ps[STp->partition].eof); 1387 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1388 #endif 1388 #endif
1389 /* do we know where we are inside a file? */ 1389 /* do we know where we are inside a file? */
1390 if (STp->ps[STp->partition].drv_block >= 0) { 1390 if (STp->ps[STp->partition].drv_block >= 0) {
1391 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 : 1391 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1392 STp->first_frame_position) << OSST_FRAME_SHIFT; 1392 STp->first_frame_position) << OSST_FRAME_SHIFT;
1393 if (STp->ps[STp->partition].rw == ST_WRITING) 1393 if (STp->ps[STp->partition].rw == ST_WRITING)
1394 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK; 1394 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1395 else 1395 else
1396 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK; 1396 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1397 } else { 1397 } else {
1398 sector = osst_get_frame_position(STp, aSRpnt); 1398 sector = osst_get_frame_position(STp, aSRpnt);
1399 if (sector > 0) 1399 if (sector > 0)
1400 sector <<= OSST_FRAME_SHIFT; 1400 sector <<= OSST_FRAME_SHIFT;
1401 } 1401 }
1402 return sector; 1402 return sector;
1403 } 1403 }
1404 1404
1405 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector) 1405 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector)
1406 { 1406 {
1407 struct st_partstat * STps = &(STp->ps[STp->partition]); 1407 struct st_partstat * STps = &(STp->ps[STp->partition]);
1408 int frame = sector >> OSST_FRAME_SHIFT, 1408 int frame = sector >> OSST_FRAME_SHIFT,
1409 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 1409 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1410 r; 1410 r;
1411 #if DEBUG 1411 #if DEBUG
1412 char * name = tape_name(STp); 1412 char * name = tape_name(STp);
1413 1413
1414 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n", 1414 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1415 name, sector, frame, offset); 1415 name, sector, frame, offset);
1416 #endif 1416 #endif
1417 if (frame < 0 || frame >= STp->capacity) return (-ENXIO); 1417 if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1418 1418
1419 if (frame <= STp->first_data_ppos) { 1419 if (frame <= STp->first_data_ppos) {
1420 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0; 1420 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1421 return (osst_set_frame_position(STp, aSRpnt, frame, 0)); 1421 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1422 } 1422 }
1423 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0); 1423 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1424 if (r < 0) return r; 1424 if (r < 0) return r;
1425 1425
1426 r = osst_get_logical_frame(STp, aSRpnt, -1, 1); 1426 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1427 if (r < 0) return r; 1427 if (r < 0) return r;
1428 1428
1429 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO); 1429 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1430 1430
1431 if (offset) { 1431 if (offset) {
1432 STp->logical_blk_num += offset / STp->block_size; 1432 STp->logical_blk_num += offset / STp->block_size;
1433 STp->buffer->read_pointer = offset; 1433 STp->buffer->read_pointer = offset;
1434 STp->buffer->buffer_bytes -= offset; 1434 STp->buffer->buffer_bytes -= offset;
1435 } else { 1435 } else {
1436 STp->frame_seq_number++; 1436 STp->frame_seq_number++;
1437 STp->frame_in_buffer = 0; 1437 STp->frame_in_buffer = 0;
1438 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1438 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1439 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0; 1439 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1440 } 1440 }
1441 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt); 1441 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1442 if (STps->eof == ST_FM_HIT) { 1442 if (STps->eof == ST_FM_HIT) {
1443 STps->drv_file++; 1443 STps->drv_file++;
1444 STps->drv_block = 0; 1444 STps->drv_block = 0;
1445 } else { 1445 } else {
1446 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)? 1446 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1447 STp->logical_blk_num - 1447 STp->logical_blk_num -
1448 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0): 1448 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1449 -1; 1449 -1;
1450 } 1450 }
1451 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF; 1451 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1452 #if DEBUG 1452 #if DEBUG
1453 printk(OSST_DEB_MSG 1453 printk(OSST_DEB_MSG
1454 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n", 1454 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1455 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num, 1455 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1456 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof); 1456 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1457 #endif 1457 #endif
1458 return 0; 1458 return 0;
1459 } 1459 }
1460 1460
1461 /* 1461 /*
1462 * Read back the drive's internal buffer contents, as a part 1462 * Read back the drive's internal buffer contents, as a part
1463 * of the write error recovery mechanism for old OnStream 1463 * of the write error recovery mechanism for old OnStream
1464 * firmware revisions. 1464 * firmware revisions.
1465 * Precondition for this function to work: all frames in the 1465 * Precondition for this function to work: all frames in the
1466 * drive's buffer must be of one type (DATA, MARK or EOD)! 1466 * drive's buffer must be of one type (DATA, MARK or EOD)!
1467 */ 1467 */
1468 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt, 1468 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
1469 unsigned int frame, unsigned int skip, int pending) 1469 unsigned int frame, unsigned int skip, int pending)
1470 { 1470 {
1471 struct osst_request * SRpnt = * aSRpnt; 1471 struct osst_request * SRpnt = * aSRpnt;
1472 unsigned char * buffer, * p; 1472 unsigned char * buffer, * p;
1473 unsigned char cmd[MAX_COMMAND_SIZE]; 1473 unsigned char cmd[MAX_COMMAND_SIZE];
1474 int flag, new_frame, i; 1474 int flag, new_frame, i;
1475 int nframes = STp->cur_frames; 1475 int nframes = STp->cur_frames;
1476 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1476 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1477 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num) 1477 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1478 - (nframes + pending - 1); 1478 - (nframes + pending - 1);
1479 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num) 1479 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1480 - (nframes + pending - 1) * blks_per_frame; 1480 - (nframes + pending - 1) * blks_per_frame;
1481 char * name = tape_name(STp); 1481 char * name = tape_name(STp);
1482 unsigned long startwait = jiffies; 1482 unsigned long startwait = jiffies;
1483 #if DEBUG 1483 #if DEBUG
1484 int dbg = debugging; 1484 int dbg = debugging;
1485 #endif 1485 #endif
1486 1486
1487 if ((buffer = vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL) 1487 if ((buffer = vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
1488 return (-EIO); 1488 return (-EIO);
1489 1489
1490 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n", 1490 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1491 name, nframes, pending?" and one that was pending":""); 1491 name, nframes, pending?" and one that was pending":"");
1492 1492
1493 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE])); 1493 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1494 #if DEBUG 1494 #if DEBUG
1495 if (pending && debugging) 1495 if (pending && debugging)
1496 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n", 1496 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1497 name, frame_seq_number + nframes, 1497 name, frame_seq_number + nframes,
1498 logical_blk_num + nframes * blks_per_frame, 1498 logical_blk_num + nframes * blks_per_frame,
1499 p[0], p[1], p[2], p[3]); 1499 p[0], p[1], p[2], p[3]);
1500 #endif 1500 #endif
1501 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) { 1501 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1502 1502
1503 memset(cmd, 0, MAX_COMMAND_SIZE); 1503 memset(cmd, 0, MAX_COMMAND_SIZE);
1504 cmd[0] = 0x3C; /* Buffer Read */ 1504 cmd[0] = 0x3C; /* Buffer Read */
1505 cmd[1] = 6; /* Retrieve Faulty Block */ 1505 cmd[1] = 6; /* Retrieve Faulty Block */
1506 cmd[7] = 32768 >> 8; 1506 cmd[7] = 32768 >> 8;
1507 cmd[8] = 32768 & 0xff; 1507 cmd[8] = 32768 & 0xff;
1508 1508
1509 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE, 1509 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1510 STp->timeout, MAX_RETRIES, 1); 1510 STp->timeout, MAX_RETRIES, 1);
1511 1511
1512 if ((STp->buffer)->syscall_result || !SRpnt) { 1512 if ((STp->buffer)->syscall_result || !SRpnt) {
1513 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name); 1513 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1514 vfree(buffer); 1514 vfree(buffer);
1515 *aSRpnt = SRpnt; 1515 *aSRpnt = SRpnt;
1516 return (-EIO); 1516 return (-EIO);
1517 } 1517 }
1518 osst_copy_from_buffer(STp->buffer, p); 1518 osst_copy_from_buffer(STp->buffer, p);
1519 #if DEBUG 1519 #if DEBUG
1520 if (debugging) 1520 if (debugging)
1521 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n", 1521 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1522 name, frame_seq_number + i, p[0], p[1], p[2], p[3]); 1522 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1523 #endif 1523 #endif
1524 } 1524 }
1525 *aSRpnt = SRpnt; 1525 *aSRpnt = SRpnt;
1526 osst_get_frame_position(STp, aSRpnt); 1526 osst_get_frame_position(STp, aSRpnt);
1527 1527
1528 #if DEBUG 1528 #if DEBUG
1529 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames); 1529 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1530 #endif 1530 #endif
1531 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */ 1531 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1532 /* In the header we don't actually re-write the frames that fail, just the ones after them */ 1532 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1533 1533
1534 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) { 1534 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1535 1535
1536 if (flag) { 1536 if (flag) {
1537 if (STp->write_type == OS_WRITE_HEADER) { 1537 if (STp->write_type == OS_WRITE_HEADER) {
1538 i += skip; 1538 i += skip;
1539 p += skip * OS_DATA_SIZE; 1539 p += skip * OS_DATA_SIZE;
1540 } 1540 }
1541 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990) 1541 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1542 new_frame = 3000-i; 1542 new_frame = 3000-i;
1543 else 1543 else
1544 new_frame += skip; 1544 new_frame += skip;
1545 #if DEBUG 1545 #if DEBUG
1546 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n", 1546 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1547 name, new_frame+i, frame_seq_number+i); 1547 name, new_frame+i, frame_seq_number+i);
1548 #endif 1548 #endif
1549 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0); 1549 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1550 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE); 1550 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1551 osst_get_frame_position(STp, aSRpnt); 1551 osst_get_frame_position(STp, aSRpnt);
1552 SRpnt = * aSRpnt; 1552 SRpnt = * aSRpnt;
1553 1553
1554 if (new_frame > frame + 1000) { 1554 if (new_frame > frame + 1000) {
1555 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name); 1555 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1556 vfree(buffer); 1556 vfree(buffer);
1557 return (-EIO); 1557 return (-EIO);
1558 } 1558 }
1559 if ( i >= nframes + pending ) break; 1559 if ( i >= nframes + pending ) break;
1560 flag = 0; 1560 flag = 0;
1561 } 1561 }
1562 osst_copy_to_buffer(STp->buffer, p); 1562 osst_copy_to_buffer(STp->buffer, p);
1563 /* 1563 /*
1564 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type! 1564 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1565 */ 1565 */
1566 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i, 1566 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1567 logical_blk_num + i*blks_per_frame, 1567 logical_blk_num + i*blks_per_frame,
1568 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame); 1568 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1569 memset(cmd, 0, MAX_COMMAND_SIZE); 1569 memset(cmd, 0, MAX_COMMAND_SIZE);
1570 cmd[0] = WRITE_6; 1570 cmd[0] = WRITE_6;
1571 cmd[1] = 1; 1571 cmd[1] = 1;
1572 cmd[4] = 1; 1572 cmd[4] = 1;
1573 1573
1574 #if DEBUG 1574 #if DEBUG
1575 if (debugging) 1575 if (debugging)
1576 printk(OSST_DEB_MSG 1576 printk(OSST_DEB_MSG
1577 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n", 1577 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1578 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame, 1578 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1579 p[0], p[1], p[2], p[3]); 1579 p[0], p[1], p[2], p[3]);
1580 #endif 1580 #endif
1581 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, 1581 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1582 STp->timeout, MAX_RETRIES, 1); 1582 STp->timeout, MAX_RETRIES, 1);
1583 1583
1584 if (STp->buffer->syscall_result) 1584 if (STp->buffer->syscall_result)
1585 flag = 1; 1585 flag = 1;
1586 else { 1586 else {
1587 p += OS_DATA_SIZE; i++; 1587 p += OS_DATA_SIZE; i++;
1588 1588
1589 /* if we just sent the last frame, wait till all successfully written */ 1589 /* if we just sent the last frame, wait till all successfully written */
1590 if ( i == nframes + pending ) { 1590 if ( i == nframes + pending ) {
1591 #if DEBUG 1591 #if DEBUG
1592 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name); 1592 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1593 #endif 1593 #endif
1594 memset(cmd, 0, MAX_COMMAND_SIZE); 1594 memset(cmd, 0, MAX_COMMAND_SIZE);
1595 cmd[0] = WRITE_FILEMARKS; 1595 cmd[0] = WRITE_FILEMARKS;
1596 cmd[1] = 1; 1596 cmd[1] = 1;
1597 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, 1597 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1598 STp->timeout, MAX_RETRIES, 1); 1598 STp->timeout, MAX_RETRIES, 1);
1599 #if DEBUG 1599 #if DEBUG
1600 if (debugging) { 1600 if (debugging) {
1601 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name); 1601 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1602 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 1602 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1603 debugging = 0; 1603 debugging = 0;
1604 } 1604 }
1605 #endif 1605 #endif
1606 flag = STp->buffer->syscall_result; 1606 flag = STp->buffer->syscall_result;
1607 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) { 1607 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1608 1608
1609 memset(cmd, 0, MAX_COMMAND_SIZE); 1609 memset(cmd, 0, MAX_COMMAND_SIZE);
1610 cmd[0] = TEST_UNIT_READY; 1610 cmd[0] = TEST_UNIT_READY;
1611 1611
1612 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, 1612 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1613 MAX_RETRIES, 1); 1613 MAX_RETRIES, 1);
1614 1614
1615 if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 && 1615 if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
1616 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) { 1616 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
1617 /* in the process of becoming ready */ 1617 /* in the process of becoming ready */
1618 msleep(100); 1618 msleep(100);
1619 continue; 1619 continue;
1620 } 1620 }
1621 if (STp->buffer->syscall_result) 1621 if (STp->buffer->syscall_result)
1622 flag = 1; 1622 flag = 1;
1623 break; 1623 break;
1624 } 1624 }
1625 #if DEBUG 1625 #if DEBUG
1626 debugging = dbg; 1626 debugging = dbg;
1627 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name); 1627 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1628 #endif 1628 #endif
1629 } 1629 }
1630 } 1630 }
1631 *aSRpnt = SRpnt; 1631 *aSRpnt = SRpnt;
1632 if (flag) { 1632 if (flag) {
1633 if ((SRpnt->sense[ 2] & 0x0f) == 13 && 1633 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1634 SRpnt->sense[12] == 0 && 1634 SRpnt->sense[12] == 0 &&
1635 SRpnt->sense[13] == 2) { 1635 SRpnt->sense[13] == 2) {
1636 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name); 1636 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1637 vfree(buffer); 1637 vfree(buffer);
1638 return (-EIO); /* hit end of tape = fail */ 1638 return (-EIO); /* hit end of tape = fail */
1639 } 1639 }
1640 i = ((SRpnt->sense[3] << 24) | 1640 i = ((SRpnt->sense[3] << 24) |
1641 (SRpnt->sense[4] << 16) | 1641 (SRpnt->sense[4] << 16) |
1642 (SRpnt->sense[5] << 8) | 1642 (SRpnt->sense[5] << 8) |
1643 SRpnt->sense[6] ) - new_frame; 1643 SRpnt->sense[6] ) - new_frame;
1644 p = &buffer[i * OS_DATA_SIZE]; 1644 p = &buffer[i * OS_DATA_SIZE];
1645 #if DEBUG 1645 #if DEBUG
1646 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i); 1646 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1647 #endif 1647 #endif
1648 osst_get_frame_position(STp, aSRpnt); 1648 osst_get_frame_position(STp, aSRpnt);
1649 #if DEBUG 1649 #if DEBUG
1650 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n", 1650 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1651 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames); 1651 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1652 #endif 1652 #endif
1653 } 1653 }
1654 } 1654 }
1655 if (flag) { 1655 if (flag) {
1656 /* error recovery did not successfully complete */ 1656 /* error recovery did not successfully complete */
1657 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name, 1657 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1658 STp->write_type == OS_WRITE_HEADER?"header":"body"); 1658 STp->write_type == OS_WRITE_HEADER?"header":"body");
1659 } 1659 }
1660 if (!pending) 1660 if (!pending)
1661 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */ 1661 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1662 vfree(buffer); 1662 vfree(buffer);
1663 return 0; 1663 return 0;
1664 } 1664 }
1665 1665
1666 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt, 1666 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
1667 unsigned int frame, unsigned int skip, int pending) 1667 unsigned int frame, unsigned int skip, int pending)
1668 { 1668 {
1669 unsigned char cmd[MAX_COMMAND_SIZE]; 1669 unsigned char cmd[MAX_COMMAND_SIZE];
1670 struct osst_request * SRpnt; 1670 struct osst_request * SRpnt;
1671 char * name = tape_name(STp); 1671 char * name = tape_name(STp);
1672 int expected = 0; 1672 int expected = 0;
1673 int attempts = 1000 / skip; 1673 int attempts = 1000 / skip;
1674 int flag = 1; 1674 int flag = 1;
1675 unsigned long startwait = jiffies; 1675 unsigned long startwait = jiffies;
1676 #if DEBUG 1676 #if DEBUG
1677 int dbg = debugging; 1677 int dbg = debugging;
1678 #endif 1678 #endif
1679 1679
1680 while (attempts && time_before(jiffies, startwait + 60*HZ)) { 1680 while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1681 if (flag) { 1681 if (flag) {
1682 #if DEBUG 1682 #if DEBUG
1683 debugging = dbg; 1683 debugging = dbg;
1684 #endif 1684 #endif
1685 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990) 1685 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1686 frame = 3000-skip; 1686 frame = 3000-skip;
1687 expected = frame+skip+STp->cur_frames+pending; 1687 expected = frame+skip+STp->cur_frames+pending;
1688 #if DEBUG 1688 #if DEBUG
1689 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n", 1689 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1690 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending); 1690 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1691 #endif 1691 #endif
1692 osst_set_frame_position(STp, aSRpnt, frame + skip, 1); 1692 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1693 flag = 0; 1693 flag = 0;
1694 attempts--; 1694 attempts--;
1695 schedule_timeout_interruptible(msecs_to_jiffies(100)); 1695 schedule_timeout_interruptible(msecs_to_jiffies(100));
1696 } 1696 }
1697 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */ 1697 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1698 #if DEBUG 1698 #if DEBUG
1699 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n", 1699 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1700 name, STp->first_frame_position, 1700 name, STp->first_frame_position,
1701 STp->last_frame_position, STp->cur_frames); 1701 STp->last_frame_position, STp->cur_frames);
1702 #endif 1702 #endif
1703 frame = STp->last_frame_position; 1703 frame = STp->last_frame_position;
1704 flag = 1; 1704 flag = 1;
1705 continue; 1705 continue;
1706 } 1706 }
1707 if (pending && STp->cur_frames < 50) { 1707 if (pending && STp->cur_frames < 50) {
1708 1708
1709 memset(cmd, 0, MAX_COMMAND_SIZE); 1709 memset(cmd, 0, MAX_COMMAND_SIZE);
1710 cmd[0] = WRITE_6; 1710 cmd[0] = WRITE_6;
1711 cmd[1] = 1; 1711 cmd[1] = 1;
1712 cmd[4] = 1; 1712 cmd[4] = 1;
1713 #if DEBUG 1713 #if DEBUG
1714 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n", 1714 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1715 name, STp->frame_seq_number-1, STp->first_frame_position); 1715 name, STp->frame_seq_number-1, STp->first_frame_position);
1716 #endif 1716 #endif
1717 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, 1717 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1718 STp->timeout, MAX_RETRIES, 1); 1718 STp->timeout, MAX_RETRIES, 1);
1719 *aSRpnt = SRpnt; 1719 *aSRpnt = SRpnt;
1720 1720
1721 if (STp->buffer->syscall_result) { /* additional write error */ 1721 if (STp->buffer->syscall_result) { /* additional write error */
1722 if ((SRpnt->sense[ 2] & 0x0f) == 13 && 1722 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1723 SRpnt->sense[12] == 0 && 1723 SRpnt->sense[12] == 0 &&
1724 SRpnt->sense[13] == 2) { 1724 SRpnt->sense[13] == 2) {
1725 printk(KERN_ERR 1725 printk(KERN_ERR
1726 "%s:E: Volume overflow in write error recovery\n", 1726 "%s:E: Volume overflow in write error recovery\n",
1727 name); 1727 name);
1728 break; /* hit end of tape = fail */ 1728 break; /* hit end of tape = fail */
1729 } 1729 }
1730 flag = 1; 1730 flag = 1;
1731 } 1731 }
1732 else 1732 else
1733 pending = 0; 1733 pending = 0;
1734 1734
1735 continue; 1735 continue;
1736 } 1736 }
1737 if (STp->cur_frames == 0) { 1737 if (STp->cur_frames == 0) {
1738 #if DEBUG 1738 #if DEBUG
1739 debugging = dbg; 1739 debugging = dbg;
1740 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name); 1740 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1741 #endif 1741 #endif
1742 if (STp->first_frame_position != expected) { 1742 if (STp->first_frame_position != expected) {
1743 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n", 1743 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1744 name, STp->first_frame_position, expected); 1744 name, STp->first_frame_position, expected);
1745 return (-EIO); 1745 return (-EIO);
1746 } 1746 }
1747 return 0; 1747 return 0;
1748 } 1748 }
1749 #if DEBUG 1749 #if DEBUG
1750 if (debugging) { 1750 if (debugging) {
1751 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name); 1751 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1752 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name); 1752 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1753 debugging = 0; 1753 debugging = 0;
1754 } 1754 }
1755 #endif 1755 #endif
1756 schedule_timeout_interruptible(msecs_to_jiffies(100)); 1756 schedule_timeout_interruptible(msecs_to_jiffies(100));
1757 } 1757 }
1758 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name); 1758 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1759 #if DEBUG 1759 #if DEBUG
1760 debugging = dbg; 1760 debugging = dbg;
1761 #endif 1761 #endif
1762 return (-EIO); 1762 return (-EIO);
1763 } 1763 }
1764 1764
1765 /* 1765 /*
1766 * Error recovery algorithm for the OnStream tape. 1766 * Error recovery algorithm for the OnStream tape.
1767 */ 1767 */
1768 1768
1769 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending) 1769 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending)
1770 { 1770 {
1771 struct osst_request * SRpnt = * aSRpnt; 1771 struct osst_request * SRpnt = * aSRpnt;
1772 struct st_partstat * STps = & STp->ps[STp->partition]; 1772 struct st_partstat * STps = & STp->ps[STp->partition];
1773 char * name = tape_name(STp); 1773 char * name = tape_name(STp);
1774 int retval = 0; 1774 int retval = 0;
1775 int rw_state; 1775 int rw_state;
1776 unsigned int frame, skip; 1776 unsigned int frame, skip;
1777 1777
1778 rw_state = STps->rw; 1778 rw_state = STps->rw;
1779 1779
1780 if ((SRpnt->sense[ 2] & 0x0f) != 3 1780 if ((SRpnt->sense[ 2] & 0x0f) != 3
1781 || SRpnt->sense[12] != 12 1781 || SRpnt->sense[12] != 12
1782 || SRpnt->sense[13] != 0) { 1782 || SRpnt->sense[13] != 0) {
1783 #if DEBUG 1783 #if DEBUG
1784 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name, 1784 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1785 SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]); 1785 SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]);
1786 #endif 1786 #endif
1787 return (-EIO); 1787 return (-EIO);
1788 } 1788 }
1789 frame = (SRpnt->sense[3] << 24) | 1789 frame = (SRpnt->sense[3] << 24) |
1790 (SRpnt->sense[4] << 16) | 1790 (SRpnt->sense[4] << 16) |
1791 (SRpnt->sense[5] << 8) | 1791 (SRpnt->sense[5] << 8) |
1792 SRpnt->sense[6]; 1792 SRpnt->sense[6];
1793 skip = SRpnt->sense[9]; 1793 skip = SRpnt->sense[9];
1794 1794
1795 #if DEBUG 1795 #if DEBUG
1796 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip); 1796 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1797 #endif 1797 #endif
1798 osst_get_frame_position(STp, aSRpnt); 1798 osst_get_frame_position(STp, aSRpnt);
1799 #if DEBUG 1799 #if DEBUG
1800 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n", 1800 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1801 name, STp->first_frame_position, STp->last_frame_position); 1801 name, STp->first_frame_position, STp->last_frame_position);
1802 #endif 1802 #endif
1803 switch (STp->write_type) { 1803 switch (STp->write_type) {
1804 case OS_WRITE_DATA: 1804 case OS_WRITE_DATA:
1805 case OS_WRITE_EOD: 1805 case OS_WRITE_EOD:
1806 case OS_WRITE_NEW_MARK: 1806 case OS_WRITE_NEW_MARK:
1807 printk(KERN_WARNING 1807 printk(KERN_WARNING
1808 "%s:I: Relocating %d buffered logical frames from position %u to %u\n", 1808 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1809 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip); 1809 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1810 if (STp->os_fw_rev >= 10600) 1810 if (STp->os_fw_rev >= 10600)
1811 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending); 1811 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1812 else 1812 else
1813 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending); 1813 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1814 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name, 1814 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1815 retval?"E" :"I", 1815 retval?"E" :"I",
1816 retval?"" :"Don't worry, ", 1816 retval?"" :"Don't worry, ",
1817 retval?" not ":" "); 1817 retval?" not ":" ");
1818 break; 1818 break;
1819 case OS_WRITE_LAST_MARK: 1819 case OS_WRITE_LAST_MARK:
1820 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name); 1820 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1821 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0); 1821 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1822 retval = -EIO; 1822 retval = -EIO;
1823 break; 1823 break;
1824 case OS_WRITE_HEADER: 1824 case OS_WRITE_HEADER:
1825 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name); 1825 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1826 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending); 1826 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1827 break; 1827 break;
1828 default: 1828 default:
1829 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name); 1829 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1830 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0); 1830 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1831 } 1831 }
1832 osst_get_frame_position(STp, aSRpnt); 1832 osst_get_frame_position(STp, aSRpnt);
1833 #if DEBUG 1833 #if DEBUG
1834 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n", 1834 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1835 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position); 1835 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1836 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num); 1836 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1837 #endif 1837 #endif
1838 if (retval == 0) { 1838 if (retval == 0) {
1839 STp->recover_count++; 1839 STp->recover_count++;
1840 STp->recover_erreg++; 1840 STp->recover_erreg++;
1841 } else 1841 } else
1842 STp->abort_count++; 1842 STp->abort_count++;
1843 1843
1844 STps->rw = rw_state; 1844 STps->rw = rw_state;
1845 return retval; 1845 return retval;
1846 } 1846 }
1847 1847
1848 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt, 1848 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt,
1849 int mt_op, int mt_count) 1849 int mt_op, int mt_count)
1850 { 1850 {
1851 char * name = tape_name(STp); 1851 char * name = tape_name(STp);
1852 int cnt; 1852 int cnt;
1853 int last_mark_ppos = -1; 1853 int last_mark_ppos = -1;
1854 1854
1855 #if DEBUG 1855 #if DEBUG
1856 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count); 1856 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1857 #endif 1857 #endif
1858 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1858 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1859 #if DEBUG 1859 #if DEBUG
1860 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name); 1860 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1861 #endif 1861 #endif
1862 return -EIO; 1862 return -EIO;
1863 } 1863 }
1864 if (STp->linux_media_version >= 4) { 1864 if (STp->linux_media_version >= 4) {
1865 /* 1865 /*
1866 * direct lookup in header filemark list 1866 * direct lookup in header filemark list
1867 */ 1867 */
1868 cnt = ntohl(STp->buffer->aux->filemark_cnt); 1868 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1869 if (STp->header_ok && 1869 if (STp->header_ok &&
1870 STp->header_cache != NULL && 1870 STp->header_cache != NULL &&
1871 (cnt - mt_count) >= 0 && 1871 (cnt - mt_count) >= 0 &&
1872 (cnt - mt_count) < OS_FM_TAB_MAX && 1872 (cnt - mt_count) < OS_FM_TAB_MAX &&
1873 (cnt - mt_count) < STp->filemark_cnt && 1873 (cnt - mt_count) < STp->filemark_cnt &&
1874 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos) 1874 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1875 1875
1876 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]); 1876 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1877 #if DEBUG 1877 #if DEBUG
1878 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX) 1878 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1879 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name, 1879 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1880 STp->header_cache == NULL?"lack of header cache":"count out of range"); 1880 STp->header_cache == NULL?"lack of header cache":"count out of range");
1881 else 1881 else
1882 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n", 1882 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1883 name, cnt, 1883 name, cnt,
1884 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || 1884 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1885 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == 1885 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1886 STp->buffer->aux->last_mark_ppos))?"match":"error", 1886 STp->buffer->aux->last_mark_ppos))?"match":"error",
1887 mt_count, last_mark_ppos); 1887 mt_count, last_mark_ppos);
1888 #endif 1888 #endif
1889 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) { 1889 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1890 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos); 1890 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1891 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1891 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1892 #if DEBUG 1892 #if DEBUG
1893 printk(OSST_DEB_MSG 1893 printk(OSST_DEB_MSG
1894 "%s:D: Couldn't get logical blk num in space_filemarks\n", name); 1894 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1895 #endif 1895 #endif
1896 return (-EIO); 1896 return (-EIO);
1897 } 1897 }
1898 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 1898 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1899 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 1899 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1900 name, last_mark_ppos); 1900 name, last_mark_ppos);
1901 return (-EIO); 1901 return (-EIO);
1902 } 1902 }
1903 goto found; 1903 goto found;
1904 } 1904 }
1905 #if DEBUG 1905 #if DEBUG
1906 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name); 1906 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1907 #endif 1907 #endif
1908 } 1908 }
1909 cnt = 0; 1909 cnt = 0;
1910 while (cnt != mt_count) { 1910 while (cnt != mt_count) {
1911 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos); 1911 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1912 if (last_mark_ppos == -1) 1912 if (last_mark_ppos == -1)
1913 return (-EIO); 1913 return (-EIO);
1914 #if DEBUG 1914 #if DEBUG
1915 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos); 1915 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1916 #endif 1916 #endif
1917 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos); 1917 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1918 cnt++; 1918 cnt++;
1919 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1919 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1920 #if DEBUG 1920 #if DEBUG
1921 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name); 1921 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1922 #endif 1922 #endif
1923 return (-EIO); 1923 return (-EIO);
1924 } 1924 }
1925 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 1925 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1926 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 1926 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1927 name, last_mark_ppos); 1927 name, last_mark_ppos);
1928 return (-EIO); 1928 return (-EIO);
1929 } 1929 }
1930 } 1930 }
1931 found: 1931 found:
1932 if (mt_op == MTBSFM) { 1932 if (mt_op == MTBSFM) {
1933 STp->frame_seq_number++; 1933 STp->frame_seq_number++;
1934 STp->frame_in_buffer = 0; 1934 STp->frame_in_buffer = 0;
1935 STp->buffer->buffer_bytes = 0; 1935 STp->buffer->buffer_bytes = 0;
1936 STp->buffer->read_pointer = 0; 1936 STp->buffer->read_pointer = 0;
1937 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1937 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1938 } 1938 }
1939 return 0; 1939 return 0;
1940 } 1940 }
1941 1941
1942 /* 1942 /*
1943 * ADRL 1.1 compatible "slow" space filemarks fwd version 1943 * ADRL 1.1 compatible "slow" space filemarks fwd version
1944 * 1944 *
1945 * Just scans for the filemark sequentially. 1945 * Just scans for the filemark sequentially.
1946 */ 1946 */
1947 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt, 1947 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt,
1948 int mt_op, int mt_count) 1948 int mt_op, int mt_count)
1949 { 1949 {
1950 int cnt = 0; 1950 int cnt = 0;
1951 #if DEBUG 1951 #if DEBUG
1952 char * name = tape_name(STp); 1952 char * name = tape_name(STp);
1953 1953
1954 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count); 1954 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1955 #endif 1955 #endif
1956 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1956 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1957 #if DEBUG 1957 #if DEBUG
1958 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name); 1958 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1959 #endif 1959 #endif
1960 return (-EIO); 1960 return (-EIO);
1961 } 1961 }
1962 while (1) { 1962 while (1) {
1963 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 1963 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1964 #if DEBUG 1964 #if DEBUG
1965 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name); 1965 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1966 #endif 1966 #endif
1967 return (-EIO); 1967 return (-EIO);
1968 } 1968 }
1969 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER) 1969 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1970 cnt++; 1970 cnt++;
1971 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) { 1971 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1972 #if DEBUG 1972 #if DEBUG
1973 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name); 1973 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1974 #endif 1974 #endif
1975 if (STp->first_frame_position > STp->eod_frame_ppos+1) { 1975 if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1976 #if DEBUG 1976 #if DEBUG
1977 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n", 1977 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1978 name, STp->eod_frame_ppos, STp->first_frame_position-1); 1978 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1979 #endif 1979 #endif
1980 STp->eod_frame_ppos = STp->first_frame_position-1; 1980 STp->eod_frame_ppos = STp->first_frame_position-1;
1981 } 1981 }
1982 return (-EIO); 1982 return (-EIO);
1983 } 1983 }
1984 if (cnt == mt_count) 1984 if (cnt == mt_count)
1985 break; 1985 break;
1986 STp->frame_in_buffer = 0; 1986 STp->frame_in_buffer = 0;
1987 } 1987 }
1988 if (mt_op == MTFSF) { 1988 if (mt_op == MTFSF) {
1989 STp->frame_seq_number++; 1989 STp->frame_seq_number++;
1990 STp->frame_in_buffer = 0; 1990 STp->frame_in_buffer = 0;
1991 STp->buffer->buffer_bytes = 0; 1991 STp->buffer->buffer_bytes = 0;
1992 STp->buffer->read_pointer = 0; 1992 STp->buffer->read_pointer = 0;
1993 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 1993 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1994 } 1994 }
1995 return 0; 1995 return 0;
1996 } 1996 }
1997 1997
1998 /* 1998 /*
1999 * Fast linux specific version of OnStream FSF 1999 * Fast linux specific version of OnStream FSF
2000 */ 2000 */
2001 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt, 2001 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt,
2002 int mt_op, int mt_count) 2002 int mt_op, int mt_count)
2003 { 2003 {
2004 char * name = tape_name(STp); 2004 char * name = tape_name(STp);
2005 int cnt = 0, 2005 int cnt = 0,
2006 next_mark_ppos = -1; 2006 next_mark_ppos = -1;
2007 2007
2008 #if DEBUG 2008 #if DEBUG
2009 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count); 2009 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
2010 #endif 2010 #endif
2011 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2011 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2012 #if DEBUG 2012 #if DEBUG
2013 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name); 2013 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
2014 #endif 2014 #endif
2015 return (-EIO); 2015 return (-EIO);
2016 } 2016 }
2017 2017
2018 if (STp->linux_media_version >= 4) { 2018 if (STp->linux_media_version >= 4) {
2019 /* 2019 /*
2020 * direct lookup in header filemark list 2020 * direct lookup in header filemark list
2021 */ 2021 */
2022 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1; 2022 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
2023 if (STp->header_ok && 2023 if (STp->header_ok &&
2024 STp->header_cache != NULL && 2024 STp->header_cache != NULL &&
2025 (cnt + mt_count) < OS_FM_TAB_MAX && 2025 (cnt + mt_count) < OS_FM_TAB_MAX &&
2026 (cnt + mt_count) < STp->filemark_cnt && 2026 (cnt + mt_count) < STp->filemark_cnt &&
2027 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || 2027 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2028 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos))) 2028 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
2029 2029
2030 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]); 2030 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
2031 #if DEBUG 2031 #if DEBUG
2032 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX) 2032 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
2033 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name, 2033 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
2034 STp->header_cache == NULL?"lack of header cache":"count out of range"); 2034 STp->header_cache == NULL?"lack of header cache":"count out of range");
2035 else 2035 else
2036 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n", 2036 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
2037 name, cnt, 2037 name, cnt,
2038 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || 2038 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2039 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == 2039 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
2040 STp->buffer->aux->last_mark_ppos))?"match":"error", 2040 STp->buffer->aux->last_mark_ppos))?"match":"error",
2041 mt_count, next_mark_ppos); 2041 mt_count, next_mark_ppos);
2042 #endif 2042 #endif
2043 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) { 2043 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
2044 #if DEBUG 2044 #if DEBUG
2045 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name); 2045 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2046 #endif 2046 #endif
2047 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count); 2047 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2048 } else { 2048 } else {
2049 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos); 2049 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2050 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2050 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2051 #if DEBUG 2051 #if DEBUG
2052 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", 2052 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2053 name); 2053 name);
2054 #endif 2054 #endif
2055 return (-EIO); 2055 return (-EIO);
2056 } 2056 }
2057 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 2057 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2058 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 2058 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2059 name, next_mark_ppos); 2059 name, next_mark_ppos);
2060 return (-EIO); 2060 return (-EIO);
2061 } 2061 }
2062 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) { 2062 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
2063 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n", 2063 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
2064 name, cnt+mt_count, next_mark_ppos, 2064 name, cnt+mt_count, next_mark_ppos,
2065 ntohl(STp->buffer->aux->filemark_cnt)); 2065 ntohl(STp->buffer->aux->filemark_cnt));
2066 return (-EIO); 2066 return (-EIO);
2067 } 2067 }
2068 } 2068 }
2069 } else { 2069 } else {
2070 /* 2070 /*
2071 * Find nearest (usually previous) marker, then jump from marker to marker 2071 * Find nearest (usually previous) marker, then jump from marker to marker
2072 */ 2072 */
2073 while (1) { 2073 while (1) {
2074 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER) 2074 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
2075 break; 2075 break;
2076 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) { 2076 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
2077 #if DEBUG 2077 #if DEBUG
2078 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name); 2078 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
2079 #endif 2079 #endif
2080 return (-EIO); 2080 return (-EIO);
2081 } 2081 }
2082 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) { 2082 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
2083 if (STp->first_mark_ppos == -1) { 2083 if (STp->first_mark_ppos == -1) {
2084 #if DEBUG 2084 #if DEBUG
2085 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name); 2085 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2086 #endif 2086 #endif
2087 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count); 2087 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2088 } 2088 }
2089 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos); 2089 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
2090 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2090 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2091 #if DEBUG 2091 #if DEBUG
2092 printk(OSST_DEB_MSG 2092 printk(OSST_DEB_MSG
2093 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n", 2093 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2094 name); 2094 name);
2095 #endif 2095 #endif
2096 return (-EIO); 2096 return (-EIO);
2097 } 2097 }
2098 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 2098 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2099 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n", 2099 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
2100 name, STp->first_mark_ppos); 2100 name, STp->first_mark_ppos);
2101 return (-EIO); 2101 return (-EIO);
2102 } 2102 }
2103 } else { 2103 } else {
2104 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0) 2104 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
2105 return (-EIO); 2105 return (-EIO);
2106 mt_count++; 2106 mt_count++;
2107 } 2107 }
2108 } 2108 }
2109 cnt++; 2109 cnt++;
2110 while (cnt != mt_count) { 2110 while (cnt != mt_count) {
2111 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos); 2111 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
2112 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) { 2112 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
2113 #if DEBUG 2113 #if DEBUG
2114 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name); 2114 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2115 #endif 2115 #endif
2116 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt); 2116 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
2117 } 2117 }
2118 #if DEBUG 2118 #if DEBUG
2119 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos); 2119 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
2120 #endif 2120 #endif
2121 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos); 2121 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2122 cnt++; 2122 cnt++;
2123 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2123 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2124 #if DEBUG 2124 #if DEBUG
2125 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", 2125 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2126 name); 2126 name);
2127 #endif 2127 #endif
2128 return (-EIO); 2128 return (-EIO);
2129 } 2129 }
2130 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { 2130 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2131 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n", 2131 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2132 name, next_mark_ppos); 2132 name, next_mark_ppos);
2133 return (-EIO); 2133 return (-EIO);
2134 } 2134 }
2135 } 2135 }
2136 } 2136 }
2137 if (mt_op == MTFSF) { 2137 if (mt_op == MTFSF) {
2138 STp->frame_seq_number++; 2138 STp->frame_seq_number++;
2139 STp->frame_in_buffer = 0; 2139 STp->frame_in_buffer = 0;
2140 STp->buffer->buffer_bytes = 0; 2140 STp->buffer->buffer_bytes = 0;
2141 STp->buffer->read_pointer = 0; 2141 STp->buffer->read_pointer = 0;
2142 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); 2142 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2143 } 2143 }
2144 return 0; 2144 return 0;
2145 } 2145 }
2146 2146
2147 /* 2147 /*
2148 * In debug mode, we want to see as many errors as possible 2148 * In debug mode, we want to see as many errors as possible
2149 * to test the error recovery mechanism. 2149 * to test the error recovery mechanism.
2150 */ 2150 */
2151 #if DEBUG 2151 #if DEBUG
2152 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries) 2152 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries)
2153 { 2153 {
2154 unsigned char cmd[MAX_COMMAND_SIZE]; 2154 unsigned char cmd[MAX_COMMAND_SIZE];
2155 struct osst_request * SRpnt = * aSRpnt; 2155 struct osst_request * SRpnt = * aSRpnt;
2156 char * name = tape_name(STp); 2156 char * name = tape_name(STp);
2157 2157
2158 memset(cmd, 0, MAX_COMMAND_SIZE); 2158 memset(cmd, 0, MAX_COMMAND_SIZE);
2159 cmd[0] = MODE_SELECT; 2159 cmd[0] = MODE_SELECT;
2160 cmd[1] = 0x10; 2160 cmd[1] = 0x10;
2161 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH; 2161 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2162 2162
2163 (STp->buffer)->b_data[0] = cmd[4] - 1; 2163 (STp->buffer)->b_data[0] = cmd[4] - 1;
2164 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */ 2164 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
2165 (STp->buffer)->b_data[2] = 0; /* Reserved */ 2165 (STp->buffer)->b_data[2] = 0; /* Reserved */
2166 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */ 2166 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
2167 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7); 2167 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2168 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2; 2168 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2169 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4; 2169 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2170 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries; 2170 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2171 2171
2172 if (debugging) 2172 if (debugging)
2173 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries); 2173 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2174 2174
2175 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); 2175 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2176 *aSRpnt = SRpnt; 2176 *aSRpnt = SRpnt;
2177 2177
2178 if ((STp->buffer)->syscall_result) 2178 if ((STp->buffer)->syscall_result)
2179 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries); 2179 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2180 } 2180 }
2181 #endif 2181 #endif
2182 2182
2183 2183
2184 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt) 2184 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt)
2185 { 2185 {
2186 int result; 2186 int result;
2187 int this_mark_ppos = STp->first_frame_position; 2187 int this_mark_ppos = STp->first_frame_position;
2188 int this_mark_lbn = STp->logical_blk_num; 2188 int this_mark_lbn = STp->logical_blk_num;
2189 #if DEBUG 2189 #if DEBUG
2190 char * name = tape_name(STp); 2190 char * name = tape_name(STp);
2191 #endif 2191 #endif
2192 2192
2193 if (STp->raw) return 0; 2193 if (STp->raw) return 0;
2194 2194
2195 STp->write_type = OS_WRITE_NEW_MARK; 2195 STp->write_type = OS_WRITE_NEW_MARK;
2196 #if DEBUG 2196 #if DEBUG
2197 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n", 2197 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2198 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn); 2198 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2199 #endif 2199 #endif
2200 STp->dirty = 1; 2200 STp->dirty = 1;
2201 result = osst_flush_write_buffer(STp, aSRpnt); 2201 result = osst_flush_write_buffer(STp, aSRpnt);
2202 result |= osst_flush_drive_buffer(STp, aSRpnt); 2202 result |= osst_flush_drive_buffer(STp, aSRpnt);
2203 STp->last_mark_ppos = this_mark_ppos; 2203 STp->last_mark_ppos = this_mark_ppos;
2204 STp->last_mark_lbn = this_mark_lbn; 2204 STp->last_mark_lbn = this_mark_lbn;
2205 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX) 2205 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2206 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos); 2206 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2207 if (STp->filemark_cnt++ == 0) 2207 if (STp->filemark_cnt++ == 0)
2208 STp->first_mark_ppos = this_mark_ppos; 2208 STp->first_mark_ppos = this_mark_ppos;
2209 return result; 2209 return result;
2210 } 2210 }
2211 2211
2212 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt) 2212 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt)
2213 { 2213 {
2214 int result; 2214 int result;
2215 #if DEBUG 2215 #if DEBUG
2216 char * name = tape_name(STp); 2216 char * name = tape_name(STp);
2217 #endif 2217 #endif
2218 2218
2219 if (STp->raw) return 0; 2219 if (STp->raw) return 0;
2220 2220
2221 STp->write_type = OS_WRITE_EOD; 2221 STp->write_type = OS_WRITE_EOD;
2222 STp->eod_frame_ppos = STp->first_frame_position; 2222 STp->eod_frame_ppos = STp->first_frame_position;
2223 #if DEBUG 2223 #if DEBUG
2224 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name, 2224 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2225 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num); 2225 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2226 #endif 2226 #endif
2227 STp->dirty = 1; 2227 STp->dirty = 1;
2228 2228
2229 result = osst_flush_write_buffer(STp, aSRpnt); 2229 result = osst_flush_write_buffer(STp, aSRpnt);
2230 result |= osst_flush_drive_buffer(STp, aSRpnt); 2230 result |= osst_flush_drive_buffer(STp, aSRpnt);
2231 STp->eod_frame_lfa = --(STp->frame_seq_number); 2231 STp->eod_frame_lfa = --(STp->frame_seq_number);
2232 return result; 2232 return result;
2233 } 2233 }
2234 2234
2235 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count) 2235 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2236 { 2236 {
2237 char * name = tape_name(STp); 2237 char * name = tape_name(STp);
2238 2238
2239 #if DEBUG 2239 #if DEBUG
2240 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where); 2240 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2241 #endif 2241 #endif
2242 osst_wait_ready(STp, aSRpnt, 60 * 5, 0); 2242 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2243 osst_set_frame_position(STp, aSRpnt, where, 0); 2243 osst_set_frame_position(STp, aSRpnt, where, 0);
2244 STp->write_type = OS_WRITE_FILLER; 2244 STp->write_type = OS_WRITE_FILLER;
2245 while (count--) { 2245 while (count--) {
2246 memcpy(STp->buffer->b_data, "Filler", 6); 2246 memcpy(STp->buffer->b_data, "Filler", 6);
2247 STp->buffer->buffer_bytes = 6; 2247 STp->buffer->buffer_bytes = 6;
2248 STp->dirty = 1; 2248 STp->dirty = 1;
2249 if (osst_flush_write_buffer(STp, aSRpnt)) { 2249 if (osst_flush_write_buffer(STp, aSRpnt)) {
2250 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name); 2250 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2251 return (-EIO); 2251 return (-EIO);
2252 } 2252 }
2253 } 2253 }
2254 #if DEBUG 2254 #if DEBUG
2255 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name); 2255 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2256 #endif 2256 #endif
2257 return osst_flush_drive_buffer(STp, aSRpnt); 2257 return osst_flush_drive_buffer(STp, aSRpnt);
2258 } 2258 }
2259 2259
2260 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count) 2260 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2261 { 2261 {
2262 char * name = tape_name(STp); 2262 char * name = tape_name(STp);
2263 int result; 2263 int result;
2264 2264
2265 #if DEBUG 2265 #if DEBUG
2266 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where); 2266 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2267 #endif 2267 #endif
2268 osst_wait_ready(STp, aSRpnt, 60 * 5, 0); 2268 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2269 osst_set_frame_position(STp, aSRpnt, where, 0); 2269 osst_set_frame_position(STp, aSRpnt, where, 0);
2270 STp->write_type = OS_WRITE_HEADER; 2270 STp->write_type = OS_WRITE_HEADER;
2271 while (count--) { 2271 while (count--) {
2272 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache); 2272 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2273 STp->buffer->buffer_bytes = sizeof(os_header_t); 2273 STp->buffer->buffer_bytes = sizeof(os_header_t);
2274 STp->dirty = 1; 2274 STp->dirty = 1;
2275 if (osst_flush_write_buffer(STp, aSRpnt)) { 2275 if (osst_flush_write_buffer(STp, aSRpnt)) {
2276 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name); 2276 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2277 return (-EIO); 2277 return (-EIO);
2278 } 2278 }
2279 } 2279 }
2280 result = osst_flush_drive_buffer(STp, aSRpnt); 2280 result = osst_flush_drive_buffer(STp, aSRpnt);
2281 #if DEBUG 2281 #if DEBUG
2282 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done"); 2282 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2283 #endif 2283 #endif
2284 return result; 2284 return result;
2285 } 2285 }
2286 2286
2287 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod) 2287 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod)
2288 { 2288 {
2289 os_header_t * header; 2289 os_header_t * header;
2290 int result; 2290 int result;
2291 char * name = tape_name(STp); 2291 char * name = tape_name(STp);
2292 2292
2293 #if DEBUG 2293 #if DEBUG
2294 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name); 2294 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2295 #endif 2295 #endif
2296 if (STp->raw) return 0; 2296 if (STp->raw) return 0;
2297 2297
2298 if (STp->header_cache == NULL) { 2298 if (STp->header_cache == NULL) {
2299 if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) { 2299 if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
2300 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name); 2300 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2301 return (-ENOMEM); 2301 return (-ENOMEM);
2302 } 2302 }
2303 memset(STp->header_cache, 0, sizeof(os_header_t)); 2303 memset(STp->header_cache, 0, sizeof(os_header_t));
2304 #if DEBUG 2304 #if DEBUG
2305 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name); 2305 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2306 #endif 2306 #endif
2307 } 2307 }
2308 if (STp->header_ok) STp->update_frame_cntr++; 2308 if (STp->header_ok) STp->update_frame_cntr++;
2309 else STp->update_frame_cntr = 0; 2309 else STp->update_frame_cntr = 0;
2310 2310
2311 header = STp->header_cache; 2311 header = STp->header_cache;
2312 strcpy(header->ident_str, "ADR_SEQ"); 2312 strcpy(header->ident_str, "ADR_SEQ");
2313 header->major_rev = 1; 2313 header->major_rev = 1;
2314 header->minor_rev = 4; 2314 header->minor_rev = 4;
2315 header->ext_trk_tb_off = htons(17192); 2315 header->ext_trk_tb_off = htons(17192);
2316 header->pt_par_num = 1; 2316 header->pt_par_num = 1;
2317 header->partition[0].partition_num = OS_DATA_PARTITION; 2317 header->partition[0].partition_num = OS_DATA_PARTITION;
2318 header->partition[0].par_desc_ver = OS_PARTITION_VERSION; 2318 header->partition[0].par_desc_ver = OS_PARTITION_VERSION;
2319 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr); 2319 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2320 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos); 2320 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2321 header->partition[0].last_frame_ppos = htonl(STp->capacity); 2321 header->partition[0].last_frame_ppos = htonl(STp->capacity);
2322 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos); 2322 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2323 header->cfg_col_width = htonl(20); 2323 header->cfg_col_width = htonl(20);
2324 header->dat_col_width = htonl(1500); 2324 header->dat_col_width = htonl(1500);
2325 header->qfa_col_width = htonl(0); 2325 header->qfa_col_width = htonl(0);
2326 header->ext_track_tb.nr_stream_part = 1; 2326 header->ext_track_tb.nr_stream_part = 1;
2327 header->ext_track_tb.et_ent_sz = 32; 2327 header->ext_track_tb.et_ent_sz = 32;
2328 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0; 2328 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2329 header->ext_track_tb.dat_ext_trk_ey.fmt = 1; 2329 header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2330 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736); 2330 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2331 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0; 2331 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2332 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa); 2332 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa);
2333 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos); 2333 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
2334 header->dat_fm_tab.fm_part_num = 0; 2334 header->dat_fm_tab.fm_part_num = 0;
2335 header->dat_fm_tab.fm_tab_ent_sz = 4; 2335 header->dat_fm_tab.fm_tab_ent_sz = 4;
2336 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX? 2336 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2337 STp->filemark_cnt:OS_FM_TAB_MAX); 2337 STp->filemark_cnt:OS_FM_TAB_MAX);
2338 2338
2339 result = __osst_write_header(STp, aSRpnt, 0xbae, 5); 2339 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2340 if (STp->update_frame_cntr == 0) 2340 if (STp->update_frame_cntr == 0)
2341 osst_write_filler(STp, aSRpnt, 0xbb3, 5); 2341 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2342 result &= __osst_write_header(STp, aSRpnt, 5, 5); 2342 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2343 2343
2344 if (locate_eod) { 2344 if (locate_eod) {
2345 #if DEBUG 2345 #if DEBUG
2346 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos); 2346 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2347 #endif 2347 #endif
2348 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0); 2348 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2349 } 2349 }
2350 if (result) 2350 if (result)
2351 printk(KERN_ERR "%s:E: Write header failed\n", name); 2351 printk(KERN_ERR "%s:E: Write header failed\n", name);
2352 else { 2352 else {
2353 memcpy(STp->application_sig, "LIN4", 4); 2353 memcpy(STp->application_sig, "LIN4", 4);
2354 STp->linux_media = 1; 2354 STp->linux_media = 1;
2355 STp->linux_media_version = 4; 2355 STp->linux_media_version = 4;
2356 STp->header_ok = 1; 2356 STp->header_ok = 1;
2357 } 2357 }
2358 return result; 2358 return result;
2359 } 2359 }
2360 2360
2361 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt) 2361 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt)
2362 { 2362 {
2363 if (STp->header_cache != NULL) 2363 if (STp->header_cache != NULL)
2364 memset(STp->header_cache, 0, sizeof(os_header_t)); 2364 memset(STp->header_cache, 0, sizeof(os_header_t));
2365 2365
2366 STp->logical_blk_num = STp->frame_seq_number = 0; 2366 STp->logical_blk_num = STp->frame_seq_number = 0;
2367 STp->frame_in_buffer = 0; 2367 STp->frame_in_buffer = 0;
2368 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A; 2368 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2369 STp->filemark_cnt = 0; 2369 STp->filemark_cnt = 0;
2370 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1; 2370 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2371 return osst_write_header(STp, aSRpnt, 1); 2371 return osst_write_header(STp, aSRpnt, 1);
2372 } 2372 }
2373 2373
2374 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos) 2374 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos)
2375 { 2375 {
2376 char * name = tape_name(STp); 2376 char * name = tape_name(STp);
2377 os_header_t * header; 2377 os_header_t * header;
2378 os_aux_t * aux; 2378 os_aux_t * aux;
2379 char id_string[8]; 2379 char id_string[8];
2380 int linux_media_version, 2380 int linux_media_version,
2381 update_frame_cntr; 2381 update_frame_cntr;
2382 2382
2383 if (STp->raw) 2383 if (STp->raw)
2384 return 1; 2384 return 1;
2385 2385
2386 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) { 2386 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2387 if (osst_set_frame_position(STp, aSRpnt, ppos, 0)) 2387 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2388 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name); 2388 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2389 osst_wait_ready(STp, aSRpnt, 60 * 15, 0); 2389 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2390 if (osst_initiate_read (STp, aSRpnt)) { 2390 if (osst_initiate_read (STp, aSRpnt)) {
2391 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name); 2391 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2392 return 0; 2392 return 0;
2393 } 2393 }
2394 } 2394 }
2395 if (osst_read_frame(STp, aSRpnt, 180)) { 2395 if (osst_read_frame(STp, aSRpnt, 180)) {
2396 #if DEBUG 2396 #if DEBUG
2397 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name); 2397 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2398 #endif 2398 #endif
2399 return 0; 2399 return 0;
2400 } 2400 }
2401 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */ 2401 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2402 aux = STp->buffer->aux; 2402 aux = STp->buffer->aux;
2403 if (aux->frame_type != OS_FRAME_TYPE_HEADER) { 2403 if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2404 #if DEBUG 2404 #if DEBUG
2405 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos); 2405 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2406 #endif 2406 #endif
2407 return 0; 2407 return 0;
2408 } 2408 }
2409 if (ntohl(aux->frame_seq_num) != 0 || 2409 if (ntohl(aux->frame_seq_num) != 0 ||
2410 ntohl(aux->logical_blk_num) != 0 || 2410 ntohl(aux->logical_blk_num) != 0 ||
2411 aux->partition.partition_num != OS_CONFIG_PARTITION || 2411 aux->partition.partition_num != OS_CONFIG_PARTITION ||
2412 ntohl(aux->partition.first_frame_ppos) != 0 || 2412 ntohl(aux->partition.first_frame_ppos) != 0 ||
2413 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) { 2413 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2414 #if DEBUG 2414 #if DEBUG
2415 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name, 2415 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2416 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num), 2416 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2417 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos), 2417 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2418 ntohl(aux->partition.last_frame_ppos)); 2418 ntohl(aux->partition.last_frame_ppos));
2419 #endif 2419 #endif
2420 return 0; 2420 return 0;
2421 } 2421 }
2422 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 && 2422 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2423 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) { 2423 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2424 strlcpy(id_string, header->ident_str, 8); 2424 strlcpy(id_string, header->ident_str, 8);
2425 #if DEBUG 2425 #if DEBUG
2426 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string); 2426 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2427 #endif 2427 #endif
2428 return 0; 2428 return 0;
2429 } 2429 }
2430 update_frame_cntr = ntohl(aux->update_frame_cntr); 2430 update_frame_cntr = ntohl(aux->update_frame_cntr);
2431 if (update_frame_cntr < STp->update_frame_cntr) { 2431 if (update_frame_cntr < STp->update_frame_cntr) {
2432 #if DEBUG 2432 #if DEBUG
2433 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n", 2433 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2434 name, ppos, update_frame_cntr, STp->update_frame_cntr); 2434 name, ppos, update_frame_cntr, STp->update_frame_cntr);
2435 #endif 2435 #endif
2436 return 0; 2436 return 0;
2437 } 2437 }
2438 if (header->major_rev != 1 || header->minor_rev != 4 ) { 2438 if (header->major_rev != 1 || header->minor_rev != 4 ) {
2439 #if DEBUG 2439 #if DEBUG
2440 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n", 2440 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2441 name, (header->major_rev != 1 || header->minor_rev < 2 || 2441 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2442 header->minor_rev > 4 )? "Invalid" : "Warning:", 2442 header->minor_rev > 4 )? "Invalid" : "Warning:",
2443 header->major_rev, header->minor_rev); 2443 header->major_rev, header->minor_rev);
2444 #endif 2444 #endif
2445 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4) 2445 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2446 return 0; 2446 return 0;
2447 } 2447 }
2448 #if DEBUG 2448 #if DEBUG
2449 if (header->pt_par_num != 1) 2449 if (header->pt_par_num != 1)
2450 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n", 2450 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2451 name, header->pt_par_num); 2451 name, header->pt_par_num);
2452 #endif 2452 #endif
2453 memcpy(id_string, aux->application_sig, 4); 2453 memcpy(id_string, aux->application_sig, 4);
2454 id_string[4] = 0; 2454 id_string[4] = 0;
2455 if (memcmp(id_string, "LIN", 3) == 0) { 2455 if (memcmp(id_string, "LIN", 3) == 0) {
2456 STp->linux_media = 1; 2456 STp->linux_media = 1;
2457 linux_media_version = id_string[3] - '0'; 2457 linux_media_version = id_string[3] - '0';
2458 if (linux_media_version != 4) 2458 if (linux_media_version != 4)
2459 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n", 2459 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2460 name, linux_media_version); 2460 name, linux_media_version);
2461 } else { 2461 } else {
2462 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string); 2462 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2463 return 0; 2463 return 0;
2464 } 2464 }
2465 if (linux_media_version < STp->linux_media_version) { 2465 if (linux_media_version < STp->linux_media_version) {
2466 #if DEBUG 2466 #if DEBUG
2467 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n", 2467 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2468 name, ppos, linux_media_version); 2468 name, ppos, linux_media_version);
2469 #endif 2469 #endif
2470 return 0; 2470 return 0;
2471 } 2471 }
2472 if (linux_media_version > STp->linux_media_version) { 2472 if (linux_media_version > STp->linux_media_version) {
2473 #if DEBUG 2473 #if DEBUG
2474 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n", 2474 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2475 name, ppos, linux_media_version); 2475 name, ppos, linux_media_version);
2476 #endif 2476 #endif
2477 memcpy(STp->application_sig, id_string, 5); 2477 memcpy(STp->application_sig, id_string, 5);
2478 STp->linux_media_version = linux_media_version; 2478 STp->linux_media_version = linux_media_version;
2479 STp->update_frame_cntr = -1; 2479 STp->update_frame_cntr = -1;
2480 } 2480 }
2481 if (update_frame_cntr > STp->update_frame_cntr) { 2481 if (update_frame_cntr > STp->update_frame_cntr) {
2482 #if DEBUG 2482 #if DEBUG
2483 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n", 2483 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2484 name, ppos, update_frame_cntr); 2484 name, ppos, update_frame_cntr);
2485 #endif 2485 #endif
2486 if (STp->header_cache == NULL) { 2486 if (STp->header_cache == NULL) {
2487 if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) { 2487 if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
2488 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name); 2488 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2489 return 0; 2489 return 0;
2490 } 2490 }
2491 #if DEBUG 2491 #if DEBUG
2492 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name); 2492 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2493 #endif 2493 #endif
2494 } 2494 }
2495 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache); 2495 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2496 header = STp->header_cache; /* further accesses from cached (full) copy */ 2496 header = STp->header_cache; /* further accesses from cached (full) copy */
2497 2497
2498 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr); 2498 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2499 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos); 2499 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2500 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos); 2500 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2501 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb); 2501 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2502 STp->filemark_cnt = ntohl(aux->filemark_cnt); 2502 STp->filemark_cnt = ntohl(aux->filemark_cnt);
2503 STp->first_mark_ppos = ntohl(aux->next_mark_ppos); 2503 STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2504 STp->last_mark_ppos = ntohl(aux->last_mark_ppos); 2504 STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2505 STp->last_mark_lbn = ntohl(aux->last_mark_lbn); 2505 STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2506 STp->update_frame_cntr = update_frame_cntr; 2506 STp->update_frame_cntr = update_frame_cntr;
2507 #if DEBUG 2507 #if DEBUG
2508 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n", 2508 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2509 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt); 2509 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2510 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name, 2510 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2511 STp->first_data_ppos, 2511 STp->first_data_ppos,
2512 ntohl(header->partition[0].last_frame_ppos), 2512 ntohl(header->partition[0].last_frame_ppos),
2513 ntohl(header->partition[0].eod_frame_ppos)); 2513 ntohl(header->partition[0].eod_frame_ppos));
2514 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n", 2514 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2515 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos); 2515 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2516 #endif 2516 #endif
2517 if (header->minor_rev < 4 && STp->linux_media_version == 4) { 2517 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2518 #if DEBUG 2518 #if DEBUG
2519 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name); 2519 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2520 #endif 2520 #endif
2521 memcpy((void *)header->dat_fm_tab.fm_tab_ent, 2521 memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2522 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent)); 2522 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2523 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list)); 2523 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2524 } 2524 }
2525 if (header->minor_rev == 4 && 2525 if (header->minor_rev == 4 &&
2526 (header->ext_trk_tb_off != htons(17192) || 2526 (header->ext_trk_tb_off != htons(17192) ||
2527 header->partition[0].partition_num != OS_DATA_PARTITION || 2527 header->partition[0].partition_num != OS_DATA_PARTITION ||
2528 header->partition[0].par_desc_ver != OS_PARTITION_VERSION || 2528 header->partition[0].par_desc_ver != OS_PARTITION_VERSION ||
2529 header->partition[0].last_frame_ppos != htonl(STp->capacity) || 2529 header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2530 header->cfg_col_width != htonl(20) || 2530 header->cfg_col_width != htonl(20) ||
2531 header->dat_col_width != htonl(1500) || 2531 header->dat_col_width != htonl(1500) ||
2532 header->qfa_col_width != htonl(0) || 2532 header->qfa_col_width != htonl(0) ||
2533 header->ext_track_tb.nr_stream_part != 1 || 2533 header->ext_track_tb.nr_stream_part != 1 ||
2534 header->ext_track_tb.et_ent_sz != 32 || 2534 header->ext_track_tb.et_ent_sz != 32 ||
2535 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION || 2535 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION ||
2536 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 || 2536 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2537 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) || 2537 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2538 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 || 2538 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2539 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) || 2539 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) ||
2540 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION || 2540 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION ||
2541 header->dat_fm_tab.fm_tab_ent_sz != 4 || 2541 header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2542 header->dat_fm_tab.fm_tab_ent_cnt != 2542 header->dat_fm_tab.fm_tab_ent_cnt !=
2543 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX))) 2543 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2544 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name); 2544 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2545 2545
2546 } 2546 }
2547 2547
2548 return 1; 2548 return 1;
2549 } 2549 }
2550 2550
2551 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt) 2551 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt)
2552 { 2552 {
2553 int position, ppos; 2553 int position, ppos;
2554 int first, last; 2554 int first, last;
2555 int valid = 0; 2555 int valid = 0;
2556 char * name = tape_name(STp); 2556 char * name = tape_name(STp);
2557 2557
2558 position = osst_get_frame_position(STp, aSRpnt); 2558 position = osst_get_frame_position(STp, aSRpnt);
2559 2559
2560 if (STp->raw) { 2560 if (STp->raw) {
2561 STp->header_ok = STp->linux_media = 1; 2561 STp->header_ok = STp->linux_media = 1;
2562 STp->linux_media_version = 0; 2562 STp->linux_media_version = 0;
2563 return 1; 2563 return 1;
2564 } 2564 }
2565 STp->header_ok = STp->linux_media = STp->linux_media_version = 0; 2565 STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2566 STp->wrt_pass_cntr = STp->update_frame_cntr = -1; 2566 STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2567 STp->eod_frame_ppos = STp->first_data_ppos = -1; 2567 STp->eod_frame_ppos = STp->first_data_ppos = -1;
2568 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1; 2568 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2569 #if DEBUG 2569 #if DEBUG
2570 printk(OSST_DEB_MSG "%s:D: Reading header\n", name); 2570 printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2571 #endif 2571 #endif
2572 2572
2573 /* optimization for speed - if we are positioned at ppos 10, read second group first */ 2573 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2574 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */ 2574 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2575 2575
2576 first = position==10?0xbae: 5; 2576 first = position==10?0xbae: 5;
2577 last = position==10?0xbb3:10; 2577 last = position==10?0xbb3:10;
2578 2578
2579 for (ppos = first; ppos < last; ppos++) 2579 for (ppos = first; ppos < last; ppos++)
2580 if (__osst_analyze_headers(STp, aSRpnt, ppos)) 2580 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2581 valid = 1; 2581 valid = 1;
2582 2582
2583 first = position==10? 5:0xbae; 2583 first = position==10? 5:0xbae;
2584 last = position==10?10:0xbb3; 2584 last = position==10?10:0xbb3;
2585 2585
2586 for (ppos = first; ppos < last; ppos++) 2586 for (ppos = first; ppos < last; ppos++)
2587 if (__osst_analyze_headers(STp, aSRpnt, ppos)) 2587 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2588 valid = 1; 2588 valid = 1;
2589 2589
2590 if (!valid) { 2590 if (!valid) {
2591 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name); 2591 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2592 STp->eod_frame_ppos = STp->first_data_ppos = 0; 2592 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2593 osst_set_frame_position(STp, aSRpnt, 10, 0); 2593 osst_set_frame_position(STp, aSRpnt, 10, 0);
2594 return 0; 2594 return 0;
2595 } 2595 }
2596 if (position <= STp->first_data_ppos) { 2596 if (position <= STp->first_data_ppos) {
2597 position = STp->first_data_ppos; 2597 position = STp->first_data_ppos;
2598 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0; 2598 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2599 } 2599 }
2600 osst_set_frame_position(STp, aSRpnt, position, 0); 2600 osst_set_frame_position(STp, aSRpnt, position, 0);
2601 STp->header_ok = 1; 2601 STp->header_ok = 1;
2602 2602
2603 return 1; 2603 return 1;
2604 } 2604 }
2605 2605
2606 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt) 2606 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt)
2607 { 2607 {
2608 int frame_position = STp->first_frame_position; 2608 int frame_position = STp->first_frame_position;
2609 int frame_seq_numbr = STp->frame_seq_number; 2609 int frame_seq_numbr = STp->frame_seq_number;
2610 int logical_blk_num = STp->logical_blk_num; 2610 int logical_blk_num = STp->logical_blk_num;
2611 int halfway_frame = STp->frame_in_buffer; 2611 int halfway_frame = STp->frame_in_buffer;
2612 int read_pointer = STp->buffer->read_pointer; 2612 int read_pointer = STp->buffer->read_pointer;
2613 int prev_mark_ppos = -1; 2613 int prev_mark_ppos = -1;
2614 int actual_mark_ppos, i, n; 2614 int actual_mark_ppos, i, n;
2615 #if DEBUG 2615 #if DEBUG
2616 char * name = tape_name(STp); 2616 char * name = tape_name(STp);
2617 2617
2618 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name); 2618 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2619 #endif 2619 #endif
2620 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); 2620 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2621 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { 2621 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2622 #if DEBUG 2622 #if DEBUG
2623 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name); 2623 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2624 #endif 2624 #endif
2625 return (-EIO); 2625 return (-EIO);
2626 } 2626 }
2627 if (STp->linux_media_version >= 4) { 2627 if (STp->linux_media_version >= 4) {
2628 for (i=0; i<STp->filemark_cnt; i++) 2628 for (i=0; i<STp->filemark_cnt; i++)
2629 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position) 2629 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2630 prev_mark_ppos = n; 2630 prev_mark_ppos = n;
2631 } else 2631 } else
2632 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */ 2632 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2633 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ? 2633 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2634 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos); 2634 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2635 if (frame_position != STp->first_frame_position || 2635 if (frame_position != STp->first_frame_position ||
2636 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) || 2636 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2637 prev_mark_ppos != actual_mark_ppos ) { 2637 prev_mark_ppos != actual_mark_ppos ) {
2638 #if DEBUG 2638 #if DEBUG
2639 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name, 2639 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2640 STp->first_frame_position, frame_position, 2640 STp->first_frame_position, frame_position,
2641 STp->frame_seq_number + (halfway_frame?0:1), 2641 STp->frame_seq_number + (halfway_frame?0:1),
2642 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos); 2642 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2643 #endif 2643 #endif
2644 return (-EIO); 2644 return (-EIO);
2645 } 2645 }
2646 if (halfway_frame) { 2646 if (halfway_frame) {
2647 /* prepare buffer for append and rewrite on top of original */ 2647 /* prepare buffer for append and rewrite on top of original */
2648 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); 2648 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2649 STp->buffer->buffer_bytes = read_pointer; 2649 STp->buffer->buffer_bytes = read_pointer;
2650 STp->ps[STp->partition].rw = ST_WRITING; 2650 STp->ps[STp->partition].rw = ST_WRITING;
2651 STp->dirty = 1; 2651 STp->dirty = 1;
2652 } 2652 }
2653 STp->frame_in_buffer = halfway_frame; 2653 STp->frame_in_buffer = halfway_frame;
2654 STp->frame_seq_number = frame_seq_numbr; 2654 STp->frame_seq_number = frame_seq_numbr;
2655 STp->logical_blk_num = logical_blk_num; 2655 STp->logical_blk_num = logical_blk_num;
2656 return 0; 2656 return 0;
2657 } 2657 }
2658 2658
2659 /* Acc. to OnStream, the vers. numbering is the following: 2659 /* Acc. to OnStream, the vers. numbering is the following:
2660 * X.XX for released versions (X=digit), 2660 * X.XX for released versions (X=digit),
2661 * XXXY for unreleased versions (Y=letter) 2661 * XXXY for unreleased versions (Y=letter)
2662 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06 2662 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2663 * This fn makes monoton numbers out of this scheme ... 2663 * This fn makes monoton numbers out of this scheme ...
2664 */ 2664 */
2665 static unsigned int osst_parse_firmware_rev (const char * str) 2665 static unsigned int osst_parse_firmware_rev (const char * str)
2666 { 2666 {
2667 if (str[1] == '.') { 2667 if (str[1] == '.') {
2668 return (str[0]-'0')*10000 2668 return (str[0]-'0')*10000
2669 +(str[2]-'0')*1000 2669 +(str[2]-'0')*1000
2670 +(str[3]-'0')*100; 2670 +(str[3]-'0')*100;
2671 } else { 2671 } else {
2672 return (str[0]-'0')*10000 2672 return (str[0]-'0')*10000
2673 +(str[1]-'0')*1000 2673 +(str[1]-'0')*1000
2674 +(str[2]-'0')*100 - 100 2674 +(str[2]-'0')*100 - 100
2675 +(str[3]-'@'); 2675 +(str[3]-'@');
2676 } 2676 }
2677 } 2677 }
2678 2678
2679 /* 2679 /*
2680 * Configure the OnStream SCII tape drive for default operation 2680 * Configure the OnStream SCII tape drive for default operation
2681 */ 2681 */
2682 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt) 2682 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
2683 { 2683 {
2684 unsigned char cmd[MAX_COMMAND_SIZE]; 2684 unsigned char cmd[MAX_COMMAND_SIZE];
2685 char * name = tape_name(STp); 2685 char * name = tape_name(STp);
2686 struct osst_request * SRpnt = * aSRpnt; 2686 struct osst_request * SRpnt = * aSRpnt;
2687 osst_mode_parameter_header_t * header; 2687 osst_mode_parameter_header_t * header;
2688 osst_block_size_page_t * bs; 2688 osst_block_size_page_t * bs;
2689 osst_capabilities_page_t * cp; 2689 osst_capabilities_page_t * cp;
2690 osst_tape_paramtr_page_t * prm; 2690 osst_tape_paramtr_page_t * prm;
2691 int drive_buffer_size; 2691 int drive_buffer_size;
2692 2692
2693 if (STp->ready != ST_READY) { 2693 if (STp->ready != ST_READY) {
2694 #if DEBUG 2694 #if DEBUG
2695 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name); 2695 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2696 #endif 2696 #endif
2697 return (-EIO); 2697 return (-EIO);
2698 } 2698 }
2699 2699
2700 if (STp->os_fw_rev < 10600) { 2700 if (STp->os_fw_rev < 10600) {
2701 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev); 2701 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2702 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name); 2702 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2703 } 2703 }
2704 2704
2705 /* 2705 /*
2706 * Configure 32.5KB (data+aux) frame size. 2706 * Configure 32.5KB (data+aux) frame size.
2707 * Get the current frame size from the block size mode page 2707 * Get the current frame size from the block size mode page
2708 */ 2708 */
2709 memset(cmd, 0, MAX_COMMAND_SIZE); 2709 memset(cmd, 0, MAX_COMMAND_SIZE);
2710 cmd[0] = MODE_SENSE; 2710 cmd[0] = MODE_SENSE;
2711 cmd[1] = 8; 2711 cmd[1] = 8;
2712 cmd[2] = BLOCK_SIZE_PAGE; 2712 cmd[2] = BLOCK_SIZE_PAGE;
2713 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH; 2713 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2714 2714
2715 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); 2715 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2716 if (SRpnt == NULL) { 2716 if (SRpnt == NULL) {
2717 #if DEBUG 2717 #if DEBUG
2718 printk(OSST_DEB_MSG "osst :D: Busy\n"); 2718 printk(OSST_DEB_MSG "osst :D: Busy\n");
2719 #endif 2719 #endif
2720 return (-EBUSY); 2720 return (-EBUSY);
2721 } 2721 }
2722 *aSRpnt = SRpnt; 2722 *aSRpnt = SRpnt;
2723 if ((STp->buffer)->syscall_result != 0) { 2723 if ((STp->buffer)->syscall_result != 0) {
2724 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name); 2724 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2725 return (-EIO); 2725 return (-EIO);
2726 } 2726 }
2727 2727
2728 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; 2728 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2729 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl); 2729 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2730 2730
2731 #if DEBUG 2731 #if DEBUG
2732 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No"); 2732 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2733 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No"); 2733 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: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No"); 2734 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2735 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No"); 2735 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2736 #endif 2736 #endif
2737 2737
2738 /* 2738 /*
2739 * Configure default auto columns mode, 32.5KB transfer mode 2739 * Configure default auto columns mode, 32.5KB transfer mode
2740 */ 2740 */
2741 bs->one = 1; 2741 bs->one = 1;
2742 bs->play32 = 0; 2742 bs->play32 = 0;
2743 bs->play32_5 = 1; 2743 bs->play32_5 = 1;
2744 bs->record32 = 0; 2744 bs->record32 = 0;
2745 bs->record32_5 = 1; 2745 bs->record32_5 = 1;
2746 2746
2747 memset(cmd, 0, MAX_COMMAND_SIZE); 2747 memset(cmd, 0, MAX_COMMAND_SIZE);
2748 cmd[0] = MODE_SELECT; 2748 cmd[0] = MODE_SELECT;
2749 cmd[1] = 0x10; 2749 cmd[1] = 0x10;
2750 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH; 2750 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2751 2751
2752 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); 2752 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2753 *aSRpnt = SRpnt; 2753 *aSRpnt = SRpnt;
2754 if ((STp->buffer)->syscall_result != 0) { 2754 if ((STp->buffer)->syscall_result != 0) {
2755 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name); 2755 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2756 return (-EIO); 2756 return (-EIO);
2757 } 2757 }
2758 2758
2759 #if DEBUG 2759 #if DEBUG
2760 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name); 2760 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2761 /* 2761 /*
2762 * In debug mode, we want to see as many errors as possible 2762 * In debug mode, we want to see as many errors as possible
2763 * to test the error recovery mechanism. 2763 * to test the error recovery mechanism.
2764 */ 2764 */
2765 osst_set_retries(STp, aSRpnt, 0); 2765 osst_set_retries(STp, aSRpnt, 0);
2766 SRpnt = * aSRpnt; 2766 SRpnt = * aSRpnt;
2767 #endif 2767 #endif
2768 2768
2769 /* 2769 /*
2770 * Set vendor name to 'LIN4' for "Linux support version 4". 2770 * Set vendor name to 'LIN4' for "Linux support version 4".
2771 */ 2771 */
2772 2772
2773 memset(cmd, 0, MAX_COMMAND_SIZE); 2773 memset(cmd, 0, MAX_COMMAND_SIZE);
2774 cmd[0] = MODE_SELECT; 2774 cmd[0] = MODE_SELECT;
2775 cmd[1] = 0x10; 2775 cmd[1] = 0x10;
2776 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH; 2776 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2777 2777
2778 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1; 2778 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2779 header->medium_type = 0; /* Medium Type - ignoring */ 2779 header->medium_type = 0; /* Medium Type - ignoring */
2780 header->dsp = 0; /* Reserved */ 2780 header->dsp = 0; /* Reserved */
2781 header->bdl = 0; /* Block Descriptor Length */ 2781 header->bdl = 0; /* Block Descriptor Length */
2782 2782
2783 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7); 2783 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2784 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6; 2784 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2785 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L'; 2785 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2786 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I'; 2786 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2787 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N'; 2787 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2788 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4'; 2788 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2789 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0; 2789 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2790 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0; 2790 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2791 2791
2792 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); 2792 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2793 *aSRpnt = SRpnt; 2793 *aSRpnt = SRpnt;
2794 2794
2795 if ((STp->buffer)->syscall_result != 0) { 2795 if ((STp->buffer)->syscall_result != 0) {
2796 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name, 2796 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2797 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2)); 2797 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2798 return (-EIO); 2798 return (-EIO);
2799 } 2799 }
2800 2800
2801 memset(cmd, 0, MAX_COMMAND_SIZE); 2801 memset(cmd, 0, MAX_COMMAND_SIZE);
2802 cmd[0] = MODE_SENSE; 2802 cmd[0] = MODE_SENSE;
2803 cmd[1] = 8; 2803 cmd[1] = 8;
2804 cmd[2] = CAPABILITIES_PAGE; 2804 cmd[2] = CAPABILITIES_PAGE;
2805 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH; 2805 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2806 2806
2807 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); 2807 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2808 *aSRpnt = SRpnt; 2808 *aSRpnt = SRpnt;
2809 2809
2810 if ((STp->buffer)->syscall_result != 0) { 2810 if ((STp->buffer)->syscall_result != 0) {
2811 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name); 2811 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2812 return (-EIO); 2812 return (-EIO);
2813 } 2813 }
2814 2814
2815 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; 2815 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2816 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data + 2816 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2817 sizeof(osst_mode_parameter_header_t) + header->bdl); 2817 sizeof(osst_mode_parameter_header_t) + header->bdl);
2818 2818
2819 drive_buffer_size = ntohs(cp->buffer_size) / 2; 2819 drive_buffer_size = ntohs(cp->buffer_size) / 2;
2820 2820
2821 memset(cmd, 0, MAX_COMMAND_SIZE); 2821 memset(cmd, 0, MAX_COMMAND_SIZE);
2822 cmd[0] = MODE_SENSE; 2822 cmd[0] = MODE_SENSE;
2823 cmd[1] = 8; 2823 cmd[1] = 8;
2824 cmd[2] = TAPE_PARAMTR_PAGE; 2824 cmd[2] = TAPE_PARAMTR_PAGE;
2825 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH; 2825 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2826 2826
2827 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); 2827 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2828 *aSRpnt = SRpnt; 2828 *aSRpnt = SRpnt;
2829 2829
2830 if ((STp->buffer)->syscall_result != 0) { 2830 if ((STp->buffer)->syscall_result != 0) {
2831 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name); 2831 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2832 return (-EIO); 2832 return (-EIO);
2833 } 2833 }
2834 2834
2835 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; 2835 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2836 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data + 2836 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2837 sizeof(osst_mode_parameter_header_t) + header->bdl); 2837 sizeof(osst_mode_parameter_header_t) + header->bdl);
2838 2838
2839 STp->density = prm->density; 2839 STp->density = prm->density;
2840 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks); 2840 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2841 #if DEBUG 2841 #if DEBUG
2842 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n", 2842 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2843 name, STp->density, STp->capacity / 32, drive_buffer_size); 2843 name, STp->density, STp->capacity / 32, drive_buffer_size);
2844 #endif 2844 #endif
2845 2845
2846 return 0; 2846 return 0;
2847 2847
2848 } 2848 }
2849 2849
2850 2850
2851 /* Step over EOF if it has been inadvertently crossed (ioctl not used because 2851 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2852 it messes up the block number). */ 2852 it messes up the block number). */
2853 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward) 2853 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward)
2854 { 2854 {
2855 int result; 2855 int result;
2856 char * name = tape_name(STp); 2856 char * name = tape_name(STp);
2857 2857
2858 #if DEBUG 2858 #if DEBUG
2859 if (debugging) 2859 if (debugging)
2860 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n", 2860 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2861 name, forward ? "forward" : "backward"); 2861 name, forward ? "forward" : "backward");
2862 #endif 2862 #endif
2863 2863
2864 if (forward) { 2864 if (forward) {
2865 /* assumes that the filemark is already read by the drive, so this is low cost */ 2865 /* assumes that the filemark is already read by the drive, so this is low cost */
2866 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1); 2866 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2867 } 2867 }
2868 else 2868 else
2869 /* assumes this is only called if we just read the filemark! */ 2869 /* assumes this is only called if we just read the filemark! */
2870 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1); 2870 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2871 2871
2872 if (result < 0) 2872 if (result < 0)
2873 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n", 2873 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2874 name, forward ? "forward" : "backward"); 2874 name, forward ? "forward" : "backward");
2875 2875
2876 return result; 2876 return result;
2877 } 2877 }
2878 2878
2879 2879
2880 /* Get the tape position. */ 2880 /* Get the tape position. */
2881 2881
2882 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt) 2882 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
2883 { 2883 {
2884 unsigned char scmd[MAX_COMMAND_SIZE]; 2884 unsigned char scmd[MAX_COMMAND_SIZE];
2885 struct osst_request * SRpnt; 2885 struct osst_request * SRpnt;
2886 int result = 0; 2886 int result = 0;
2887 char * name = tape_name(STp); 2887 char * name = tape_name(STp);
2888 2888
2889 /* KG: We want to be able to use it for checking Write Buffer availability 2889 /* KG: We want to be able to use it for checking Write Buffer availability
2890 * and thus don't want to risk to overwrite anything. Exchange buffers ... */ 2890 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2891 char mybuf[24]; 2891 char mybuf[24];
2892 char * olddata = STp->buffer->b_data; 2892 char * olddata = STp->buffer->b_data;
2893 int oldsize = STp->buffer->buffer_size; 2893 int oldsize = STp->buffer->buffer_size;
2894 2894
2895 if (STp->ready != ST_READY) return (-EIO); 2895 if (STp->ready != ST_READY) return (-EIO);
2896 2896
2897 memset (scmd, 0, MAX_COMMAND_SIZE); 2897 memset (scmd, 0, MAX_COMMAND_SIZE);
2898 scmd[0] = READ_POSITION; 2898 scmd[0] = READ_POSITION;
2899 2899
2900 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; 2900 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2901 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE, 2901 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2902 STp->timeout, MAX_RETRIES, 1); 2902 STp->timeout, MAX_RETRIES, 1);
2903 if (!SRpnt) { 2903 if (!SRpnt) {
2904 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; 2904 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2905 return (-EBUSY); 2905 return (-EBUSY);
2906 } 2906 }
2907 *aSRpnt = SRpnt; 2907 *aSRpnt = SRpnt;
2908 2908
2909 if (STp->buffer->syscall_result) 2909 if (STp->buffer->syscall_result)
2910 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */ 2910 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */
2911 2911
2912 if (result == -EINVAL) 2912 if (result == -EINVAL)
2913 printk(KERN_ERR "%s:E: Can't read tape position.\n", name); 2913 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2914 else { 2914 else {
2915 if (result == -EIO) { /* re-read position - this needs to preserve media errors */ 2915 if (result == -EIO) { /* re-read position - this needs to preserve media errors */
2916 unsigned char mysense[16]; 2916 unsigned char mysense[16];
2917 memcpy (mysense, SRpnt->sense, 16); 2917 memcpy (mysense, SRpnt->sense, 16);
2918 memset (scmd, 0, MAX_COMMAND_SIZE); 2918 memset (scmd, 0, MAX_COMMAND_SIZE);
2919 scmd[0] = READ_POSITION; 2919 scmd[0] = READ_POSITION;
2920 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; 2920 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2921 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE, 2921 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2922 STp->timeout, MAX_RETRIES, 1); 2922 STp->timeout, MAX_RETRIES, 1);
2923 #if DEBUG 2923 #if DEBUG
2924 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n", 2924 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2925 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:", 2925 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2926 SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]); 2926 SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]);
2927 #endif 2927 #endif
2928 if (!STp->buffer->syscall_result) 2928 if (!STp->buffer->syscall_result)
2929 memcpy (SRpnt->sense, mysense, 16); 2929 memcpy (SRpnt->sense, mysense, 16);
2930 else 2930 else
2931 printk(KERN_WARNING "%s:W: Double error in get position\n", name); 2931 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2932 } 2932 }
2933 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24) 2933 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2934 + ((STp->buffer)->b_data[5] << 16) 2934 + ((STp->buffer)->b_data[5] << 16)
2935 + ((STp->buffer)->b_data[6] << 8) 2935 + ((STp->buffer)->b_data[6] << 8)
2936 + (STp->buffer)->b_data[7]; 2936 + (STp->buffer)->b_data[7];
2937 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24) 2937 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2938 + ((STp->buffer)->b_data[ 9] << 16) 2938 + ((STp->buffer)->b_data[ 9] << 16)
2939 + ((STp->buffer)->b_data[10] << 8) 2939 + ((STp->buffer)->b_data[10] << 8)
2940 + (STp->buffer)->b_data[11]; 2940 + (STp->buffer)->b_data[11];
2941 STp->cur_frames = (STp->buffer)->b_data[15]; 2941 STp->cur_frames = (STp->buffer)->b_data[15];
2942 #if DEBUG 2942 #if DEBUG
2943 if (debugging) { 2943 if (debugging) {
2944 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name, 2944 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2945 STp->first_frame_position, STp->last_frame_position, 2945 STp->first_frame_position, STp->last_frame_position,
2946 ((STp->buffer)->b_data[0]&0x80)?" (BOP)": 2946 ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2947 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"", 2947 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2948 STp->cur_frames); 2948 STp->cur_frames);
2949 } 2949 }
2950 #endif 2950 #endif
2951 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) { 2951 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2952 #if DEBUG 2952 #if DEBUG
2953 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name, 2953 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2954 STp->first_frame_position, STp->last_frame_position, STp->cur_frames); 2954 STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2955 #endif 2955 #endif
2956 STp->first_frame_position = STp->last_frame_position; 2956 STp->first_frame_position = STp->last_frame_position;
2957 } 2957 }
2958 } 2958 }
2959 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; 2959 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2960 2960
2961 return (result == 0 ? STp->first_frame_position : result); 2961 return (result == 0 ? STp->first_frame_position : result);
2962 } 2962 }
2963 2963
2964 2964
2965 /* Set the tape block */ 2965 /* Set the tape block */
2966 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip) 2966 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip)
2967 { 2967 {
2968 unsigned char scmd[MAX_COMMAND_SIZE]; 2968 unsigned char scmd[MAX_COMMAND_SIZE];
2969 struct osst_request * SRpnt; 2969 struct osst_request * SRpnt;
2970 struct st_partstat * STps; 2970 struct st_partstat * STps;
2971 int result = 0; 2971 int result = 0;
2972 int pp = (ppos == 3000 && !skip)? 0 : ppos; 2972 int pp = (ppos == 3000 && !skip)? 0 : ppos;
2973 char * name = tape_name(STp); 2973 char * name = tape_name(STp);
2974 2974
2975 if (STp->ready != ST_READY) return (-EIO); 2975 if (STp->ready != ST_READY) return (-EIO);
2976 2976
2977 STps = &(STp->ps[STp->partition]); 2977 STps = &(STp->ps[STp->partition]);
2978 2978
2979 if (ppos < 0 || ppos > STp->capacity) { 2979 if (ppos < 0 || ppos > STp->capacity) {
2980 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos); 2980 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2981 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1); 2981 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2982 result = (-EINVAL); 2982 result = (-EINVAL);
2983 } 2983 }
2984 2984
2985 do { 2985 do {
2986 #if DEBUG 2986 #if DEBUG
2987 if (debugging) 2987 if (debugging)
2988 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp); 2988 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2989 #endif 2989 #endif
2990 memset (scmd, 0, MAX_COMMAND_SIZE); 2990 memset (scmd, 0, MAX_COMMAND_SIZE);
2991 scmd[0] = SEEK_10; 2991 scmd[0] = SEEK_10;
2992 scmd[1] = 1; 2992 scmd[1] = 1;
2993 scmd[3] = (pp >> 24); 2993 scmd[3] = (pp >> 24);
2994 scmd[4] = (pp >> 16); 2994 scmd[4] = (pp >> 16);
2995 scmd[5] = (pp >> 8); 2995 scmd[5] = (pp >> 8);
2996 scmd[6] = pp; 2996 scmd[6] = pp;
2997 if (skip) 2997 if (skip)
2998 scmd[9] = 0x80; 2998 scmd[9] = 0x80;
2999 2999
3000 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout, 3000 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
3001 MAX_RETRIES, 1); 3001 MAX_RETRIES, 1);
3002 if (!SRpnt) 3002 if (!SRpnt)
3003 return (-EBUSY); 3003 return (-EBUSY);
3004 *aSRpnt = SRpnt; 3004 *aSRpnt = SRpnt;
3005 3005
3006 if ((STp->buffer)->syscall_result != 0) { 3006 if ((STp->buffer)->syscall_result != 0) {
3007 #if DEBUG 3007 #if DEBUG
3008 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n", 3008 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
3009 name, STp->first_frame_position, pp); 3009 name, STp->first_frame_position, pp);
3010 #endif 3010 #endif
3011 result = (-EIO); 3011 result = (-EIO);
3012 } 3012 }
3013 if (pp != ppos) 3013 if (pp != ppos)
3014 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE); 3014 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
3015 } while ((pp != ppos) && (pp = ppos)); 3015 } while ((pp != ppos) && (pp = ppos));
3016 STp->first_frame_position = STp->last_frame_position = ppos; 3016 STp->first_frame_position = STp->last_frame_position = ppos;
3017 STps->eof = ST_NOEOF; 3017 STps->eof = ST_NOEOF;
3018 STps->at_sm = 0; 3018 STps->at_sm = 0;
3019 STps->rw = ST_IDLE; 3019 STps->rw = ST_IDLE;
3020 STp->frame_in_buffer = 0; 3020 STp->frame_in_buffer = 0;
3021 return result; 3021 return result;
3022 } 3022 }
3023 3023
3024 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT) 3024 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT)
3025 { 3025 {
3026 struct st_partstat * STps = &(STp->ps[STp->partition]); 3026 struct st_partstat * STps = &(STp->ps[STp->partition]);
3027 int result = 0; 3027 int result = 0;
3028 3028
3029 if (STp->write_type != OS_WRITE_NEW_MARK) { 3029 if (STp->write_type != OS_WRITE_NEW_MARK) {
3030 /* true unless the user wrote the filemark for us */ 3030 /* true unless the user wrote the filemark for us */
3031 result = osst_flush_drive_buffer(STp, aSRpnt); 3031 result = osst_flush_drive_buffer(STp, aSRpnt);
3032 if (result < 0) goto out; 3032 if (result < 0) goto out;
3033 result = osst_write_filemark(STp, aSRpnt); 3033 result = osst_write_filemark(STp, aSRpnt);
3034 if (result < 0) goto out; 3034 if (result < 0) goto out;
3035 3035
3036 if (STps->drv_file >= 0) 3036 if (STps->drv_file >= 0)
3037 STps->drv_file++ ; 3037 STps->drv_file++ ;
3038 STps->drv_block = 0; 3038 STps->drv_block = 0;
3039 } 3039 }
3040 result = osst_write_eod(STp, aSRpnt); 3040 result = osst_write_eod(STp, aSRpnt);
3041 osst_write_header(STp, aSRpnt, leave_at_EOT); 3041 osst_write_header(STp, aSRpnt, leave_at_EOT);
3042 3042
3043 STps->eof = ST_FM; 3043 STps->eof = ST_FM;
3044 out: 3044 out:
3045 return result; 3045 return result;
3046 } 3046 }
3047 3047
3048 /* osst versions of st functions - augmented and stripped to suit OnStream only */ 3048 /* osst versions of st functions - augmented and stripped to suit OnStream only */
3049 3049
3050 /* Flush the write buffer (never need to write if variable blocksize). */ 3050 /* Flush the write buffer (never need to write if variable blocksize). */
3051 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt) 3051 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt)
3052 { 3052 {
3053 int offset, transfer, blks = 0; 3053 int offset, transfer, blks = 0;
3054 int result = 0; 3054 int result = 0;
3055 unsigned char cmd[MAX_COMMAND_SIZE]; 3055 unsigned char cmd[MAX_COMMAND_SIZE];
3056 struct osst_request * SRpnt = *aSRpnt; 3056 struct osst_request * SRpnt = *aSRpnt;
3057 struct st_partstat * STps; 3057 struct st_partstat * STps;
3058 char * name = tape_name(STp); 3058 char * name = tape_name(STp);
3059 3059
3060 if ((STp->buffer)->writing) { 3060 if ((STp->buffer)->writing) {
3061 if (SRpnt == (STp->buffer)->last_SRpnt) 3061 if (SRpnt == (STp->buffer)->last_SRpnt)
3062 #if DEBUG 3062 #if DEBUG
3063 { printk(OSST_DEB_MSG 3063 { printk(OSST_DEB_MSG
3064 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name); 3064 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name);
3065 #endif 3065 #endif
3066 *aSRpnt = SRpnt = NULL; 3066 *aSRpnt = SRpnt = NULL;
3067 #if DEBUG 3067 #if DEBUG
3068 } else if (SRpnt) 3068 } else if (SRpnt)
3069 printk(OSST_DEB_MSG 3069 printk(OSST_DEB_MSG
3070 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name); 3070 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name);
3071 #endif 3071 #endif
3072 osst_write_behind_check(STp); 3072 osst_write_behind_check(STp);
3073 if ((STp->buffer)->syscall_result) { 3073 if ((STp->buffer)->syscall_result) {
3074 #if DEBUG 3074 #if DEBUG
3075 if (debugging) 3075 if (debugging)
3076 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n", 3076 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
3077 name, (STp->buffer)->midlevel_result); 3077 name, (STp->buffer)->midlevel_result);
3078 #endif 3078 #endif
3079 if ((STp->buffer)->midlevel_result == INT_MAX) 3079 if ((STp->buffer)->midlevel_result == INT_MAX)
3080 return (-ENOSPC); 3080 return (-ENOSPC);
3081 return (-EIO); 3081 return (-EIO);
3082 } 3082 }
3083 } 3083 }
3084 3084
3085 result = 0; 3085 result = 0;
3086 if (STp->dirty == 1) { 3086 if (STp->dirty == 1) {
3087 3087
3088 STp->write_count++; 3088 STp->write_count++;
3089 STps = &(STp->ps[STp->partition]); 3089 STps = &(STp->ps[STp->partition]);
3090 STps->rw = ST_WRITING; 3090 STps->rw = ST_WRITING;
3091 offset = STp->buffer->buffer_bytes; 3091 offset = STp->buffer->buffer_bytes;
3092 blks = (offset + STp->block_size - 1) / STp->block_size; 3092 blks = (offset + STp->block_size - 1) / STp->block_size;
3093 transfer = OS_FRAME_SIZE; 3093 transfer = OS_FRAME_SIZE;
3094 3094
3095 if (offset < OS_DATA_SIZE) 3095 if (offset < OS_DATA_SIZE)
3096 osst_zero_buffer_tail(STp->buffer); 3096 osst_zero_buffer_tail(STp->buffer);
3097 3097
3098 if (STp->poll) 3098 if (STp->poll)
3099 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120)) 3099 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
3100 result = osst_recover_wait_frame(STp, aSRpnt, 1); 3100 result = osst_recover_wait_frame(STp, aSRpnt, 1);
3101 3101
3102 memset(cmd, 0, MAX_COMMAND_SIZE); 3102 memset(cmd, 0, MAX_COMMAND_SIZE);
3103 cmd[0] = WRITE_6; 3103 cmd[0] = WRITE_6;
3104 cmd[1] = 1; 3104 cmd[1] = 1;
3105 cmd[4] = 1; 3105 cmd[4] = 1;
3106 3106
3107 switch (STp->write_type) { 3107 switch (STp->write_type) {
3108 case OS_WRITE_DATA: 3108 case OS_WRITE_DATA:
3109 #if DEBUG 3109 #if DEBUG
3110 if (debugging) 3110 if (debugging)
3111 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", 3111 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
3112 name, blks, STp->frame_seq_number, 3112 name, blks, STp->frame_seq_number,
3113 STp->logical_blk_num - blks, STp->logical_blk_num - 1); 3113 STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3114 #endif 3114 #endif
3115 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++, 3115 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3116 STp->logical_blk_num - blks, STp->block_size, blks); 3116 STp->logical_blk_num - blks, STp->block_size, blks);
3117 break; 3117 break;
3118 case OS_WRITE_EOD: 3118 case OS_WRITE_EOD:
3119 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++, 3119 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
3120 STp->logical_blk_num, 0, 0); 3120 STp->logical_blk_num, 0, 0);
3121 break; 3121 break;
3122 case OS_WRITE_NEW_MARK: 3122 case OS_WRITE_NEW_MARK:
3123 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++, 3123 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
3124 STp->logical_blk_num++, 0, blks=1); 3124 STp->logical_blk_num++, 0, blks=1);
3125 break; 3125 break;
3126 case OS_WRITE_HEADER: 3126 case OS_WRITE_HEADER:
3127 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0); 3127 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
3128 break; 3128 break;
3129 default: /* probably FILLER */ 3129 default: /* probably FILLER */
3130 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0); 3130 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
3131 } 3131 }
3132 #if DEBUG 3132 #if DEBUG
3133 if (debugging) 3133 if (debugging)
3134 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transferring %d bytes in %d lblocks.\n", 3134 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transferring %d bytes in %d lblocks.\n",
3135 name, offset, transfer, blks); 3135 name, offset, transfer, blks);
3136 #endif 3136 #endif
3137 3137
3138 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE, 3138 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3139 STp->timeout, MAX_RETRIES, 1); 3139 STp->timeout, MAX_RETRIES, 1);
3140 *aSRpnt = SRpnt; 3140 *aSRpnt = SRpnt;
3141 if (!SRpnt) 3141 if (!SRpnt)
3142 return (-EBUSY); 3142 return (-EBUSY);
3143 3143
3144 if ((STp->buffer)->syscall_result != 0) { 3144 if ((STp->buffer)->syscall_result != 0) {
3145 #if DEBUG 3145 #if DEBUG
3146 printk(OSST_DEB_MSG 3146 printk(OSST_DEB_MSG
3147 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n", 3147 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3148 name, SRpnt->sense[0], SRpnt->sense[2], 3148 name, SRpnt->sense[0], SRpnt->sense[2],
3149 SRpnt->sense[12], SRpnt->sense[13]); 3149 SRpnt->sense[12], SRpnt->sense[13]);
3150 #endif 3150 #endif
3151 if ((SRpnt->sense[0] & 0x70) == 0x70 && 3151 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3152 (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */ 3152 (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3153 (SRpnt->sense[2] & 0x0f) == NO_SENSE) { 3153 (SRpnt->sense[2] & 0x0f) == NO_SENSE) {
3154 STp->dirty = 0; 3154 STp->dirty = 0;
3155 (STp->buffer)->buffer_bytes = 0; 3155 (STp->buffer)->buffer_bytes = 0;
3156 result = (-ENOSPC); 3156 result = (-ENOSPC);
3157 } 3157 }
3158 else { 3158 else {
3159 if (osst_write_error_recovery(STp, aSRpnt, 1)) { 3159 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3160 printk(KERN_ERR "%s:E: Error on flush write.\n", name); 3160 printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3161 result = (-EIO); 3161 result = (-EIO);
3162 } 3162 }
3163 } 3163 }
3164 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */ 3164 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
3165 } 3165 }
3166 else { 3166 else {
3167 STp->first_frame_position++; 3167 STp->first_frame_position++;
3168 STp->dirty = 0; 3168 STp->dirty = 0;
3169 (STp->buffer)->buffer_bytes = 0; 3169 (STp->buffer)->buffer_bytes = 0;
3170 } 3170 }
3171 } 3171 }
3172 #if DEBUG 3172 #if DEBUG
3173 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result); 3173 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3174 #endif 3174 #endif
3175 return result; 3175 return result;
3176 } 3176 }
3177 3177
3178 3178
3179 /* Flush the tape buffer. The tape will be positioned correctly unless 3179 /* Flush the tape buffer. The tape will be positioned correctly unless
3180 seek_next is true. */ 3180 seek_next is true. */
3181 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next) 3181 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next)
3182 { 3182 {
3183 struct st_partstat * STps; 3183 struct st_partstat * STps;
3184 int backspace = 0, result = 0; 3184 int backspace = 0, result = 0;
3185 #if DEBUG 3185 #if DEBUG
3186 char * name = tape_name(STp); 3186 char * name = tape_name(STp);
3187 #endif 3187 #endif
3188 3188
3189 /* 3189 /*
3190 * If there was a bus reset, block further access 3190 * If there was a bus reset, block further access
3191 * to this device. 3191 * to this device.
3192 */ 3192 */
3193 if( STp->pos_unknown) 3193 if( STp->pos_unknown)
3194 return (-EIO); 3194 return (-EIO);
3195 3195
3196 if (STp->ready != ST_READY) 3196 if (STp->ready != ST_READY)
3197 return 0; 3197 return 0;
3198 3198
3199 STps = &(STp->ps[STp->partition]); 3199 STps = &(STp->ps[STp->partition]);
3200 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */ 3200 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
3201 STp->write_type = OS_WRITE_DATA; 3201 STp->write_type = OS_WRITE_DATA;
3202 return osst_flush_write_buffer(STp, aSRpnt); 3202 return osst_flush_write_buffer(STp, aSRpnt);
3203 } 3203 }
3204 if (STp->block_size == 0) 3204 if (STp->block_size == 0)
3205 return 0; 3205 return 0;
3206 3206
3207 #if DEBUG 3207 #if DEBUG
3208 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name); 3208 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3209 #endif 3209 #endif
3210 3210
3211 if (!STp->can_bsr) { 3211 if (!STp->can_bsr) {
3212 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size - 3212 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3213 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ; 3213 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3214 (STp->buffer)->buffer_bytes = 0; 3214 (STp->buffer)->buffer_bytes = 0;
3215 (STp->buffer)->read_pointer = 0; 3215 (STp->buffer)->read_pointer = 0;
3216 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */ 3216 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3217 } 3217 }
3218 3218
3219 if (!seek_next) { 3219 if (!seek_next) {
3220 if (STps->eof == ST_FM_HIT) { 3220 if (STps->eof == ST_FM_HIT) {
3221 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */ 3221 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3222 if (!result) 3222 if (!result)
3223 STps->eof = ST_NOEOF; 3223 STps->eof = ST_NOEOF;
3224 else { 3224 else {
3225 if (STps->drv_file >= 0) 3225 if (STps->drv_file >= 0)
3226 STps->drv_file++; 3226 STps->drv_file++;
3227 STps->drv_block = 0; 3227 STps->drv_block = 0;
3228 } 3228 }
3229 } 3229 }
3230 if (!result && backspace > 0) /* TODO -- design and run a test case for this */ 3230 if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3231 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace); 3231 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3232 } 3232 }
3233 else if (STps->eof == ST_FM_HIT) { 3233 else if (STps->eof == ST_FM_HIT) {
3234 if (STps->drv_file >= 0) 3234 if (STps->drv_file >= 0)
3235 STps->drv_file++; 3235 STps->drv_file++;
3236 STps->drv_block = 0; 3236 STps->drv_block = 0;
3237 STps->eof = ST_NOEOF; 3237 STps->eof = ST_NOEOF;
3238 } 3238 }
3239 3239
3240 return result; 3240 return result;
3241 } 3241 }
3242 3242
3243 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous) 3243 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous)
3244 { 3244 {
3245 unsigned char cmd[MAX_COMMAND_SIZE]; 3245 unsigned char cmd[MAX_COMMAND_SIZE];
3246 struct osst_request * SRpnt; 3246 struct osst_request * SRpnt;
3247 int blks; 3247 int blks;
3248 #if DEBUG 3248 #if DEBUG
3249 char * name = tape_name(STp); 3249 char * name = tape_name(STp);
3250 #endif 3250 #endif
3251 3251
3252 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */ 3252 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3253 #if DEBUG 3253 #if DEBUG
3254 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name); 3254 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3255 #endif 3255 #endif
3256 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) { 3256 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3257 return (-EIO); 3257 return (-EIO);
3258 } 3258 }
3259 /* error recovery may have bumped us past the header partition */ 3259 /* error recovery may have bumped us past the header partition */
3260 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) { 3260 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3261 #if DEBUG 3261 #if DEBUG
3262 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name); 3262 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3263 #endif 3263 #endif
3264 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8); 3264 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3265 } 3265 }
3266 } 3266 }
3267 3267
3268 if (STp->poll) 3268 if (STp->poll)
3269 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120)) 3269 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3270 if (osst_recover_wait_frame(STp, aSRpnt, 1)) 3270 if (osst_recover_wait_frame(STp, aSRpnt, 1))
3271 return (-EIO); 3271 return (-EIO);
3272 3272
3273 // osst_build_stats(STp, &SRpnt); 3273 // osst_build_stats(STp, &SRpnt);
3274 3274
3275 STp->ps[STp->partition].rw = ST_WRITING; 3275 STp->ps[STp->partition].rw = ST_WRITING;
3276 STp->write_type = OS_WRITE_DATA; 3276 STp->write_type = OS_WRITE_DATA;
3277 3277
3278 memset(cmd, 0, MAX_COMMAND_SIZE); 3278 memset(cmd, 0, MAX_COMMAND_SIZE);
3279 cmd[0] = WRITE_6; 3279 cmd[0] = WRITE_6;
3280 cmd[1] = 1; 3280 cmd[1] = 1;
3281 cmd[4] = 1; /* one frame at a time... */ 3281 cmd[4] = 1; /* one frame at a time... */
3282 blks = STp->buffer->buffer_bytes / STp->block_size; 3282 blks = STp->buffer->buffer_bytes / STp->block_size;
3283 #if DEBUG 3283 #if DEBUG
3284 if (debugging) 3284 if (debugging)
3285 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks, 3285 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3286 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1); 3286 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3287 #endif 3287 #endif
3288 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++, 3288 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3289 STp->logical_blk_num - blks, STp->block_size, blks); 3289 STp->logical_blk_num - blks, STp->block_size, blks);
3290 3290
3291 #if DEBUG 3291 #if DEBUG
3292 if (!synchronous) 3292 if (!synchronous)
3293 STp->write_pending = 1; 3293 STp->write_pending = 1;
3294 #endif 3294 #endif
3295 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout, 3295 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3296 MAX_RETRIES, synchronous); 3296 MAX_RETRIES, synchronous);
3297 if (!SRpnt) 3297 if (!SRpnt)
3298 return (-EBUSY); 3298 return (-EBUSY);
3299 *aSRpnt = SRpnt; 3299 *aSRpnt = SRpnt;
3300 3300
3301 if (synchronous) { 3301 if (synchronous) {
3302 if (STp->buffer->syscall_result != 0) { 3302 if (STp->buffer->syscall_result != 0) {
3303 #if DEBUG 3303 #if DEBUG
3304 if (debugging) 3304 if (debugging)
3305 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name); 3305 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3306 #endif 3306 #endif
3307 if ((SRpnt->sense[0] & 0x70) == 0x70 && 3307 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3308 (SRpnt->sense[2] & 0x40)) { 3308 (SRpnt->sense[2] & 0x40)) {
3309 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW) 3309 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW)
3310 return (-ENOSPC); 3310 return (-ENOSPC);
3311 } 3311 }
3312 else { 3312 else {
3313 if (osst_write_error_recovery(STp, aSRpnt, 1)) 3313 if (osst_write_error_recovery(STp, aSRpnt, 1))
3314 return (-EIO); 3314 return (-EIO);
3315 } 3315 }
3316 } 3316 }
3317 else 3317 else
3318 STp->first_frame_position++; 3318 STp->first_frame_position++;
3319 } 3319 }
3320 3320
3321 STp->write_count++; 3321 STp->write_count++;
3322 3322
3323 return 0; 3323 return 0;
3324 } 3324 }
3325 3325
3326 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */ 3326 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */
3327 static int do_door_lock(struct osst_tape * STp, int do_lock) 3327 static int do_door_lock(struct osst_tape * STp, int do_lock)
3328 { 3328 {
3329 int retval, cmd; 3329 int retval, cmd;
3330 3330
3331 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK; 3331 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
3332 #if DEBUG 3332 #if DEBUG
3333 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl"); 3333 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3334 #endif 3334 #endif
3335 retval = scsi_ioctl(STp->device, cmd, NULL); 3335 retval = scsi_ioctl(STp->device, cmd, NULL);
3336 if (!retval) { 3336 if (!retval) {
3337 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED; 3337 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3338 } 3338 }
3339 else { 3339 else {
3340 STp->door_locked = ST_LOCK_FAILS; 3340 STp->door_locked = ST_LOCK_FAILS;
3341 } 3341 }
3342 return retval; 3342 return retval;
3343 } 3343 }
3344 3344
3345 /* Set the internal state after reset */ 3345 /* Set the internal state after reset */
3346 static void reset_state(struct osst_tape *STp) 3346 static void reset_state(struct osst_tape *STp)
3347 { 3347 {
3348 int i; 3348 int i;
3349 struct st_partstat *STps; 3349 struct st_partstat *STps;
3350 3350
3351 STp->pos_unknown = 0; 3351 STp->pos_unknown = 0;
3352 for (i = 0; i < ST_NBR_PARTITIONS; i++) { 3352 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3353 STps = &(STp->ps[i]); 3353 STps = &(STp->ps[i]);
3354 STps->rw = ST_IDLE; 3354 STps->rw = ST_IDLE;
3355 STps->eof = ST_NOEOF; 3355 STps->eof = ST_NOEOF;
3356 STps->at_sm = 0; 3356 STps->at_sm = 0;
3357 STps->last_block_valid = 0; 3357 STps->last_block_valid = 0;
3358 STps->drv_block = -1; 3358 STps->drv_block = -1;
3359 STps->drv_file = -1; 3359 STps->drv_file = -1;
3360 } 3360 }
3361 } 3361 }
3362 3362
3363 3363
3364 /* Entry points to osst */ 3364 /* Entry points to osst */
3365 3365
3366 /* Write command */ 3366 /* Write command */
3367 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos) 3367 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3368 { 3368 {
3369 ssize_t total, retval = 0; 3369 ssize_t total, retval = 0;
3370 ssize_t i, do_count, blks, transfer; 3370 ssize_t i, do_count, blks, transfer;
3371 int write_threshold; 3371 int write_threshold;
3372 int doing_write = 0; 3372 int doing_write = 0;
3373 const char __user * b_point; 3373 const char __user * b_point;
3374 struct osst_request * SRpnt = NULL; 3374 struct osst_request * SRpnt = NULL;
3375 struct st_modedef * STm; 3375 struct st_modedef * STm;
3376 struct st_partstat * STps; 3376 struct st_partstat * STps;
3377 struct osst_tape * STp = filp->private_data; 3377 struct osst_tape * STp = filp->private_data;
3378 char * name = tape_name(STp); 3378 char * name = tape_name(STp);
3379 3379
3380 3380
3381 if (mutex_lock_interruptible(&STp->lock)) 3381 if (mutex_lock_interruptible(&STp->lock))
3382 return (-ERESTARTSYS); 3382 return (-ERESTARTSYS);
3383 3383
3384 /* 3384 /*
3385 * If we are in the middle of error recovery, don't let anyone 3385 * If we are in the middle of error recovery, don't let anyone
3386 * else try and use this device. Also, if error recovery fails, it 3386 * else try and use this device. Also, if error recovery fails, it
3387 * may try and take the device offline, in which case all further 3387 * may try and take the device offline, in which case all further
3388 * access to the device is prohibited. 3388 * access to the device is prohibited.
3389 */ 3389 */
3390 if( !scsi_block_when_processing_errors(STp->device) ) { 3390 if( !scsi_block_when_processing_errors(STp->device) ) {
3391 retval = (-ENXIO); 3391 retval = (-ENXIO);
3392 goto out; 3392 goto out;
3393 } 3393 }
3394 3394
3395 if (STp->ready != ST_READY) { 3395 if (STp->ready != ST_READY) {
3396 if (STp->ready == ST_NO_TAPE) 3396 if (STp->ready == ST_NO_TAPE)
3397 retval = (-ENOMEDIUM); 3397 retval = (-ENOMEDIUM);
3398 else 3398 else
3399 retval = (-EIO); 3399 retval = (-EIO);
3400 goto out; 3400 goto out;
3401 } 3401 }
3402 STm = &(STp->modes[STp->current_mode]); 3402 STm = &(STp->modes[STp->current_mode]);
3403 if (!STm->defined) { 3403 if (!STm->defined) {
3404 retval = (-ENXIO); 3404 retval = (-ENXIO);
3405 goto out; 3405 goto out;
3406 } 3406 }
3407 if (count == 0) 3407 if (count == 0)
3408 goto out; 3408 goto out;
3409 3409
3410 /* 3410 /*
3411 * If there was a bus reset, block further access 3411 * If there was a bus reset, block further access
3412 * to this device. 3412 * to this device.
3413 */ 3413 */
3414 if (STp->pos_unknown) { 3414 if (STp->pos_unknown) {
3415 retval = (-EIO); 3415 retval = (-EIO);
3416 goto out; 3416 goto out;
3417 } 3417 }
3418 3418
3419 #if DEBUG 3419 #if DEBUG
3420 if (!STp->in_use) { 3420 if (!STp->in_use) {
3421 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name); 3421 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3422 retval = (-EIO); 3422 retval = (-EIO);
3423 goto out; 3423 goto out;
3424 } 3424 }
3425 #endif 3425 #endif
3426 3426
3427 if (STp->write_prot) { 3427 if (STp->write_prot) {
3428 retval = (-EACCES); 3428 retval = (-EACCES);
3429 goto out; 3429 goto out;
3430 } 3430 }
3431 3431
3432 /* Write must be integral number of blocks */ 3432 /* Write must be integral number of blocks */
3433 if (STp->block_size != 0 && (count % STp->block_size) != 0) { 3433 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3434 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n", 3434 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3435 name, count, STp->block_size<1024? 3435 name, count, STp->block_size<1024?
3436 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k'); 3436 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3437 retval = (-EINVAL); 3437 retval = (-EINVAL);
3438 goto out; 3438 goto out;
3439 } 3439 }
3440 3440
3441 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) { 3441 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3442 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n", 3442 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3443 name, STp->first_frame_position); 3443 name, STp->first_frame_position);
3444 retval = (-ENOSPC); 3444 retval = (-ENOSPC);
3445 goto out; 3445 goto out;
3446 } 3446 }
3447 3447
3448 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1)) 3448 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3449 STp->door_locked = ST_LOCKED_AUTO; 3449 STp->door_locked = ST_LOCKED_AUTO;
3450 3450
3451 STps = &(STp->ps[STp->partition]); 3451 STps = &(STp->ps[STp->partition]);
3452 3452
3453 if (STps->rw == ST_READING) { 3453 if (STps->rw == ST_READING) {
3454 #if DEBUG 3454 #if DEBUG
3455 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name, 3455 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3456 STps->drv_file, STps->drv_block); 3456 STps->drv_file, STps->drv_block);
3457 #endif 3457 #endif
3458 retval = osst_flush_buffer(STp, &SRpnt, 0); 3458 retval = osst_flush_buffer(STp, &SRpnt, 0);
3459 if (retval) 3459 if (retval)
3460 goto out; 3460 goto out;
3461 STps->rw = ST_IDLE; 3461 STps->rw = ST_IDLE;
3462 } 3462 }
3463 if (STps->rw != ST_WRITING) { 3463 if (STps->rw != ST_WRITING) {
3464 /* Are we totally rewriting this tape? */ 3464 /* Are we totally rewriting this tape? */
3465 if (!STp->header_ok || 3465 if (!STp->header_ok ||
3466 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) || 3466 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3467 (STps->drv_file == 0 && STps->drv_block == 0)) { 3467 (STps->drv_file == 0 && STps->drv_block == 0)) {
3468 STp->wrt_pass_cntr++; 3468 STp->wrt_pass_cntr++;
3469 #if DEBUG 3469 #if DEBUG
3470 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n", 3470 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3471 name, STp->wrt_pass_cntr); 3471 name, STp->wrt_pass_cntr);
3472 #endif 3472 #endif
3473 osst_reset_header(STp, &SRpnt); 3473 osst_reset_header(STp, &SRpnt);
3474 STps->drv_file = STps->drv_block = 0; 3474 STps->drv_file = STps->drv_block = 0;
3475 } 3475 }
3476 /* Do we know where we'll be writing on the tape? */ 3476 /* Do we know where we'll be writing on the tape? */
3477 else { 3477 else {
3478 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) || 3478 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3479 STps->drv_file < 0 || STps->drv_block < 0) { 3479 STps->drv_file < 0 || STps->drv_block < 0) {
3480 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */ 3480 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3481 STps->drv_file = STp->filemark_cnt; 3481 STps->drv_file = STp->filemark_cnt;
3482 STps->drv_block = 0; 3482 STps->drv_block = 0;
3483 } 3483 }
3484 else { 3484 else {
3485 /* We have no idea where the tape is positioned - give up */ 3485 /* We have no idea where the tape is positioned - give up */
3486 #if DEBUG 3486 #if DEBUG
3487 printk(OSST_DEB_MSG 3487 printk(OSST_DEB_MSG
3488 "%s:D: Cannot write at indeterminate position.\n", name); 3488 "%s:D: Cannot write at indeterminate position.\n", name);
3489 #endif 3489 #endif
3490 retval = (-EIO); 3490 retval = (-EIO);
3491 goto out; 3491 goto out;
3492 } 3492 }
3493 } 3493 }
3494 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) { 3494 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3495 STp->filemark_cnt = STps->drv_file; 3495 STp->filemark_cnt = STps->drv_file;
3496 STp->last_mark_ppos = 3496 STp->last_mark_ppos =
3497 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]); 3497 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3498 printk(KERN_WARNING 3498 printk(KERN_WARNING
3499 "%s:W: Overwriting file %d with old write pass counter %d\n", 3499 "%s:W: Overwriting file %d with old write pass counter %d\n",
3500 name, STps->drv_file, STp->wrt_pass_cntr); 3500 name, STps->drv_file, STp->wrt_pass_cntr);
3501 printk(KERN_WARNING 3501 printk(KERN_WARNING
3502 "%s:W: may lead to stale data being accepted on reading back!\n", 3502 "%s:W: may lead to stale data being accepted on reading back!\n",
3503 name); 3503 name);
3504 #if DEBUG 3504 #if DEBUG
3505 printk(OSST_DEB_MSG 3505 printk(OSST_DEB_MSG
3506 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n", 3506 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3507 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn); 3507 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3508 #endif 3508 #endif
3509 } 3509 }
3510 } 3510 }
3511 STp->fast_open = 0; 3511 STp->fast_open = 0;
3512 } 3512 }
3513 if (!STp->header_ok) { 3513 if (!STp->header_ok) {
3514 #if DEBUG 3514 #if DEBUG
3515 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name); 3515 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3516 #endif 3516 #endif
3517 retval = (-EIO); 3517 retval = (-EIO);
3518 goto out; 3518 goto out;
3519 } 3519 }
3520 3520
3521 if ((STp->buffer)->writing) { 3521 if ((STp->buffer)->writing) {
3522 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__); 3522 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3523 osst_write_behind_check(STp); 3523 osst_write_behind_check(STp);
3524 if ((STp->buffer)->syscall_result) { 3524 if ((STp->buffer)->syscall_result) {
3525 #if DEBUG 3525 #if DEBUG
3526 if (debugging) 3526 if (debugging)
3527 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name, 3527 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3528 (STp->buffer)->midlevel_result); 3528 (STp->buffer)->midlevel_result);
3529 #endif 3529 #endif
3530 if ((STp->buffer)->midlevel_result == INT_MAX) 3530 if ((STp->buffer)->midlevel_result == INT_MAX)
3531 STps->eof = ST_EOM_OK; 3531 STps->eof = ST_EOM_OK;
3532 else 3532 else
3533 STps->eof = ST_EOM_ERROR; 3533 STps->eof = ST_EOM_ERROR;
3534 } 3534 }
3535 } 3535 }
3536 if (STps->eof == ST_EOM_OK) { 3536 if (STps->eof == ST_EOM_OK) {
3537 retval = (-ENOSPC); 3537 retval = (-ENOSPC);
3538 goto out; 3538 goto out;
3539 } 3539 }
3540 else if (STps->eof == ST_EOM_ERROR) { 3540 else if (STps->eof == ST_EOM_ERROR) {
3541 retval = (-EIO); 3541 retval = (-EIO);
3542 goto out; 3542 goto out;
3543 } 3543 }
3544 3544
3545 /* Check the buffer readability in cases where copy_user might catch 3545 /* Check the buffer readability in cases where copy_user might catch
3546 the problems after some tape movement. */ 3546 the problems after some tape movement. */
3547 if ((copy_from_user(&i, buf, 1) != 0 || 3547 if ((copy_from_user(&i, buf, 1) != 0 ||
3548 copy_from_user(&i, buf + count - 1, 1) != 0)) { 3548 copy_from_user(&i, buf + count - 1, 1) != 0)) {
3549 retval = (-EFAULT); 3549 retval = (-EFAULT);
3550 goto out; 3550 goto out;
3551 } 3551 }
3552 3552
3553 if (!STm->do_buffer_writes) { 3553 if (!STm->do_buffer_writes) {
3554 write_threshold = 1; 3554 write_threshold = 1;
3555 } 3555 }
3556 else 3556 else
3557 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size; 3557 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3558 if (!STm->do_async_writes) 3558 if (!STm->do_async_writes)
3559 write_threshold--; 3559 write_threshold--;
3560 3560
3561 total = count; 3561 total = count;
3562 #if DEBUG 3562 #if DEBUG
3563 if (debugging) 3563 if (debugging)
3564 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n", 3564 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3565 name, (int) count, STps->drv_file, STps->drv_block, 3565 name, (int) count, STps->drv_file, STps->drv_block,
3566 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position); 3566 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3567 #endif 3567 #endif
3568 b_point = buf; 3568 b_point = buf;
3569 while ((STp->buffer)->buffer_bytes + count > write_threshold) 3569 while ((STp->buffer)->buffer_bytes + count > write_threshold)
3570 { 3570 {
3571 doing_write = 1; 3571 doing_write = 1;
3572 do_count = (STp->buffer)->buffer_blocks * STp->block_size - 3572 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3573 (STp->buffer)->buffer_bytes; 3573 (STp->buffer)->buffer_bytes;
3574 if (do_count > count) 3574 if (do_count > count)
3575 do_count = count; 3575 do_count = count;
3576 3576
3577 i = append_to_buffer(b_point, STp->buffer, do_count); 3577 i = append_to_buffer(b_point, STp->buffer, do_count);
3578 if (i) { 3578 if (i) {
3579 retval = i; 3579 retval = i;
3580 goto out; 3580 goto out;
3581 } 3581 }
3582 3582
3583 blks = do_count / STp->block_size; 3583 blks = do_count / STp->block_size;
3584 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */ 3584 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3585 3585
3586 i = osst_write_frame(STp, &SRpnt, 1); 3586 i = osst_write_frame(STp, &SRpnt, 1);
3587 3587
3588 if (i == (-ENOSPC)) { 3588 if (i == (-ENOSPC)) {
3589 transfer = STp->buffer->writing; /* FIXME -- check this logic */ 3589 transfer = STp->buffer->writing; /* FIXME -- check this logic */
3590 if (transfer <= do_count) { 3590 if (transfer <= do_count) {
3591 *ppos += do_count - transfer; 3591 *ppos += do_count - transfer;
3592 count -= do_count - transfer; 3592 count -= do_count - transfer;
3593 if (STps->drv_block >= 0) { 3593 if (STps->drv_block >= 0) {
3594 STps->drv_block += (do_count - transfer) / STp->block_size; 3594 STps->drv_block += (do_count - transfer) / STp->block_size;
3595 } 3595 }
3596 STps->eof = ST_EOM_OK; 3596 STps->eof = ST_EOM_OK;
3597 retval = (-ENOSPC); /* EOM within current request */ 3597 retval = (-ENOSPC); /* EOM within current request */
3598 #if DEBUG 3598 #if DEBUG
3599 if (debugging) 3599 if (debugging)
3600 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n", 3600 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3601 name, (int) transfer); 3601 name, (int) transfer);
3602 #endif 3602 #endif
3603 } 3603 }
3604 else { 3604 else {
3605 STps->eof = ST_EOM_ERROR; 3605 STps->eof = ST_EOM_ERROR;
3606 STps->drv_block = (-1); /* Too cautious? */ 3606 STps->drv_block = (-1); /* Too cautious? */
3607 retval = (-EIO); /* EOM for old data */ 3607 retval = (-EIO); /* EOM for old data */
3608 #if DEBUG 3608 #if DEBUG
3609 if (debugging) 3609 if (debugging)
3610 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name); 3610 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3611 #endif 3611 #endif
3612 } 3612 }
3613 } 3613 }
3614 else 3614 else
3615 retval = i; 3615 retval = i;
3616 3616
3617 if (retval < 0) { 3617 if (retval < 0) {
3618 if (SRpnt != NULL) { 3618 if (SRpnt != NULL) {
3619 osst_release_request(SRpnt); 3619 osst_release_request(SRpnt);
3620 SRpnt = NULL; 3620 SRpnt = NULL;
3621 } 3621 }
3622 STp->buffer->buffer_bytes = 0; 3622 STp->buffer->buffer_bytes = 0;
3623 STp->dirty = 0; 3623 STp->dirty = 0;
3624 if (count < total) 3624 if (count < total)
3625 retval = total - count; 3625 retval = total - count;
3626 goto out; 3626 goto out;
3627 } 3627 }
3628 3628
3629 *ppos += do_count; 3629 *ppos += do_count;
3630 b_point += do_count; 3630 b_point += do_count;
3631 count -= do_count; 3631 count -= do_count;
3632 if (STps->drv_block >= 0) { 3632 if (STps->drv_block >= 0) {
3633 STps->drv_block += blks; 3633 STps->drv_block += blks;
3634 } 3634 }
3635 STp->buffer->buffer_bytes = 0; 3635 STp->buffer->buffer_bytes = 0;
3636 STp->dirty = 0; 3636 STp->dirty = 0;
3637 } /* end while write threshold exceeded */ 3637 } /* end while write threshold exceeded */
3638 3638
3639 if (count != 0) { 3639 if (count != 0) {
3640 STp->dirty = 1; 3640 STp->dirty = 1;
3641 i = append_to_buffer(b_point, STp->buffer, count); 3641 i = append_to_buffer(b_point, STp->buffer, count);
3642 if (i) { 3642 if (i) {
3643 retval = i; 3643 retval = i;
3644 goto out; 3644 goto out;
3645 } 3645 }
3646 blks = count / STp->block_size; 3646 blks = count / STp->block_size;
3647 STp->logical_blk_num += blks; 3647 STp->logical_blk_num += blks;
3648 if (STps->drv_block >= 0) { 3648 if (STps->drv_block >= 0) {
3649 STps->drv_block += blks; 3649 STps->drv_block += blks;
3650 } 3650 }
3651 *ppos += count; 3651 *ppos += count;
3652 count = 0; 3652 count = 0;
3653 } 3653 }
3654 3654
3655 if (doing_write && (STp->buffer)->syscall_result != 0) { 3655 if (doing_write && (STp->buffer)->syscall_result != 0) {
3656 retval = (STp->buffer)->syscall_result; 3656 retval = (STp->buffer)->syscall_result;
3657 goto out; 3657 goto out;
3658 } 3658 }
3659 3659
3660 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) { 3660 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3661 /* Schedule an asynchronous write */ 3661 /* Schedule an asynchronous write */
3662 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes / 3662 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3663 STp->block_size) * STp->block_size; 3663 STp->block_size) * STp->block_size;
3664 STp->dirty = !((STp->buffer)->writing == 3664 STp->dirty = !((STp->buffer)->writing ==
3665 (STp->buffer)->buffer_bytes); 3665 (STp->buffer)->buffer_bytes);
3666 3666
3667 i = osst_write_frame(STp, &SRpnt, 0); 3667 i = osst_write_frame(STp, &SRpnt, 0);
3668 if (i < 0) { 3668 if (i < 0) {
3669 retval = (-EIO); 3669 retval = (-EIO);
3670 goto out; 3670 goto out;
3671 } 3671 }
3672 SRpnt = NULL; /* Prevent releasing this request! */ 3672 SRpnt = NULL; /* Prevent releasing this request! */
3673 } 3673 }
3674 STps->at_sm &= (total == 0); 3674 STps->at_sm &= (total == 0);
3675 if (total > 0) 3675 if (total > 0)
3676 STps->eof = ST_NOEOF; 3676 STps->eof = ST_NOEOF;
3677 3677
3678 retval = total; 3678 retval = total;
3679 3679
3680 out: 3680 out:
3681 if (SRpnt != NULL) osst_release_request(SRpnt); 3681 if (SRpnt != NULL) osst_release_request(SRpnt);
3682 3682
3683 mutex_unlock(&STp->lock); 3683 mutex_unlock(&STp->lock);
3684 3684
3685 return retval; 3685 return retval;
3686 } 3686 }
3687 3687
3688 3688
3689 /* Read command */ 3689 /* Read command */
3690 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos) 3690 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3691 { 3691 {
3692 ssize_t total, retval = 0; 3692 ssize_t total, retval = 0;
3693 ssize_t i, transfer; 3693 ssize_t i, transfer;
3694 int special; 3694 int special;
3695 struct st_modedef * STm; 3695 struct st_modedef * STm;
3696 struct st_partstat * STps; 3696 struct st_partstat * STps;
3697 struct osst_request * SRpnt = NULL; 3697 struct osst_request * SRpnt = NULL;
3698 struct osst_tape * STp = filp->private_data; 3698 struct osst_tape * STp = filp->private_data;
3699 char * name = tape_name(STp); 3699 char * name = tape_name(STp);
3700 3700
3701 3701
3702 if (mutex_lock_interruptible(&STp->lock)) 3702 if (mutex_lock_interruptible(&STp->lock))
3703 return (-ERESTARTSYS); 3703 return (-ERESTARTSYS);
3704 3704
3705 /* 3705 /*
3706 * If we are in the middle of error recovery, don't let anyone 3706 * If we are in the middle of error recovery, don't let anyone
3707 * else try and use this device. Also, if error recovery fails, it 3707 * else try and use this device. Also, if error recovery fails, it
3708 * may try and take the device offline, in which case all further 3708 * may try and take the device offline, in which case all further
3709 * access to the device is prohibited. 3709 * access to the device is prohibited.
3710 */ 3710 */
3711 if( !scsi_block_when_processing_errors(STp->device) ) { 3711 if( !scsi_block_when_processing_errors(STp->device) ) {
3712 retval = (-ENXIO); 3712 retval = (-ENXIO);
3713 goto out; 3713 goto out;
3714 } 3714 }
3715 3715
3716 if (STp->ready != ST_READY) { 3716 if (STp->ready != ST_READY) {
3717 if (STp->ready == ST_NO_TAPE) 3717 if (STp->ready == ST_NO_TAPE)
3718 retval = (-ENOMEDIUM); 3718 retval = (-ENOMEDIUM);
3719 else 3719 else
3720 retval = (-EIO); 3720 retval = (-EIO);
3721 goto out; 3721 goto out;
3722 } 3722 }
3723 STm = &(STp->modes[STp->current_mode]); 3723 STm = &(STp->modes[STp->current_mode]);
3724 if (!STm->defined) { 3724 if (!STm->defined) {
3725 retval = (-ENXIO); 3725 retval = (-ENXIO);
3726 goto out; 3726 goto out;
3727 } 3727 }
3728 #if DEBUG 3728 #if DEBUG
3729 if (!STp->in_use) { 3729 if (!STp->in_use) {
3730 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name); 3730 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3731 retval = (-EIO); 3731 retval = (-EIO);
3732 goto out; 3732 goto out;
3733 } 3733 }
3734 #endif 3734 #endif
3735 /* Must have initialized medium */ 3735 /* Must have initialized medium */
3736 if (!STp->header_ok) { 3736 if (!STp->header_ok) {
3737 retval = (-EIO); 3737 retval = (-EIO);
3738 goto out; 3738 goto out;
3739 } 3739 }
3740 3740
3741 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1)) 3741 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3742 STp->door_locked = ST_LOCKED_AUTO; 3742 STp->door_locked = ST_LOCKED_AUTO;
3743 3743
3744 STps = &(STp->ps[STp->partition]); 3744 STps = &(STp->ps[STp->partition]);
3745 if (STps->rw == ST_WRITING) { 3745 if (STps->rw == ST_WRITING) {
3746 retval = osst_flush_buffer(STp, &SRpnt, 0); 3746 retval = osst_flush_buffer(STp, &SRpnt, 0);
3747 if (retval) 3747 if (retval)
3748 goto out; 3748 goto out;
3749 STps->rw = ST_IDLE; 3749 STps->rw = ST_IDLE;
3750 /* FIXME -- this may leave the tape without EOD and up2date headers */ 3750 /* FIXME -- this may leave the tape without EOD and up2date headers */
3751 } 3751 }
3752 3752
3753 if ((count % STp->block_size) != 0) { 3753 if ((count % STp->block_size) != 0) {
3754 printk(KERN_WARNING 3754 printk(KERN_WARNING
3755 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count, 3755 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3756 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k'); 3756 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3757 } 3757 }
3758 3758
3759 #if DEBUG 3759 #if DEBUG
3760 if (debugging && STps->eof != ST_NOEOF) 3760 if (debugging && STps->eof != ST_NOEOF)
3761 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name, 3761 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3762 STps->eof, (STp->buffer)->buffer_bytes); 3762 STps->eof, (STp->buffer)->buffer_bytes);
3763 #endif 3763 #endif
3764 if ((STp->buffer)->buffer_bytes == 0 && 3764 if ((STp->buffer)->buffer_bytes == 0 &&
3765 STps->eof >= ST_EOD_1) { 3765 STps->eof >= ST_EOD_1) {
3766 if (STps->eof < ST_EOD) { 3766 if (STps->eof < ST_EOD) {
3767 STps->eof += 1; 3767 STps->eof += 1;
3768 retval = 0; 3768 retval = 0;
3769 goto out; 3769 goto out;
3770 } 3770 }
3771 retval = (-EIO); /* EOM or Blank Check */ 3771 retval = (-EIO); /* EOM or Blank Check */
3772 goto out; 3772 goto out;
3773 } 3773 }
3774 3774
3775 /* Check the buffer writability before any tape movement. Don't alter 3775 /* Check the buffer writability before any tape movement. Don't alter
3776 buffer data. */ 3776 buffer data. */
3777 if (copy_from_user(&i, buf, 1) != 0 || 3777 if (copy_from_user(&i, buf, 1) != 0 ||
3778 copy_to_user (buf, &i, 1) != 0 || 3778 copy_to_user (buf, &i, 1) != 0 ||
3779 copy_from_user(&i, buf + count - 1, 1) != 0 || 3779 copy_from_user(&i, buf + count - 1, 1) != 0 ||
3780 copy_to_user (buf + count - 1, &i, 1) != 0) { 3780 copy_to_user (buf + count - 1, &i, 1) != 0) {
3781 retval = (-EFAULT); 3781 retval = (-EFAULT);
3782 goto out; 3782 goto out;
3783 } 3783 }
3784 3784
3785 /* Loop until enough data in buffer or a special condition found */ 3785 /* Loop until enough data in buffer or a special condition found */
3786 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) { 3786 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3787 3787
3788 /* Get new data if the buffer is empty */ 3788 /* Get new data if the buffer is empty */
3789 if ((STp->buffer)->buffer_bytes == 0) { 3789 if ((STp->buffer)->buffer_bytes == 0) {
3790 if (STps->eof == ST_FM_HIT) 3790 if (STps->eof == ST_FM_HIT)
3791 break; 3791 break;
3792 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0); 3792 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3793 if (special < 0) { /* No need to continue read */ 3793 if (special < 0) { /* No need to continue read */
3794 STp->frame_in_buffer = 0; 3794 STp->frame_in_buffer = 0;
3795 retval = special; 3795 retval = special;
3796 goto out; 3796 goto out;
3797 } 3797 }
3798 } 3798 }
3799 3799
3800 /* Move the data from driver buffer to user buffer */ 3800 /* Move the data from driver buffer to user buffer */
3801 if ((STp->buffer)->buffer_bytes > 0) { 3801 if ((STp->buffer)->buffer_bytes > 0) {
3802 #if DEBUG 3802 #if DEBUG
3803 if (debugging && STps->eof != ST_NOEOF) 3803 if (debugging && STps->eof != ST_NOEOF)
3804 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name, 3804 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3805 STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total)); 3805 STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total));
3806 #endif 3806 #endif
3807 /* force multiple of block size, note block_size may have been adjusted */ 3807 /* force multiple of block size, note block_size may have been adjusted */
3808 transfer = (((STp->buffer)->buffer_bytes < count - total ? 3808 transfer = (((STp->buffer)->buffer_bytes < count - total ?
3809 (STp->buffer)->buffer_bytes : count - total)/ 3809 (STp->buffer)->buffer_bytes : count - total)/
3810 STp->block_size) * STp->block_size; 3810 STp->block_size) * STp->block_size;
3811 3811
3812 if (transfer == 0) { 3812 if (transfer == 0) {
3813 printk(KERN_WARNING 3813 printk(KERN_WARNING
3814 "%s:W: Nothing can be transferred, requested %Zd, tape block size (%d%c).\n", 3814 "%s:W: Nothing can be transferred, requested %Zd, tape block size (%d%c).\n",
3815 name, count, STp->block_size < 1024? 3815 name, count, STp->block_size < 1024?
3816 STp->block_size:STp->block_size/1024, 3816 STp->block_size:STp->block_size/1024,
3817 STp->block_size<1024?'b':'k'); 3817 STp->block_size<1024?'b':'k');
3818 break; 3818 break;
3819 } 3819 }
3820 i = from_buffer(STp->buffer, buf, transfer); 3820 i = from_buffer(STp->buffer, buf, transfer);
3821 if (i) { 3821 if (i) {
3822 retval = i; 3822 retval = i;
3823 goto out; 3823 goto out;
3824 } 3824 }
3825 STp->logical_blk_num += transfer / STp->block_size; 3825 STp->logical_blk_num += transfer / STp->block_size;
3826 STps->drv_block += transfer / STp->block_size; 3826 STps->drv_block += transfer / STp->block_size;
3827 *ppos += transfer; 3827 *ppos += transfer;
3828 buf += transfer; 3828 buf += transfer;
3829 total += transfer; 3829 total += transfer;
3830 } 3830 }
3831 3831
3832 if ((STp->buffer)->buffer_bytes == 0) { 3832 if ((STp->buffer)->buffer_bytes == 0) {
3833 #if DEBUG 3833 #if DEBUG
3834 if (debugging) 3834 if (debugging)
3835 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n", 3835 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3836 name, STp->frame_seq_number); 3836 name, STp->frame_seq_number);
3837 #endif 3837 #endif
3838 STp->frame_in_buffer = 0; 3838 STp->frame_in_buffer = 0;
3839 STp->frame_seq_number++; /* frame to look for next time */ 3839 STp->frame_seq_number++; /* frame to look for next time */
3840 } 3840 }
3841 } /* for (total = 0, special = 0; total < count && !special; ) */ 3841 } /* for (total = 0, special = 0; total < count && !special; ) */
3842 3842
3843 /* Change the eof state if no data from tape or buffer */ 3843 /* Change the eof state if no data from tape or buffer */
3844 if (total == 0) { 3844 if (total == 0) {
3845 if (STps->eof == ST_FM_HIT) { 3845 if (STps->eof == ST_FM_HIT) {
3846 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM; 3846 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3847 STps->drv_block = 0; 3847 STps->drv_block = 0;
3848 if (STps->drv_file >= 0) 3848 if (STps->drv_file >= 0)
3849 STps->drv_file++; 3849 STps->drv_file++;
3850 } 3850 }
3851 else if (STps->eof == ST_EOD_1) { 3851 else if (STps->eof == ST_EOD_1) {
3852 STps->eof = ST_EOD_2; 3852 STps->eof = ST_EOD_2;
3853 if (STps->drv_block > 0 && STps->drv_file >= 0) 3853 if (STps->drv_block > 0 && STps->drv_file >= 0)
3854 STps->drv_file++; 3854 STps->drv_file++;
3855 STps->drv_block = 0; 3855 STps->drv_block = 0;
3856 } 3856 }
3857 else if (STps->eof == ST_EOD_2) 3857 else if (STps->eof == ST_EOD_2)
3858 STps->eof = ST_EOD; 3858 STps->eof = ST_EOD;
3859 } 3859 }
3860 else if (STps->eof == ST_FM) 3860 else if (STps->eof == ST_FM)
3861 STps->eof = ST_NOEOF; 3861 STps->eof = ST_NOEOF;
3862 3862
3863 retval = total; 3863 retval = total;
3864 3864
3865 out: 3865 out:
3866 if (SRpnt != NULL) osst_release_request(SRpnt); 3866 if (SRpnt != NULL) osst_release_request(SRpnt);
3867 3867
3868 mutex_unlock(&STp->lock); 3868 mutex_unlock(&STp->lock);
3869 3869
3870 return retval; 3870 return retval;
3871 } 3871 }
3872 3872
3873 3873
3874 /* Set the driver options */ 3874 /* Set the driver options */
3875 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name) 3875 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3876 { 3876 {
3877 printk(KERN_INFO 3877 printk(KERN_INFO
3878 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n", 3878 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3879 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes, 3879 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3880 STm->do_read_ahead); 3880 STm->do_read_ahead);
3881 printk(KERN_INFO 3881 printk(KERN_INFO
3882 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n", 3882 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3883 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock); 3883 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3884 printk(KERN_INFO 3884 printk(KERN_INFO
3885 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n", 3885 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3886 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions, 3886 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3887 STp->scsi2_logical); 3887 STp->scsi2_logical);
3888 printk(KERN_INFO 3888 printk(KERN_INFO
3889 "%s:I: sysv: %d\n", name, STm->sysv); 3889 "%s:I: sysv: %d\n", name, STm->sysv);
3890 #if DEBUG 3890 #if DEBUG
3891 printk(KERN_INFO 3891 printk(KERN_INFO
3892 "%s:D: debugging: %d\n", 3892 "%s:D: debugging: %d\n",
3893 name, debugging); 3893 name, debugging);
3894 #endif 3894 #endif
3895 } 3895 }
3896 3896
3897 3897
3898 static int osst_set_options(struct osst_tape *STp, long options) 3898 static int osst_set_options(struct osst_tape *STp, long options)
3899 { 3899 {
3900 int value; 3900 int value;
3901 long code; 3901 long code;
3902 struct st_modedef * STm; 3902 struct st_modedef * STm;
3903 char * name = tape_name(STp); 3903 char * name = tape_name(STp);
3904 3904
3905 STm = &(STp->modes[STp->current_mode]); 3905 STm = &(STp->modes[STp->current_mode]);
3906 if (!STm->defined) { 3906 if (!STm->defined) {
3907 memcpy(STm, &(STp->modes[0]), sizeof(*STm)); 3907 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3908 modes_defined = 1; 3908 modes_defined = 1;
3909 #if DEBUG 3909 #if DEBUG
3910 if (debugging) 3910 if (debugging)
3911 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n", 3911 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3912 name, STp->current_mode); 3912 name, STp->current_mode);
3913 #endif 3913 #endif
3914 } 3914 }
3915 3915
3916 code = options & MT_ST_OPTIONS; 3916 code = options & MT_ST_OPTIONS;
3917 if (code == MT_ST_BOOLEANS) { 3917 if (code == MT_ST_BOOLEANS) {
3918 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0; 3918 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3919 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0; 3919 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3920 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0; 3920 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3921 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0; 3921 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3922 STp->two_fm = (options & MT_ST_TWO_FM) != 0; 3922 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3923 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0; 3923 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3924 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0; 3924 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3925 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0; 3925 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3926 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0; 3926 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3927 if ((STp->device)->scsi_level >= SCSI_2) 3927 if ((STp->device)->scsi_level >= SCSI_2)
3928 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0; 3928 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3929 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0; 3929 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3930 STm->sysv = (options & MT_ST_SYSV) != 0; 3930 STm->sysv = (options & MT_ST_SYSV) != 0;
3931 #if DEBUG 3931 #if DEBUG
3932 debugging = (options & MT_ST_DEBUGGING) != 0; 3932 debugging = (options & MT_ST_DEBUGGING) != 0;
3933 #endif 3933 #endif
3934 osst_log_options(STp, STm, name); 3934 osst_log_options(STp, STm, name);
3935 } 3935 }
3936 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) { 3936 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3937 value = (code == MT_ST_SETBOOLEANS); 3937 value = (code == MT_ST_SETBOOLEANS);
3938 if ((options & MT_ST_BUFFER_WRITES) != 0) 3938 if ((options & MT_ST_BUFFER_WRITES) != 0)
3939 STm->do_buffer_writes = value; 3939 STm->do_buffer_writes = value;
3940 if ((options & MT_ST_ASYNC_WRITES) != 0) 3940 if ((options & MT_ST_ASYNC_WRITES) != 0)
3941 STm->do_async_writes = value; 3941 STm->do_async_writes = value;
3942 if ((options & MT_ST_DEF_WRITES) != 0) 3942 if ((options & MT_ST_DEF_WRITES) != 0)
3943 STm->defaults_for_writes = value; 3943 STm->defaults_for_writes = value;
3944 if ((options & MT_ST_READ_AHEAD) != 0) 3944 if ((options & MT_ST_READ_AHEAD) != 0)
3945 STm->do_read_ahead = value; 3945 STm->do_read_ahead = value;
3946 if ((options & MT_ST_TWO_FM) != 0) 3946 if ((options & MT_ST_TWO_FM) != 0)
3947 STp->two_fm = value; 3947 STp->two_fm = value;
3948 if ((options & MT_ST_FAST_MTEOM) != 0) 3948 if ((options & MT_ST_FAST_MTEOM) != 0)
3949 STp->fast_mteom = value; 3949 STp->fast_mteom = value;
3950 if ((options & MT_ST_AUTO_LOCK) != 0) 3950 if ((options & MT_ST_AUTO_LOCK) != 0)
3951 STp->do_auto_lock = value; 3951 STp->do_auto_lock = value;
3952 if ((options & MT_ST_CAN_BSR) != 0) 3952 if ((options & MT_ST_CAN_BSR) != 0)
3953 STp->can_bsr = value; 3953 STp->can_bsr = value;
3954 if ((options & MT_ST_NO_BLKLIMS) != 0) 3954 if ((options & MT_ST_NO_BLKLIMS) != 0)
3955 STp->omit_blklims = value; 3955 STp->omit_blklims = value;
3956 if ((STp->device)->scsi_level >= SCSI_2 && 3956 if ((STp->device)->scsi_level >= SCSI_2 &&
3957 (options & MT_ST_CAN_PARTITIONS) != 0) 3957 (options & MT_ST_CAN_PARTITIONS) != 0)
3958 STp->can_partitions = value; 3958 STp->can_partitions = value;
3959 if ((options & MT_ST_SCSI2LOGICAL) != 0) 3959 if ((options & MT_ST_SCSI2LOGICAL) != 0)
3960 STp->scsi2_logical = value; 3960 STp->scsi2_logical = value;
3961 if ((options & MT_ST_SYSV) != 0) 3961 if ((options & MT_ST_SYSV) != 0)
3962 STm->sysv = value; 3962 STm->sysv = value;
3963 #if DEBUG 3963 #if DEBUG
3964 if ((options & MT_ST_DEBUGGING) != 0) 3964 if ((options & MT_ST_DEBUGGING) != 0)
3965 debugging = value; 3965 debugging = value;
3966 #endif 3966 #endif
3967 osst_log_options(STp, STm, name); 3967 osst_log_options(STp, STm, name);
3968 } 3968 }
3969 else if (code == MT_ST_WRITE_THRESHOLD) { 3969 else if (code == MT_ST_WRITE_THRESHOLD) {
3970 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE; 3970 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3971 if (value < 1 || value > osst_buffer_size) { 3971 if (value < 1 || value > osst_buffer_size) {
3972 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n", 3972 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3973 name, value); 3973 name, value);
3974 return (-EIO); 3974 return (-EIO);
3975 } 3975 }
3976 STp->write_threshold = value; 3976 STp->write_threshold = value;
3977 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n", 3977 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3978 name, value); 3978 name, value);
3979 } 3979 }
3980 else if (code == MT_ST_DEF_BLKSIZE) { 3980 else if (code == MT_ST_DEF_BLKSIZE) {
3981 value = (options & ~MT_ST_OPTIONS); 3981 value = (options & ~MT_ST_OPTIONS);
3982 if (value == ~MT_ST_OPTIONS) { 3982 if (value == ~MT_ST_OPTIONS) {
3983 STm->default_blksize = (-1); 3983 STm->default_blksize = (-1);
3984 printk(KERN_INFO "%s:I: Default block size disabled.\n", name); 3984 printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3985 } 3985 }
3986 else { 3986 else {
3987 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) { 3987 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3988 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n", 3988 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3989 name, value); 3989 name, value);
3990 return (-EINVAL); 3990 return (-EINVAL);
3991 } 3991 }
3992 STm->default_blksize = value; 3992 STm->default_blksize = value;
3993 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n", 3993 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
3994 name, STm->default_blksize); 3994 name, STm->default_blksize);
3995 } 3995 }
3996 } 3996 }
3997 else if (code == MT_ST_TIMEOUTS) { 3997 else if (code == MT_ST_TIMEOUTS) {
3998 value = (options & ~MT_ST_OPTIONS); 3998 value = (options & ~MT_ST_OPTIONS);
3999 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) { 3999 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
4000 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ; 4000 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
4001 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name, 4001 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
4002 (value & ~MT_ST_SET_LONG_TIMEOUT)); 4002 (value & ~MT_ST_SET_LONG_TIMEOUT));
4003 } 4003 }
4004 else { 4004 else {
4005 STp->timeout = value * HZ; 4005 STp->timeout = value * HZ;
4006 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value); 4006 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
4007 } 4007 }
4008 } 4008 }
4009 else if (code == MT_ST_DEF_OPTIONS) { 4009 else if (code == MT_ST_DEF_OPTIONS) {
4010 code = (options & ~MT_ST_CLEAR_DEFAULT); 4010 code = (options & ~MT_ST_CLEAR_DEFAULT);
4011 value = (options & MT_ST_CLEAR_DEFAULT); 4011 value = (options & MT_ST_CLEAR_DEFAULT);
4012 if (code == MT_ST_DEF_DENSITY) { 4012 if (code == MT_ST_DEF_DENSITY) {
4013 if (value == MT_ST_CLEAR_DEFAULT) { 4013 if (value == MT_ST_CLEAR_DEFAULT) {
4014 STm->default_density = (-1); 4014 STm->default_density = (-1);
4015 printk(KERN_INFO "%s:I: Density default disabled.\n", name); 4015 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
4016 } 4016 }
4017 else { 4017 else {
4018 STm->default_density = value & 0xff; 4018 STm->default_density = value & 0xff;
4019 printk(KERN_INFO "%s:I: Density default set to %x\n", 4019 printk(KERN_INFO "%s:I: Density default set to %x\n",
4020 name, STm->default_density); 4020 name, STm->default_density);
4021 } 4021 }
4022 } 4022 }
4023 else if (code == MT_ST_DEF_DRVBUFFER) { 4023 else if (code == MT_ST_DEF_DRVBUFFER) {
4024 if (value == MT_ST_CLEAR_DEFAULT) { 4024 if (value == MT_ST_CLEAR_DEFAULT) {
4025 STp->default_drvbuffer = 0xff; 4025 STp->default_drvbuffer = 0xff;
4026 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name); 4026 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
4027 } 4027 }
4028 else { 4028 else {
4029 STp->default_drvbuffer = value & 7; 4029 STp->default_drvbuffer = value & 7;
4030 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n", 4030 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
4031 name, STp->default_drvbuffer); 4031 name, STp->default_drvbuffer);
4032 } 4032 }
4033 } 4033 }
4034 else if (code == MT_ST_DEF_COMPRESSION) { 4034 else if (code == MT_ST_DEF_COMPRESSION) {
4035 if (value == MT_ST_CLEAR_DEFAULT) { 4035 if (value == MT_ST_CLEAR_DEFAULT) {
4036 STm->default_compression = ST_DONT_TOUCH; 4036 STm->default_compression = ST_DONT_TOUCH;
4037 printk(KERN_INFO "%s:I: Compression default disabled.\n", name); 4037 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
4038 } 4038 }
4039 else { 4039 else {
4040 STm->default_compression = (value & 1 ? ST_YES : ST_NO); 4040 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
4041 printk(KERN_INFO "%s:I: Compression default set to %x\n", 4041 printk(KERN_INFO "%s:I: Compression default set to %x\n",
4042 name, (value & 1)); 4042 name, (value & 1));
4043 } 4043 }
4044 } 4044 }
4045 } 4045 }
4046 else 4046 else
4047 return (-EIO); 4047 return (-EIO);
4048 4048
4049 return 0; 4049 return 0;
4050 } 4050 }
4051 4051
4052 4052
4053 /* Internal ioctl function */ 4053 /* Internal ioctl function */
4054 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt, 4054 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt,
4055 unsigned int cmd_in, unsigned long arg) 4055 unsigned int cmd_in, unsigned long arg)
4056 { 4056 {
4057 int timeout; 4057 int timeout;
4058 long ltmp; 4058 long ltmp;
4059 int i, ioctl_result; 4059 int i, ioctl_result;
4060 int chg_eof = 1; 4060 int chg_eof = 1;
4061 unsigned char cmd[MAX_COMMAND_SIZE]; 4061 unsigned char cmd[MAX_COMMAND_SIZE];
4062 struct osst_request * SRpnt = * aSRpnt; 4062 struct osst_request * SRpnt = * aSRpnt;
4063 struct st_partstat * STps; 4063 struct st_partstat * STps;
4064 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num; 4064 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
4065 int datalen = 0, direction = DMA_NONE; 4065 int datalen = 0, direction = DMA_NONE;
4066 char * name = tape_name(STp); 4066 char * name = tape_name(STp);
4067 4067
4068 if (STp->ready != ST_READY && cmd_in != MTLOAD) { 4068 if (STp->ready != ST_READY && cmd_in != MTLOAD) {
4069 if (STp->ready == ST_NO_TAPE) 4069 if (STp->ready == ST_NO_TAPE)
4070 return (-ENOMEDIUM); 4070 return (-ENOMEDIUM);
4071 else 4071 else
4072 return (-EIO); 4072 return (-EIO);
4073 } 4073 }
4074 timeout = STp->long_timeout; 4074 timeout = STp->long_timeout;
4075 STps = &(STp->ps[STp->partition]); 4075 STps = &(STp->ps[STp->partition]);
4076 fileno = STps->drv_file; 4076 fileno = STps->drv_file;
4077 blkno = STps->drv_block; 4077 blkno = STps->drv_block;
4078 at_sm = STps->at_sm; 4078 at_sm = STps->at_sm;
4079 frame_seq_numbr = STp->frame_seq_number; 4079 frame_seq_numbr = STp->frame_seq_number;
4080 logical_blk_num = STp->logical_blk_num; 4080 logical_blk_num = STp->logical_blk_num;
4081 4081
4082 memset(cmd, 0, MAX_COMMAND_SIZE); 4082 memset(cmd, 0, MAX_COMMAND_SIZE);
4083 switch (cmd_in) { 4083 switch (cmd_in) {
4084 case MTFSFM: 4084 case MTFSFM:
4085 chg_eof = 0; /* Changed from the FSF after this */ 4085 chg_eof = 0; /* Changed from the FSF after this */
4086 case MTFSF: 4086 case MTFSF:
4087 if (STp->raw) 4087 if (STp->raw)
4088 return (-EIO); 4088 return (-EIO);
4089 if (STp->linux_media) 4089 if (STp->linux_media)
4090 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg); 4090 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
4091 else 4091 else
4092 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg); 4092 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
4093 if (fileno >= 0) 4093 if (fileno >= 0)
4094 fileno += arg; 4094 fileno += arg;
4095 blkno = 0; 4095 blkno = 0;
4096 at_sm &= (arg == 0); 4096 at_sm &= (arg == 0);
4097 goto os_bypass; 4097 goto os_bypass;
4098 4098
4099 case MTBSF: 4099 case MTBSF:
4100 chg_eof = 0; /* Changed from the FSF after this */ 4100 chg_eof = 0; /* Changed from the FSF after this */
4101 case MTBSFM: 4101 case MTBSFM:
4102 if (STp->raw) 4102 if (STp->raw)
4103 return (-EIO); 4103 return (-EIO);
4104 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg); 4104 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
4105 if (fileno >= 0) 4105 if (fileno >= 0)
4106 fileno -= arg; 4106 fileno -= arg;
4107 blkno = (-1); /* We can't know the block number */ 4107 blkno = (-1); /* We can't know the block number */
4108 at_sm &= (arg == 0); 4108 at_sm &= (arg == 0);
4109 goto os_bypass; 4109 goto os_bypass;
4110 4110
4111 case MTFSR: 4111 case MTFSR:
4112 case MTBSR: 4112 case MTBSR:
4113 #if DEBUG 4113 #if DEBUG
4114 if (debugging) 4114 if (debugging)
4115 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n", 4115 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
4116 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num); 4116 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
4117 #endif 4117 #endif
4118 if (cmd_in == MTFSR) { 4118 if (cmd_in == MTFSR) {
4119 logical_blk_num += arg; 4119 logical_blk_num += arg;
4120 if (blkno >= 0) blkno += arg; 4120 if (blkno >= 0) blkno += arg;
4121 } 4121 }
4122 else { 4122 else {
4123 logical_blk_num -= arg; 4123 logical_blk_num -= arg;
4124 if (blkno >= 0) blkno -= arg; 4124 if (blkno >= 0) blkno -= arg;
4125 } 4125 }
4126 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num); 4126 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
4127 fileno = STps->drv_file; 4127 fileno = STps->drv_file;
4128 blkno = STps->drv_block; 4128 blkno = STps->drv_block;
4129 at_sm &= (arg == 0); 4129 at_sm &= (arg == 0);
4130 goto os_bypass; 4130 goto os_bypass;
4131 4131
4132 case MTFSS: 4132 case MTFSS:
4133 cmd[0] = SPACE; 4133 cmd[0] = SPACE;
4134 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */ 4134 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4135 cmd[2] = (arg >> 16); 4135 cmd[2] = (arg >> 16);
4136 cmd[3] = (arg >> 8); 4136 cmd[3] = (arg >> 8);
4137 cmd[4] = arg; 4137 cmd[4] = arg;
4138 #if DEBUG 4138 #if DEBUG
4139 if (debugging) 4139 if (debugging)
4140 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name, 4140 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4141 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]); 4141 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4142 #endif 4142 #endif
4143 if (arg != 0) { 4143 if (arg != 0) {
4144 blkno = fileno = (-1); 4144 blkno = fileno = (-1);
4145 at_sm = 1; 4145 at_sm = 1;
4146 } 4146 }
4147 break; 4147 break;
4148 case MTBSS: 4148 case MTBSS:
4149 cmd[0] = SPACE; 4149 cmd[0] = SPACE;
4150 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */ 4150 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4151 ltmp = (-arg); 4151 ltmp = (-arg);
4152 cmd[2] = (ltmp >> 16); 4152 cmd[2] = (ltmp >> 16);
4153 cmd[3] = (ltmp >> 8); 4153 cmd[3] = (ltmp >> 8);
4154 cmd[4] = ltmp; 4154 cmd[4] = ltmp;
4155 #if DEBUG 4155 #if DEBUG
4156 if (debugging) { 4156 if (debugging) {
4157 if (cmd[2] & 0x80) 4157 if (cmd[2] & 0x80)
4158 ltmp = 0xff000000; 4158 ltmp = 0xff000000;
4159 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4]; 4159 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4160 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n", 4160 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4161 name, (-ltmp)); 4161 name, (-ltmp));
4162 } 4162 }
4163 #endif 4163 #endif
4164 if (arg != 0) { 4164 if (arg != 0) {
4165 blkno = fileno = (-1); 4165 blkno = fileno = (-1);
4166 at_sm = 1; 4166 at_sm = 1;
4167 } 4167 }
4168 break; 4168 break;
4169 case MTWEOF: 4169 case MTWEOF:
4170 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) { 4170 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4171 STp->write_type = OS_WRITE_DATA; 4171 STp->write_type = OS_WRITE_DATA;
4172 ioctl_result = osst_flush_write_buffer(STp, &SRpnt); 4172 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4173 } else 4173 } else
4174 ioctl_result = 0; 4174 ioctl_result = 0;
4175 #if DEBUG 4175 #if DEBUG
4176 if (debugging) 4176 if (debugging)
4177 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg); 4177 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4178 #endif 4178 #endif
4179 for (i=0; i<arg; i++) 4179 for (i=0; i<arg; i++)
4180 ioctl_result |= osst_write_filemark(STp, &SRpnt); 4180 ioctl_result |= osst_write_filemark(STp, &SRpnt);
4181 if (fileno >= 0) fileno += arg; 4181 if (fileno >= 0) fileno += arg;
4182 if (blkno >= 0) blkno = 0; 4182 if (blkno >= 0) blkno = 0;
4183 goto os_bypass; 4183 goto os_bypass;
4184 4184
4185 case MTWSM: 4185 case MTWSM:
4186 if (STp->write_prot) 4186 if (STp->write_prot)
4187 return (-EACCES); 4187 return (-EACCES);
4188 if (!STp->raw) 4188 if (!STp->raw)
4189 return 0; 4189 return 0;
4190 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */ 4190 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
4191 if (cmd_in == MTWSM) 4191 if (cmd_in == MTWSM)
4192 cmd[1] = 2; 4192 cmd[1] = 2;
4193 cmd[2] = (arg >> 16); 4193 cmd[2] = (arg >> 16);
4194 cmd[3] = (arg >> 8); 4194 cmd[3] = (arg >> 8);
4195 cmd[4] = arg; 4195 cmd[4] = arg;
4196 timeout = STp->timeout; 4196 timeout = STp->timeout;
4197 #if DEBUG 4197 #if DEBUG
4198 if (debugging) 4198 if (debugging)
4199 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name, 4199 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4200 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]); 4200 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4201 #endif 4201 #endif
4202 if (fileno >= 0) 4202 if (fileno >= 0)
4203 fileno += arg; 4203 fileno += arg;
4204 blkno = 0; 4204 blkno = 0;
4205 at_sm = (cmd_in == MTWSM); 4205 at_sm = (cmd_in == MTWSM);
4206 break; 4206 break;
4207 case MTOFFL: 4207 case MTOFFL:
4208 case MTLOAD: 4208 case MTLOAD:
4209 case MTUNLOAD: 4209 case MTUNLOAD:
4210 case MTRETEN: 4210 case MTRETEN:
4211 cmd[0] = START_STOP; 4211 cmd[0] = START_STOP;
4212 cmd[1] = 1; /* Don't wait for completion */ 4212 cmd[1] = 1; /* Don't wait for completion */
4213 if (cmd_in == MTLOAD) { 4213 if (cmd_in == MTLOAD) {
4214 if (STp->ready == ST_NO_TAPE) 4214 if (STp->ready == ST_NO_TAPE)
4215 cmd[4] = 4; /* open tray */ 4215 cmd[4] = 4; /* open tray */
4216 else 4216 else
4217 cmd[4] = 1; /* load */ 4217 cmd[4] = 1; /* load */
4218 } 4218 }
4219 if (cmd_in == MTRETEN) 4219 if (cmd_in == MTRETEN)
4220 cmd[4] = 3; /* retension then mount */ 4220 cmd[4] = 3; /* retension then mount */
4221 if (cmd_in == MTOFFL) 4221 if (cmd_in == MTOFFL)
4222 cmd[4] = 4; /* rewind then eject */ 4222 cmd[4] = 4; /* rewind then eject */
4223 timeout = STp->timeout; 4223 timeout = STp->timeout;
4224 #if DEBUG 4224 #if DEBUG
4225 if (debugging) { 4225 if (debugging) {
4226 switch (cmd_in) { 4226 switch (cmd_in) {
4227 case MTUNLOAD: 4227 case MTUNLOAD:
4228 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name); 4228 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4229 break; 4229 break;
4230 case MTLOAD: 4230 case MTLOAD:
4231 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name); 4231 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4232 break; 4232 break;
4233 case MTRETEN: 4233 case MTRETEN:
4234 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name); 4234 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4235 break; 4235 break;
4236 case MTOFFL: 4236 case MTOFFL:
4237 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name); 4237 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4238 break; 4238 break;
4239 } 4239 }
4240 } 4240 }
4241 #endif 4241 #endif
4242 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ; 4242 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4243 break; 4243 break;
4244 case MTNOP: 4244 case MTNOP:
4245 #if DEBUG 4245 #if DEBUG
4246 if (debugging) 4246 if (debugging)
4247 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name); 4247 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4248 #endif 4248 #endif
4249 return 0; /* Should do something ? */ 4249 return 0; /* Should do something ? */
4250 break; 4250 break;
4251 case MTEOM: 4251 case MTEOM:
4252 #if DEBUG 4252 #if DEBUG
4253 if (debugging) 4253 if (debugging)
4254 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name); 4254 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4255 #endif 4255 #endif
4256 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) || 4256 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4257 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) { 4257 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4258 ioctl_result = -EIO; 4258 ioctl_result = -EIO;
4259 goto os_bypass; 4259 goto os_bypass;
4260 } 4260 }
4261 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) { 4261 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4262 #if DEBUG 4262 #if DEBUG
4263 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name); 4263 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4264 #endif 4264 #endif
4265 ioctl_result = -EIO; 4265 ioctl_result = -EIO;
4266 goto os_bypass; 4266 goto os_bypass;
4267 } 4267 }
4268 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0); 4268 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4269 fileno = STp->filemark_cnt; 4269 fileno = STp->filemark_cnt;
4270 blkno = at_sm = 0; 4270 blkno = at_sm = 0;
4271 goto os_bypass; 4271 goto os_bypass;
4272 4272
4273 case MTERASE: 4273 case MTERASE:
4274 if (STp->write_prot) 4274 if (STp->write_prot)
4275 return (-EACCES); 4275 return (-EACCES);
4276 ioctl_result = osst_reset_header(STp, &SRpnt); 4276 ioctl_result = osst_reset_header(STp, &SRpnt);
4277 i = osst_write_eod(STp, &SRpnt); 4277 i = osst_write_eod(STp, &SRpnt);
4278 if (i < ioctl_result) ioctl_result = i; 4278 if (i < ioctl_result) ioctl_result = i;
4279 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos); 4279 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4280 if (i < ioctl_result) ioctl_result = i; 4280 if (i < ioctl_result) ioctl_result = i;
4281 fileno = blkno = at_sm = 0 ; 4281 fileno = blkno = at_sm = 0 ;
4282 goto os_bypass; 4282 goto os_bypass;
4283 4283
4284 case MTREW: 4284 case MTREW:
4285 cmd[0] = REZERO_UNIT; /* rewind */ 4285 cmd[0] = REZERO_UNIT; /* rewind */
4286 cmd[1] = 1; 4286 cmd[1] = 1;
4287 #if DEBUG 4287 #if DEBUG
4288 if (debugging) 4288 if (debugging)
4289 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]); 4289 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4290 #endif 4290 #endif
4291 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ; 4291 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4292 break; 4292 break;
4293 4293
4294 case MTSETBLK: /* Set block length */ 4294 case MTSETBLK: /* Set block length */
4295 if ((STps->drv_block == 0 ) && 4295 if ((STps->drv_block == 0 ) &&
4296 !STp->dirty && 4296 !STp->dirty &&
4297 ((STp->buffer)->buffer_bytes == 0) && 4297 ((STp->buffer)->buffer_bytes == 0) &&
4298 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) && 4298 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4299 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) && 4299 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4300 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) { 4300 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4301 /* 4301 /*
4302 * Only allowed to change the block size if you opened the 4302 * Only allowed to change the block size if you opened the
4303 * device at the beginning of a file before writing anything. 4303 * device at the beginning of a file before writing anything.
4304 * Note, that when reading, changing block_size is futile, 4304 * Note, that when reading, changing block_size is futile,
4305 * as the size used when writing overrides it. 4305 * as the size used when writing overrides it.
4306 */ 4306 */
4307 STp->block_size = (arg & MT_ST_BLKSIZE_MASK); 4307 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4308 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n", 4308 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4309 name, STp->block_size); 4309 name, STp->block_size);
4310 return 0; 4310 return 0;
4311 } 4311 }
4312 case MTSETDENSITY: /* Set tape density */ 4312 case MTSETDENSITY: /* Set tape density */
4313 case MTSETDRVBUFFER: /* Set drive buffering */ 4313 case MTSETDRVBUFFER: /* Set drive buffering */
4314 case SET_DENS_AND_BLK: /* Set density and block size */ 4314 case SET_DENS_AND_BLK: /* Set density and block size */
4315 chg_eof = 0; 4315 chg_eof = 0;
4316 if (STp->dirty || (STp->buffer)->buffer_bytes != 0) 4316 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4317 return (-EIO); /* Not allowed if data in buffer */ 4317 return (-EIO); /* Not allowed if data in buffer */
4318 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) && 4318 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4319 (arg & MT_ST_BLKSIZE_MASK) != 0 && 4319 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4320 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) { 4320 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4321 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n", 4321 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4322 name, (int)(arg & MT_ST_BLKSIZE_MASK), 4322 name, (int)(arg & MT_ST_BLKSIZE_MASK),
4323 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now"); 4323 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4324 return (-EINVAL); 4324 return (-EINVAL);
4325 } 4325 }
4326 return 0; /* FIXME silently ignore if block size didn't change */ 4326 return 0; /* FIXME silently ignore if block size didn't change */
4327 4327
4328 default: 4328 default:
4329 return (-ENOSYS); 4329 return (-ENOSYS);
4330 } 4330 }
4331 4331
4332 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1); 4332 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4333 4333
4334 ioctl_result = (STp->buffer)->syscall_result; 4334 ioctl_result = (STp->buffer)->syscall_result;
4335 4335
4336 if (!SRpnt) { 4336 if (!SRpnt) {
4337 #if DEBUG 4337 #if DEBUG
4338 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name); 4338 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4339 #endif 4339 #endif
4340 return ioctl_result; 4340 return ioctl_result;
4341 } 4341 }
4342 4342
4343 if (!ioctl_result) { /* SCSI command successful */ 4343 if (!ioctl_result) { /* SCSI command successful */
4344 STp->frame_seq_number = frame_seq_numbr; 4344 STp->frame_seq_number = frame_seq_numbr;
4345 STp->logical_blk_num = logical_blk_num; 4345 STp->logical_blk_num = logical_blk_num;
4346 } 4346 }
4347 4347
4348 os_bypass: 4348 os_bypass:
4349 #if DEBUG 4349 #if DEBUG
4350 if (debugging) 4350 if (debugging)
4351 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result); 4351 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4352 #endif 4352 #endif
4353 4353
4354 if (!ioctl_result) { /* success */ 4354 if (!ioctl_result) { /* success */
4355 4355
4356 if (cmd_in == MTFSFM) { 4356 if (cmd_in == MTFSFM) {
4357 fileno--; 4357 fileno--;
4358 blkno--; 4358 blkno--;
4359 } 4359 }
4360 if (cmd_in == MTBSFM) { 4360 if (cmd_in == MTBSFM) {
4361 fileno++; 4361 fileno++;
4362 blkno++; 4362 blkno++;
4363 } 4363 }
4364 STps->drv_block = blkno; 4364 STps->drv_block = blkno;
4365 STps->drv_file = fileno; 4365 STps->drv_file = fileno;
4366 STps->at_sm = at_sm; 4366 STps->at_sm = at_sm;
4367 4367
4368 if (cmd_in == MTEOM) 4368 if (cmd_in == MTEOM)
4369 STps->eof = ST_EOD; 4369 STps->eof = ST_EOD;
4370 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) { 4370 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4371 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1); 4371 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4372 STps->drv_block++; 4372 STps->drv_block++;
4373 STp->logical_blk_num++; 4373 STp->logical_blk_num++;
4374 STp->frame_seq_number++; 4374 STp->frame_seq_number++;
4375 STp->frame_in_buffer = 0; 4375 STp->frame_in_buffer = 0;
4376 STp->buffer->read_pointer = 0; 4376 STp->buffer->read_pointer = 0;
4377 } 4377 }
4378 else if (cmd_in == MTFSF) 4378 else if (cmd_in == MTFSF)
4379 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM; 4379 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4380 else if (chg_eof) 4380 else if (chg_eof)
4381 STps->eof = ST_NOEOF; 4381 STps->eof = ST_NOEOF;
4382 4382
4383 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD) 4383 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4384 STp->rew_at_close = 0; 4384 STp->rew_at_close = 0;
4385 else if (cmd_in == MTLOAD) { 4385 else if (cmd_in == MTLOAD) {
4386 for (i=0; i < ST_NBR_PARTITIONS; i++) { 4386 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4387 STp->ps[i].rw = ST_IDLE; 4387 STp->ps[i].rw = ST_IDLE;
4388 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */ 4388 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4389 } 4389 }
4390 STp->partition = 0; 4390 STp->partition = 0;
4391 } 4391 }
4392 4392
4393 if (cmd_in == MTREW) { 4393 if (cmd_in == MTREW) {
4394 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos); 4394 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4395 if (ioctl_result > 0) 4395 if (ioctl_result > 0)
4396 ioctl_result = 0; 4396 ioctl_result = 0;
4397 } 4397 }
4398 4398
4399 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) { 4399 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4400 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0) 4400 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4401 STps->drv_file = STps->drv_block = -1; 4401 STps->drv_file = STps->drv_block = -1;
4402 else 4402 else
4403 STps->drv_file = STps->drv_block = 0; 4403 STps->drv_file = STps->drv_block = 0;
4404 STps->eof = ST_NOEOF; 4404 STps->eof = ST_NOEOF;
4405 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) { 4405 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4406 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) 4406 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4407 STps->drv_file = STps->drv_block = -1; 4407 STps->drv_file = STps->drv_block = -1;
4408 else { 4408 else {
4409 STps->drv_file = STp->filemark_cnt; 4409 STps->drv_file = STp->filemark_cnt;
4410 STps->drv_block = 0; 4410 STps->drv_block = 0;
4411 } 4411 }
4412 STps->eof = ST_EOD; 4412 STps->eof = ST_EOD;
4413 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) { 4413 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4414 STps->drv_file = STps->drv_block = (-1); 4414 STps->drv_file = STps->drv_block = (-1);
4415 STps->eof = ST_NOEOF; 4415 STps->eof = ST_NOEOF;
4416 STp->header_ok = 0; 4416 STp->header_ok = 0;
4417 } else if (cmd_in == MTERASE) { 4417 } else if (cmd_in == MTERASE) {
4418 STp->header_ok = 0; 4418 STp->header_ok = 0;
4419 } else if (SRpnt) { /* SCSI command was not completely successful. */ 4419 } else if (SRpnt) { /* SCSI command was not completely successful. */
4420 if (SRpnt->sense[2] & 0x40) { 4420 if (SRpnt->sense[2] & 0x40) {
4421 STps->eof = ST_EOM_OK; 4421 STps->eof = ST_EOM_OK;
4422 STps->drv_block = 0; 4422 STps->drv_block = 0;
4423 } 4423 }
4424 if (chg_eof) 4424 if (chg_eof)
4425 STps->eof = ST_NOEOF; 4425 STps->eof = ST_NOEOF;
4426 4426
4427 if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK) 4427 if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK)
4428 STps->eof = ST_EOD; 4428 STps->eof = ST_EOD;
4429 4429
4430 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60)) 4430 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4431 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE); 4431 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4432 } 4432 }
4433 *aSRpnt = SRpnt; 4433 *aSRpnt = SRpnt;
4434 4434
4435 return ioctl_result; 4435 return ioctl_result;
4436 } 4436 }
4437 4437
4438 4438
4439 /* Open the device */ 4439 /* Open the device */
4440 static int __os_scsi_tape_open(struct inode * inode, struct file * filp) 4440 static int __os_scsi_tape_open(struct inode * inode, struct file * filp)
4441 { 4441 {
4442 unsigned short flags; 4442 unsigned short flags;
4443 int i, b_size, new_session = 0, retval = 0; 4443 int i, b_size, new_session = 0, retval = 0;
4444 unsigned char cmd[MAX_COMMAND_SIZE]; 4444 unsigned char cmd[MAX_COMMAND_SIZE];
4445 struct osst_request * SRpnt = NULL; 4445 struct osst_request * SRpnt = NULL;
4446 struct osst_tape * STp; 4446 struct osst_tape * STp;
4447 struct st_modedef * STm; 4447 struct st_modedef * STm;
4448 struct st_partstat * STps; 4448 struct st_partstat * STps;
4449 char * name; 4449 char * name;
4450 int dev = TAPE_NR(inode); 4450 int dev = TAPE_NR(inode);
4451 int mode = TAPE_MODE(inode); 4451 int mode = TAPE_MODE(inode);
4452 4452
4453 /* 4453 /*
4454 * We really want to do nonseekable_open(inode, filp); here, but some 4454 * We really want to do nonseekable_open(inode, filp); here, but some
4455 * versions of tar incorrectly call lseek on tapes and bail out if that 4455 * versions of tar incorrectly call lseek on tapes and bail out if that
4456 * fails. So we disallow pread() and pwrite(), but permit lseeks. 4456 * fails. So we disallow pread() and pwrite(), but permit lseeks.
4457 */ 4457 */
4458 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); 4458 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
4459 4459
4460 write_lock(&os_scsi_tapes_lock); 4460 write_lock(&os_scsi_tapes_lock);
4461 if (dev >= osst_max_dev || os_scsi_tapes == NULL || 4461 if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4462 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) { 4462 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4463 write_unlock(&os_scsi_tapes_lock); 4463 write_unlock(&os_scsi_tapes_lock);
4464 return (-ENXIO); 4464 return (-ENXIO);
4465 } 4465 }
4466 4466
4467 name = tape_name(STp); 4467 name = tape_name(STp);
4468 4468
4469 if (STp->in_use) { 4469 if (STp->in_use) {
4470 write_unlock(&os_scsi_tapes_lock); 4470 write_unlock(&os_scsi_tapes_lock);
4471 #if DEBUG 4471 #if DEBUG
4472 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name); 4472 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4473 #endif 4473 #endif
4474 return (-EBUSY); 4474 return (-EBUSY);
4475 } 4475 }
4476 if (scsi_device_get(STp->device)) { 4476 if (scsi_device_get(STp->device)) {
4477 write_unlock(&os_scsi_tapes_lock); 4477 write_unlock(&os_scsi_tapes_lock);
4478 #if DEBUG 4478 #if DEBUG
4479 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name); 4479 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4480 #endif 4480 #endif
4481 return (-ENXIO); 4481 return (-ENXIO);
4482 } 4482 }
4483 filp->private_data = STp; 4483 filp->private_data = STp;
4484 STp->in_use = 1; 4484 STp->in_use = 1;
4485 write_unlock(&os_scsi_tapes_lock); 4485 write_unlock(&os_scsi_tapes_lock);
4486 STp->rew_at_close = TAPE_REWIND(inode); 4486 STp->rew_at_close = TAPE_REWIND(inode);
4487 4487
4488 if( !scsi_block_when_processing_errors(STp->device) ) { 4488 if( !scsi_block_when_processing_errors(STp->device) ) {
4489 return -ENXIO; 4489 return -ENXIO;
4490 } 4490 }
4491 4491
4492 if (mode != STp->current_mode) { 4492 if (mode != STp->current_mode) {
4493 #if DEBUG 4493 #if DEBUG
4494 if (debugging) 4494 if (debugging)
4495 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n", 4495 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4496 name, STp->current_mode, mode); 4496 name, STp->current_mode, mode);
4497 #endif 4497 #endif
4498 new_session = 1; 4498 new_session = 1;
4499 STp->current_mode = mode; 4499 STp->current_mode = mode;
4500 } 4500 }
4501 STm = &(STp->modes[STp->current_mode]); 4501 STm = &(STp->modes[STp->current_mode]);
4502 4502
4503 flags = filp->f_flags; 4503 flags = filp->f_flags;
4504 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY); 4504 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4505 4505
4506 STp->raw = TAPE_IS_RAW(inode); 4506 STp->raw = TAPE_IS_RAW(inode);
4507 if (STp->raw) 4507 if (STp->raw)
4508 STp->header_ok = 0; 4508 STp->header_ok = 0;
4509 4509
4510 /* Allocate data segments for this device's tape buffer */ 4510 /* Allocate data segments for this device's tape buffer */
4511 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) { 4511 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4512 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name); 4512 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4513 retval = (-EOVERFLOW); 4513 retval = (-EOVERFLOW);
4514 goto err_out; 4514 goto err_out;
4515 } 4515 }
4516 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) { 4516 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4517 for (i = 0, b_size = 0; 4517 for (i = 0, b_size = 0;
4518 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); 4518 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4519 b_size += STp->buffer->sg[i++].length); 4519 b_size += STp->buffer->sg[i++].length);
4520 STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size); 4520 STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
4521 #if DEBUG 4521 #if DEBUG
4522 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name, 4522 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4523 STp->buffer->b_data, page_address(STp->buffer->sg[0].page)); 4523 STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4524 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name, 4524 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4525 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page)); 4525 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4526 #endif 4526 #endif
4527 } else { 4527 } else {
4528 STp->buffer->aux = NULL; /* this had better never happen! */ 4528 STp->buffer->aux = NULL; /* this had better never happen! */
4529 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE); 4529 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4530 retval = (-EIO); 4530 retval = (-EIO);
4531 goto err_out; 4531 goto err_out;
4532 } 4532 }
4533 STp->buffer->writing = 0; 4533 STp->buffer->writing = 0;
4534 STp->buffer->syscall_result = 0; 4534 STp->buffer->syscall_result = 0;
4535 STp->dirty = 0; 4535 STp->dirty = 0;
4536 for (i=0; i < ST_NBR_PARTITIONS; i++) { 4536 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4537 STps = &(STp->ps[i]); 4537 STps = &(STp->ps[i]);
4538 STps->rw = ST_IDLE; 4538 STps->rw = ST_IDLE;
4539 } 4539 }
4540 STp->ready = ST_READY; 4540 STp->ready = ST_READY;
4541 #if DEBUG 4541 #if DEBUG
4542 STp->nbr_waits = STp->nbr_finished = 0; 4542 STp->nbr_waits = STp->nbr_finished = 0;
4543 #endif 4543 #endif
4544 4544
4545 memset (cmd, 0, MAX_COMMAND_SIZE); 4545 memset (cmd, 0, MAX_COMMAND_SIZE);
4546 cmd[0] = TEST_UNIT_READY; 4546 cmd[0] = TEST_UNIT_READY;
4547 4547
4548 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); 4548 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4549 if (!SRpnt) { 4549 if (!SRpnt) {
4550 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */ 4550 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
4551 goto err_out; 4551 goto err_out;
4552 } 4552 }
4553 if ((SRpnt->sense[0] & 0x70) == 0x70 && 4553 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4554 (SRpnt->sense[2] & 0x0f) == NOT_READY && 4554 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4555 SRpnt->sense[12] == 4 ) { 4555 SRpnt->sense[12] == 4 ) {
4556 #if DEBUG 4556 #if DEBUG
4557 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]); 4557 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]);
4558 #endif 4558 #endif
4559 if (filp->f_flags & O_NONBLOCK) { 4559 if (filp->f_flags & O_NONBLOCK) {
4560 retval = -EAGAIN; 4560 retval = -EAGAIN;
4561 goto err_out; 4561 goto err_out;
4562 } 4562 }
4563 if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */ 4563 if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */
4564 memset (cmd, 0, MAX_COMMAND_SIZE); 4564 memset (cmd, 0, MAX_COMMAND_SIZE);
4565 cmd[0] = START_STOP; 4565 cmd[0] = START_STOP;
4566 cmd[1] = 1; 4566 cmd[1] = 1;
4567 cmd[4] = 1; 4567 cmd[4] = 1;
4568 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, 4568 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4569 STp->timeout, MAX_RETRIES, 1); 4569 STp->timeout, MAX_RETRIES, 1);
4570 } 4570 }
4571 osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0); 4571 osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
4572 } 4572 }
4573 if ((SRpnt->sense[0] & 0x70) == 0x70 && 4573 if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4574 (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */ 4574 (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4575 #if DEBUG 4575 #if DEBUG
4576 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name); 4576 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4577 #endif 4577 #endif
4578 STp->header_ok = 0; 4578 STp->header_ok = 0;
4579 4579
4580 for (i=0; i < 10; i++) { 4580 for (i=0; i < 10; i++) {
4581 4581
4582 memset (cmd, 0, MAX_COMMAND_SIZE); 4582 memset (cmd, 0, MAX_COMMAND_SIZE);
4583 cmd[0] = TEST_UNIT_READY; 4583 cmd[0] = TEST_UNIT_READY;
4584 4584
4585 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, 4585 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4586 STp->timeout, MAX_RETRIES, 1); 4586 STp->timeout, MAX_RETRIES, 1);
4587 if ((SRpnt->sense[0] & 0x70) != 0x70 || 4587 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4588 (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION) 4588 (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
4589 break; 4589 break;
4590 } 4590 }
4591 4591
4592 STp->pos_unknown = 0; 4592 STp->pos_unknown = 0;
4593 STp->partition = STp->new_partition = 0; 4593 STp->partition = STp->new_partition = 0;
4594 if (STp->can_partitions) 4594 if (STp->can_partitions)
4595 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */ 4595 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4596 for (i=0; i < ST_NBR_PARTITIONS; i++) { 4596 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4597 STps = &(STp->ps[i]); 4597 STps = &(STp->ps[i]);
4598 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */ 4598 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4599 STps->eof = ST_NOEOF; 4599 STps->eof = ST_NOEOF;
4600 STps->at_sm = 0; 4600 STps->at_sm = 0;
4601 STps->last_block_valid = 0; 4601 STps->last_block_valid = 0;
4602 STps->drv_block = 0; 4602 STps->drv_block = 0;
4603 STps->drv_file = 0 ; 4603 STps->drv_file = 0 ;
4604 } 4604 }
4605 new_session = 1; 4605 new_session = 1;
4606 STp->recover_count = 0; 4606 STp->recover_count = 0;
4607 STp->abort_count = 0; 4607 STp->abort_count = 0;
4608 } 4608 }
4609 /* 4609 /*
4610 * if we have valid headers from before, and the drive/tape seem untouched, 4610 * if we have valid headers from before, and the drive/tape seem untouched,
4611 * open without reconfiguring and re-reading the headers 4611 * open without reconfiguring and re-reading the headers
4612 */ 4612 */
4613 if (!STp->buffer->syscall_result && STp->header_ok && 4613 if (!STp->buffer->syscall_result && STp->header_ok &&
4614 !SRpnt->result && SRpnt->sense[0] == 0) { 4614 !SRpnt->result && SRpnt->sense[0] == 0) {
4615 4615
4616 memset(cmd, 0, MAX_COMMAND_SIZE); 4616 memset(cmd, 0, MAX_COMMAND_SIZE);
4617 cmd[0] = MODE_SENSE; 4617 cmd[0] = MODE_SENSE;
4618 cmd[1] = 8; 4618 cmd[1] = 8;
4619 cmd[2] = VENDOR_IDENT_PAGE; 4619 cmd[2] = VENDOR_IDENT_PAGE;
4620 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH; 4620 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4621 4621
4622 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); 4622 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4623 4623
4624 if (STp->buffer->syscall_result || 4624 if (STp->buffer->syscall_result ||
4625 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' || 4625 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4626 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' || 4626 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4627 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' || 4627 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4628 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) { 4628 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4629 #if DEBUG 4629 #if DEBUG
4630 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name, 4630 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4631 STp->buffer->b_data[MODE_HEADER_LENGTH + 2], 4631 STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4632 STp->buffer->b_data[MODE_HEADER_LENGTH + 3], 4632 STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4633 STp->buffer->b_data[MODE_HEADER_LENGTH + 4], 4633 STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4634 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]); 4634 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4635 #endif 4635 #endif
4636 STp->header_ok = 0; 4636 STp->header_ok = 0;
4637 } 4637 }
4638 i = STp->first_frame_position; 4638 i = STp->first_frame_position;
4639 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) { 4639 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4640 if (STp->door_locked == ST_UNLOCKED) { 4640 if (STp->door_locked == ST_UNLOCKED) {
4641 if (do_door_lock(STp, 1)) 4641 if (do_door_lock(STp, 1))
4642 printk(KERN_INFO "%s:I: Can't lock drive door\n", name); 4642 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4643 else 4643 else
4644 STp->door_locked = ST_LOCKED_AUTO; 4644 STp->door_locked = ST_LOCKED_AUTO;
4645 } 4645 }
4646 if (!STp->frame_in_buffer) { 4646 if (!STp->frame_in_buffer) {
4647 STp->block_size = (STm->default_blksize > 0) ? 4647 STp->block_size = (STm->default_blksize > 0) ?
4648 STm->default_blksize : OS_DATA_SIZE; 4648 STm->default_blksize : OS_DATA_SIZE;
4649 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0; 4649 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4650 } 4650 }
4651 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size; 4651 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4652 STp->fast_open = 1; 4652 STp->fast_open = 1;
4653 osst_release_request(SRpnt); 4653 osst_release_request(SRpnt);
4654 return 0; 4654 return 0;
4655 } 4655 }
4656 #if DEBUG 4656 #if DEBUG
4657 if (i != STp->first_frame_position) 4657 if (i != STp->first_frame_position)
4658 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n", 4658 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4659 name, i, STp->first_frame_position); 4659 name, i, STp->first_frame_position);
4660 #endif 4660 #endif
4661 STp->header_ok = 0; 4661 STp->header_ok = 0;
4662 } 4662 }
4663 STp->fast_open = 0; 4663 STp->fast_open = 0;
4664 4664
4665 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */ 4665 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4666 (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) { 4666 (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) {
4667 4667
4668 memset(cmd, 0, MAX_COMMAND_SIZE); 4668 memset(cmd, 0, MAX_COMMAND_SIZE);
4669 cmd[0] = MODE_SELECT; 4669 cmd[0] = MODE_SELECT;
4670 cmd[1] = 0x10; 4670 cmd[1] = 0x10;
4671 cmd[4] = 4 + MODE_HEADER_LENGTH; 4671 cmd[4] = 4 + MODE_HEADER_LENGTH;
4672 4672
4673 (STp->buffer)->b_data[0] = cmd[4] - 1; 4673 (STp->buffer)->b_data[0] = cmd[4] - 1;
4674 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */ 4674 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4675 (STp->buffer)->b_data[2] = 0; /* Reserved */ 4675 (STp->buffer)->b_data[2] = 0; /* Reserved */
4676 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */ 4676 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4677 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f; 4677 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4678 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1; 4678 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4679 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2; 4679 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4680 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3; 4680 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4681 4681
4682 #if DEBUG 4682 #if DEBUG
4683 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name); 4683 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4684 #endif 4684 #endif
4685 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); 4685 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4686 4686
4687 STp->header_ok = 0; 4687 STp->header_ok = 0;
4688 4688
4689 for (i=0; i < 10; i++) { 4689 for (i=0; i < 10; i++) {
4690 4690
4691 memset (cmd, 0, MAX_COMMAND_SIZE); 4691 memset (cmd, 0, MAX_COMMAND_SIZE);
4692 cmd[0] = TEST_UNIT_READY; 4692 cmd[0] = TEST_UNIT_READY;
4693 4693
4694 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, 4694 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4695 STp->timeout, MAX_RETRIES, 1); 4695 STp->timeout, MAX_RETRIES, 1);
4696 if ((SRpnt->sense[0] & 0x70) != 0x70 || 4696 if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4697 (SRpnt->sense[2] & 0x0f) == NOT_READY) 4697 (SRpnt->sense[2] & 0x0f) == NOT_READY)
4698 break; 4698 break;
4699 4699
4700 if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { 4700 if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
4701 int j;
4702
4701 STp->pos_unknown = 0; 4703 STp->pos_unknown = 0;
4702 STp->partition = STp->new_partition = 0; 4704 STp->partition = STp->new_partition = 0;
4703 if (STp->can_partitions) 4705 if (STp->can_partitions)
4704 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */ 4706 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4705 int j;
4706 for (j = 0; j < ST_NBR_PARTITIONS; j++) { 4707 for (j = 0; j < ST_NBR_PARTITIONS; j++) {
4707 STps = &(STp->ps[j]); 4708 STps = &(STp->ps[j]);
4708 STps->rw = ST_IDLE; 4709 STps->rw = ST_IDLE;
4709 STps->eof = ST_NOEOF; 4710 STps->eof = ST_NOEOF;
4710 STps->at_sm = 0; 4711 STps->at_sm = 0;
4711 STps->last_block_valid = 0; 4712 STps->last_block_valid = 0;
4712 STps->drv_block = 0; 4713 STps->drv_block = 0;
4713 STps->drv_file = 0 ; 4714 STps->drv_file = 0 ;
4714 } 4715 }
4715 new_session = 1; 4716 new_session = 1;
4716 } 4717 }
4717 } 4718 }
4718 } 4719 }
4719 4720
4720 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */ 4721 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4721 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name); 4722 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4722 4723
4723 if ((STp->buffer)->syscall_result != 0) { 4724 if ((STp->buffer)->syscall_result != 0) {
4724 if ((STp->device)->scsi_level >= SCSI_2 && 4725 if ((STp->device)->scsi_level >= SCSI_2 &&
4725 (SRpnt->sense[0] & 0x70) == 0x70 && 4726 (SRpnt->sense[0] & 0x70) == 0x70 &&
4726 (SRpnt->sense[2] & 0x0f) == NOT_READY && 4727 (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4727 SRpnt->sense[12] == 0x3a) { /* Check ASC */ 4728 SRpnt->sense[12] == 0x3a) { /* Check ASC */
4728 STp->ready = ST_NO_TAPE; 4729 STp->ready = ST_NO_TAPE;
4729 } else 4730 } else
4730 STp->ready = ST_NOT_READY; 4731 STp->ready = ST_NOT_READY;
4731 osst_release_request(SRpnt); 4732 osst_release_request(SRpnt);
4732 SRpnt = NULL; 4733 SRpnt = NULL;
4733 STp->density = 0; /* Clear the erroneous "residue" */ 4734 STp->density = 0; /* Clear the erroneous "residue" */
4734 STp->write_prot = 0; 4735 STp->write_prot = 0;
4735 STp->block_size = 0; 4736 STp->block_size = 0;
4736 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1); 4737 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4737 STp->partition = STp->new_partition = 0; 4738 STp->partition = STp->new_partition = 0;
4738 STp->door_locked = ST_UNLOCKED; 4739 STp->door_locked = ST_UNLOCKED;
4739 return 0; 4740 return 0;
4740 } 4741 }
4741 4742
4742 osst_configure_onstream(STp, &SRpnt); 4743 osst_configure_onstream(STp, &SRpnt);
4743 4744
4744 STp->block_size = STp->raw ? OS_FRAME_SIZE : ( 4745 STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4745 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE); 4746 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4746 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size; 4747 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4747 STp->buffer->buffer_bytes = 4748 STp->buffer->buffer_bytes =
4748 STp->buffer->read_pointer = 4749 STp->buffer->read_pointer =
4749 STp->frame_in_buffer = 0; 4750 STp->frame_in_buffer = 0;
4750 4751
4751 #if DEBUG 4752 #if DEBUG
4752 if (debugging) 4753 if (debugging)
4753 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n", 4754 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4754 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size, 4755 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4755 (STp->buffer)->buffer_blocks); 4756 (STp->buffer)->buffer_blocks);
4756 #endif 4757 #endif
4757 4758
4758 if (STp->drv_write_prot) { 4759 if (STp->drv_write_prot) {
4759 STp->write_prot = 1; 4760 STp->write_prot = 1;
4760 #if DEBUG 4761 #if DEBUG
4761 if (debugging) 4762 if (debugging)
4762 printk(OSST_DEB_MSG "%s:D: Write protected\n", name); 4763 printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4763 #endif 4764 #endif
4764 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) { 4765 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4765 retval = (-EROFS); 4766 retval = (-EROFS);
4766 goto err_out; 4767 goto err_out;
4767 } 4768 }
4768 } 4769 }
4769 4770
4770 if (new_session) { /* Change the drive parameters for the new mode */ 4771 if (new_session) { /* Change the drive parameters for the new mode */
4771 #if DEBUG 4772 #if DEBUG
4772 if (debugging) 4773 if (debugging)
4773 printk(OSST_DEB_MSG "%s:D: New Session\n", name); 4774 printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4774 #endif 4775 #endif
4775 STp->density_changed = STp->blksize_changed = 0; 4776 STp->density_changed = STp->blksize_changed = 0;
4776 STp->compression_changed = 0; 4777 STp->compression_changed = 0;
4777 } 4778 }
4778 4779
4779 /* 4780 /*
4780 * properly position the tape and check the ADR headers 4781 * properly position the tape and check the ADR headers
4781 */ 4782 */
4782 if (STp->door_locked == ST_UNLOCKED) { 4783 if (STp->door_locked == ST_UNLOCKED) {
4783 if (do_door_lock(STp, 1)) 4784 if (do_door_lock(STp, 1))
4784 printk(KERN_INFO "%s:I: Can't lock drive door\n", name); 4785 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4785 else 4786 else
4786 STp->door_locked = ST_LOCKED_AUTO; 4787 STp->door_locked = ST_LOCKED_AUTO;
4787 } 4788 }
4788 4789
4789 osst_analyze_headers(STp, &SRpnt); 4790 osst_analyze_headers(STp, &SRpnt);
4790 4791
4791 osst_release_request(SRpnt); 4792 osst_release_request(SRpnt);
4792 SRpnt = NULL; 4793 SRpnt = NULL;
4793 4794
4794 return 0; 4795 return 0;
4795 4796
4796 err_out: 4797 err_out:
4797 if (SRpnt != NULL) 4798 if (SRpnt != NULL)
4798 osst_release_request(SRpnt); 4799 osst_release_request(SRpnt);
4799 normalize_buffer(STp->buffer); 4800 normalize_buffer(STp->buffer);
4800 STp->header_ok = 0; 4801 STp->header_ok = 0;
4801 STp->in_use = 0; 4802 STp->in_use = 0;
4802 scsi_device_put(STp->device); 4803 scsi_device_put(STp->device);
4803 4804
4804 return retval; 4805 return retval;
4805 } 4806 }
4806 4807
4807 /* BKL pushdown: spaghetti avoidance wrapper */ 4808 /* BKL pushdown: spaghetti avoidance wrapper */
4808 static int os_scsi_tape_open(struct inode * inode, struct file * filp) 4809 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4809 { 4810 {
4810 int ret; 4811 int ret;
4811 4812
4812 mutex_lock(&osst_int_mutex); 4813 mutex_lock(&osst_int_mutex);
4813 ret = __os_scsi_tape_open(inode, filp); 4814 ret = __os_scsi_tape_open(inode, filp);
4814 mutex_unlock(&osst_int_mutex); 4815 mutex_unlock(&osst_int_mutex);
4815 return ret; 4816 return ret;
4816 } 4817 }
4817 4818
4818 4819
4819 4820
4820 /* Flush the tape buffer before close */ 4821 /* Flush the tape buffer before close */
4821 static int os_scsi_tape_flush(struct file * filp, fl_owner_t id) 4822 static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
4822 { 4823 {
4823 int result = 0, result2; 4824 int result = 0, result2;
4824 struct osst_tape * STp = filp->private_data; 4825 struct osst_tape * STp = filp->private_data;
4825 struct st_modedef * STm = &(STp->modes[STp->current_mode]); 4826 struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4826 struct st_partstat * STps = &(STp->ps[STp->partition]); 4827 struct st_partstat * STps = &(STp->ps[STp->partition]);
4827 struct osst_request * SRpnt = NULL; 4828 struct osst_request * SRpnt = NULL;
4828 char * name = tape_name(STp); 4829 char * name = tape_name(STp);
4829 4830
4830 if (file_count(filp) > 1) 4831 if (file_count(filp) > 1)
4831 return 0; 4832 return 0;
4832 4833
4833 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) { 4834 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4834 STp->write_type = OS_WRITE_DATA; 4835 STp->write_type = OS_WRITE_DATA;
4835 result = osst_flush_write_buffer(STp, &SRpnt); 4836 result = osst_flush_write_buffer(STp, &SRpnt);
4836 if (result != 0 && result != (-ENOSPC)) 4837 if (result != 0 && result != (-ENOSPC))
4837 goto out; 4838 goto out;
4838 } 4839 }
4839 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) { 4840 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4840 4841
4841 #if DEBUG 4842 #if DEBUG
4842 if (debugging) { 4843 if (debugging) {
4843 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n", 4844 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4844 name, (long)(filp->f_pos)); 4845 name, (long)(filp->f_pos));
4845 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n", 4846 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4846 name, STp->nbr_waits, STp->nbr_finished); 4847 name, STp->nbr_waits, STp->nbr_finished);
4847 } 4848 }
4848 #endif 4849 #endif
4849 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close)); 4850 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4850 #if DEBUG 4851 #if DEBUG
4851 if (debugging) 4852 if (debugging)
4852 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n", 4853 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4853 name, 1+STp->two_fm); 4854 name, 1+STp->two_fm);
4854 #endif 4855 #endif
4855 } 4856 }
4856 else if (!STp->rew_at_close) { 4857 else if (!STp->rew_at_close) {
4857 STps = &(STp->ps[STp->partition]); 4858 STps = &(STp->ps[STp->partition]);
4858 if (!STm->sysv || STps->rw != ST_READING) { 4859 if (!STm->sysv || STps->rw != ST_READING) {
4859 if (STp->can_bsr) 4860 if (STp->can_bsr)
4860 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */ 4861 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4861 else if (STps->eof == ST_FM_HIT) { 4862 else if (STps->eof == ST_FM_HIT) {
4862 result = cross_eof(STp, &SRpnt, 0); 4863 result = cross_eof(STp, &SRpnt, 0);
4863 if (result) { 4864 if (result) {
4864 if (STps->drv_file >= 0) 4865 if (STps->drv_file >= 0)
4865 STps->drv_file++; 4866 STps->drv_file++;
4866 STps->drv_block = 0; 4867 STps->drv_block = 0;
4867 STps->eof = ST_FM; 4868 STps->eof = ST_FM;
4868 } 4869 }
4869 else 4870 else
4870 STps->eof = ST_NOEOF; 4871 STps->eof = ST_NOEOF;
4871 } 4872 }
4872 } 4873 }
4873 else if ((STps->eof == ST_NOEOF && 4874 else if ((STps->eof == ST_NOEOF &&
4874 !(result = cross_eof(STp, &SRpnt, 1))) || 4875 !(result = cross_eof(STp, &SRpnt, 1))) ||
4875 STps->eof == ST_FM_HIT) { 4876 STps->eof == ST_FM_HIT) {
4876 if (STps->drv_file >= 0) 4877 if (STps->drv_file >= 0)
4877 STps->drv_file++; 4878 STps->drv_file++;
4878 STps->drv_block = 0; 4879 STps->drv_block = 0;
4879 STps->eof = ST_FM; 4880 STps->eof = ST_FM;
4880 } 4881 }
4881 } 4882 }
4882 4883
4883 out: 4884 out:
4884 if (STp->rew_at_close) { 4885 if (STp->rew_at_close) {
4885 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos); 4886 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4886 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0; 4887 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4887 if (result == 0 && result2 < 0) 4888 if (result == 0 && result2 < 0)
4888 result = result2; 4889 result = result2;
4889 } 4890 }
4890 if (SRpnt) osst_release_request(SRpnt); 4891 if (SRpnt) osst_release_request(SRpnt);
4891 4892
4892 if (STp->abort_count || STp->recover_count) { 4893 if (STp->abort_count || STp->recover_count) {
4893 printk(KERN_INFO "%s:I:", name); 4894 printk(KERN_INFO "%s:I:", name);
4894 if (STp->abort_count) 4895 if (STp->abort_count)
4895 printk(" %d unrecovered errors", STp->abort_count); 4896 printk(" %d unrecovered errors", STp->abort_count);
4896 if (STp->recover_count) 4897 if (STp->recover_count)
4897 printk(" %d recovered errors", STp->recover_count); 4898 printk(" %d recovered errors", STp->recover_count);
4898 if (STp->write_count) 4899 if (STp->write_count)
4899 printk(" in %d frames written", STp->write_count); 4900 printk(" in %d frames written", STp->write_count);
4900 if (STp->read_count) 4901 if (STp->read_count)
4901 printk(" in %d frames read", STp->read_count); 4902 printk(" in %d frames read", STp->read_count);
4902 printk("\n"); 4903 printk("\n");
4903 STp->recover_count = 0; 4904 STp->recover_count = 0;
4904 STp->abort_count = 0; 4905 STp->abort_count = 0;
4905 } 4906 }
4906 STp->write_count = 0; 4907 STp->write_count = 0;
4907 STp->read_count = 0; 4908 STp->read_count = 0;
4908 4909
4909 return result; 4910 return result;
4910 } 4911 }
4911 4912
4912 4913
4913 /* Close the device and release it */ 4914 /* Close the device and release it */
4914 static int os_scsi_tape_close(struct inode * inode, struct file * filp) 4915 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4915 { 4916 {
4916 int result = 0; 4917 int result = 0;
4917 struct osst_tape * STp = filp->private_data; 4918 struct osst_tape * STp = filp->private_data;
4918 4919
4919 if (STp->door_locked == ST_LOCKED_AUTO) 4920 if (STp->door_locked == ST_LOCKED_AUTO)
4920 do_door_lock(STp, 0); 4921 do_door_lock(STp, 0);
4921 4922
4922 if (STp->raw) 4923 if (STp->raw)
4923 STp->header_ok = 0; 4924 STp->header_ok = 0;
4924 4925
4925 normalize_buffer(STp->buffer); 4926 normalize_buffer(STp->buffer);
4926 write_lock(&os_scsi_tapes_lock); 4927 write_lock(&os_scsi_tapes_lock);
4927 STp->in_use = 0; 4928 STp->in_use = 0;
4928 write_unlock(&os_scsi_tapes_lock); 4929 write_unlock(&os_scsi_tapes_lock);
4929 4930
4930 scsi_device_put(STp->device); 4931 scsi_device_put(STp->device);
4931 4932
4932 return result; 4933 return result;
4933 } 4934 }
4934 4935
4935 4936
4936 /* The ioctl command */ 4937 /* The ioctl command */
4937 static long osst_ioctl(struct file * file, 4938 static long osst_ioctl(struct file * file,
4938 unsigned int cmd_in, unsigned long arg) 4939 unsigned int cmd_in, unsigned long arg)
4939 { 4940 {
4940 int i, cmd_nr, cmd_type, blk, retval = 0; 4941 int i, cmd_nr, cmd_type, blk, retval = 0;
4941 struct st_modedef * STm; 4942 struct st_modedef * STm;
4942 struct st_partstat * STps; 4943 struct st_partstat * STps;
4943 struct osst_request * SRpnt = NULL; 4944 struct osst_request * SRpnt = NULL;
4944 struct osst_tape * STp = file->private_data; 4945 struct osst_tape * STp = file->private_data;
4945 char * name = tape_name(STp); 4946 char * name = tape_name(STp);
4946 void __user * p = (void __user *)arg; 4947 void __user * p = (void __user *)arg;
4947 4948
4948 mutex_lock(&osst_int_mutex); 4949 mutex_lock(&osst_int_mutex);
4949 if (mutex_lock_interruptible(&STp->lock)) { 4950 if (mutex_lock_interruptible(&STp->lock)) {
4950 mutex_unlock(&osst_int_mutex); 4951 mutex_unlock(&osst_int_mutex);
4951 return -ERESTARTSYS; 4952 return -ERESTARTSYS;
4952 } 4953 }
4953 4954
4954 #if DEBUG 4955 #if DEBUG
4955 if (debugging && !STp->in_use) { 4956 if (debugging && !STp->in_use) {
4956 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name); 4957 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4957 retval = (-EIO); 4958 retval = (-EIO);
4958 goto out; 4959 goto out;
4959 } 4960 }
4960 #endif 4961 #endif
4961 STm = &(STp->modes[STp->current_mode]); 4962 STm = &(STp->modes[STp->current_mode]);
4962 STps = &(STp->ps[STp->partition]); 4963 STps = &(STp->ps[STp->partition]);
4963 4964
4964 /* 4965 /*
4965 * If we are in the middle of error recovery, don't let anyone 4966 * If we are in the middle of error recovery, don't let anyone
4966 * else try and use this device. Also, if error recovery fails, it 4967 * else try and use this device. Also, if error recovery fails, it
4967 * may try and take the device offline, in which case all further 4968 * may try and take the device offline, in which case all further
4968 * access to the device is prohibited. 4969 * access to the device is prohibited.
4969 */ 4970 */
4970 if( !scsi_block_when_processing_errors(STp->device) ) { 4971 if( !scsi_block_when_processing_errors(STp->device) ) {
4971 retval = (-ENXIO); 4972 retval = (-ENXIO);
4972 goto out; 4973 goto out;
4973 } 4974 }
4974 4975
4975 cmd_type = _IOC_TYPE(cmd_in); 4976 cmd_type = _IOC_TYPE(cmd_in);
4976 cmd_nr = _IOC_NR(cmd_in); 4977 cmd_nr = _IOC_NR(cmd_in);
4977 #if DEBUG 4978 #if DEBUG
4978 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name, 4979 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4979 cmd_type, cmd_nr, STp->raw?"raw":"normal"); 4980 cmd_type, cmd_nr, STp->raw?"raw":"normal");
4980 #endif 4981 #endif
4981 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) { 4982 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4982 struct mtop mtc; 4983 struct mtop mtc;
4983 int auto_weof = 0; 4984 int auto_weof = 0;
4984 4985
4985 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) { 4986 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
4986 retval = (-EINVAL); 4987 retval = (-EINVAL);
4987 goto out; 4988 goto out;
4988 } 4989 }
4989 4990
4990 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop)); 4991 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
4991 if (i) { 4992 if (i) {
4992 retval = (-EFAULT); 4993 retval = (-EFAULT);
4993 goto out; 4994 goto out;
4994 } 4995 }
4995 4996
4996 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) { 4997 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
4997 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name); 4998 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
4998 retval = (-EPERM); 4999 retval = (-EPERM);
4999 goto out; 5000 goto out;
5000 } 5001 }
5001 5002
5002 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) { 5003 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
5003 retval = (-ENXIO); 5004 retval = (-ENXIO);
5004 goto out; 5005 goto out;
5005 } 5006 }
5006 5007
5007 if (!STp->pos_unknown) { 5008 if (!STp->pos_unknown) {
5008 5009
5009 if (STps->eof == ST_FM_HIT) { 5010 if (STps->eof == ST_FM_HIT) {
5010 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) { 5011 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
5011 mtc.mt_count -= 1; 5012 mtc.mt_count -= 1;
5012 if (STps->drv_file >= 0) 5013 if (STps->drv_file >= 0)
5013 STps->drv_file += 1; 5014 STps->drv_file += 1;
5014 } 5015 }
5015 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) { 5016 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
5016 mtc.mt_count += 1; 5017 mtc.mt_count += 1;
5017 if (STps->drv_file >= 0) 5018 if (STps->drv_file >= 0)
5018 STps->drv_file += 1; 5019 STps->drv_file += 1;
5019 } 5020 }
5020 } 5021 }
5021 5022
5022 if (mtc.mt_op == MTSEEK) { 5023 if (mtc.mt_op == MTSEEK) {
5023 /* Old position must be restored if partition will be changed */ 5024 /* Old position must be restored if partition will be changed */
5024 i = !STp->can_partitions || (STp->new_partition != STp->partition); 5025 i = !STp->can_partitions || (STp->new_partition != STp->partition);
5025 } 5026 }
5026 else { 5027 else {
5027 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL || 5028 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
5028 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM || 5029 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
5029 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD || 5030 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
5030 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM || 5031 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
5031 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM || 5032 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
5032 mtc.mt_op == MTCOMPRESSION; 5033 mtc.mt_op == MTCOMPRESSION;
5033 } 5034 }
5034 i = osst_flush_buffer(STp, &SRpnt, i); 5035 i = osst_flush_buffer(STp, &SRpnt, i);
5035 if (i < 0) { 5036 if (i < 0) {
5036 retval = i; 5037 retval = i;
5037 goto out; 5038 goto out;
5038 } 5039 }
5039 } 5040 }
5040 else { 5041 else {
5041 /* 5042 /*
5042 * If there was a bus reset, block further access 5043 * If there was a bus reset, block further access
5043 * to this device. If the user wants to rewind the tape, 5044 * to this device. If the user wants to rewind the tape,
5044 * then reset the flag and allow access again. 5045 * then reset the flag and allow access again.
5045 */ 5046 */
5046 if(mtc.mt_op != MTREW && 5047 if(mtc.mt_op != MTREW &&
5047 mtc.mt_op != MTOFFL && 5048 mtc.mt_op != MTOFFL &&
5048 mtc.mt_op != MTRETEN && 5049 mtc.mt_op != MTRETEN &&
5049 mtc.mt_op != MTERASE && 5050 mtc.mt_op != MTERASE &&
5050 mtc.mt_op != MTSEEK && 5051 mtc.mt_op != MTSEEK &&
5051 mtc.mt_op != MTEOM) { 5052 mtc.mt_op != MTEOM) {
5052 retval = (-EIO); 5053 retval = (-EIO);
5053 goto out; 5054 goto out;
5054 } 5055 }
5055 reset_state(STp); 5056 reset_state(STp);
5056 /* remove this when the midlevel properly clears was_reset */ 5057 /* remove this when the midlevel properly clears was_reset */
5057 STp->device->was_reset = 0; 5058 STp->device->was_reset = 0;
5058 } 5059 }
5059 5060
5060 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK && 5061 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK &&
5061 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK && 5062 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
5062 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER && 5063 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER &&
5063 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART && 5064 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART &&
5064 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) { 5065 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) {
5065 5066
5066 /* 5067 /*
5067 * The user tells us to move to another position on the tape. 5068 * The user tells us to move to another position on the tape.
5068 * If we were appending to the tape content, that would leave 5069 * If we were appending to the tape content, that would leave
5069 * the tape without proper end, in that case write EOD and 5070 * the tape without proper end, in that case write EOD and
5070 * update the header to reflect its position. 5071 * update the header to reflect its position.
5071 */ 5072 */
5072 #if DEBUG 5073 #if DEBUG
5073 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name, 5074 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
5074 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle", 5075 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
5075 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number, 5076 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
5076 STp->logical_blk_num, STps->drv_file, STps->drv_block ); 5077 STp->logical_blk_num, STps->drv_file, STps->drv_block );
5077 #endif 5078 #endif
5078 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) { 5079 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
5079 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) && 5080 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
5080 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL)); 5081 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
5081 i = osst_write_trailer(STp, &SRpnt, 5082 i = osst_write_trailer(STp, &SRpnt,
5082 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL)); 5083 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
5083 #if DEBUG 5084 #if DEBUG
5084 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", 5085 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
5085 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos, 5086 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
5086 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block ); 5087 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
5087 #endif 5088 #endif
5088 if (i < 0) { 5089 if (i < 0) {
5089 retval = i; 5090 retval = i;
5090 goto out; 5091 goto out;
5091 } 5092 }
5092 } 5093 }
5093 STps->rw = ST_IDLE; 5094 STps->rw = ST_IDLE;
5094 } 5095 }
5095 5096
5096 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED) 5097 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
5097 do_door_lock(STp, 0); /* Ignore result! */ 5098 do_door_lock(STp, 0); /* Ignore result! */
5098 5099
5099 if (mtc.mt_op == MTSETDRVBUFFER && 5100 if (mtc.mt_op == MTSETDRVBUFFER &&
5100 (mtc.mt_count & MT_ST_OPTIONS) != 0) { 5101 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
5101 retval = osst_set_options(STp, mtc.mt_count); 5102 retval = osst_set_options(STp, mtc.mt_count);
5102 goto out; 5103 goto out;
5103 } 5104 }
5104 5105
5105 if (mtc.mt_op == MTSETPART) { 5106 if (mtc.mt_op == MTSETPART) {
5106 if (mtc.mt_count >= STp->nbr_partitions) 5107 if (mtc.mt_count >= STp->nbr_partitions)
5107 retval = -EINVAL; 5108 retval = -EINVAL;
5108 else { 5109 else {
5109 STp->new_partition = mtc.mt_count; 5110 STp->new_partition = mtc.mt_count;
5110 retval = 0; 5111 retval = 0;
5111 } 5112 }
5112 goto out; 5113 goto out;
5113 } 5114 }
5114 5115
5115 if (mtc.mt_op == MTMKPART) { 5116 if (mtc.mt_op == MTMKPART) {
5116 if (!STp->can_partitions) { 5117 if (!STp->can_partitions) {
5117 retval = (-EINVAL); 5118 retval = (-EINVAL);
5118 goto out; 5119 goto out;
5119 } 5120 }
5120 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*|| 5121 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
5121 (i = partition_tape(inode, mtc.mt_count)) < 0*/) { 5122 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
5122 retval = i; 5123 retval = i;
5123 goto out; 5124 goto out;
5124 } 5125 }
5125 for (i=0; i < ST_NBR_PARTITIONS; i++) { 5126 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5126 STp->ps[i].rw = ST_IDLE; 5127 STp->ps[i].rw = ST_IDLE;
5127 STp->ps[i].at_sm = 0; 5128 STp->ps[i].at_sm = 0;
5128 STp->ps[i].last_block_valid = 0; 5129 STp->ps[i].last_block_valid = 0;
5129 } 5130 }
5130 STp->partition = STp->new_partition = 0; 5131 STp->partition = STp->new_partition = 0;
5131 STp->nbr_partitions = 1; /* Bad guess ?-) */ 5132 STp->nbr_partitions = 1; /* Bad guess ?-) */
5132 STps->drv_block = STps->drv_file = 0; 5133 STps->drv_block = STps->drv_file = 0;
5133 retval = 0; 5134 retval = 0;
5134 goto out; 5135 goto out;
5135 } 5136 }
5136 5137
5137 if (mtc.mt_op == MTSEEK) { 5138 if (mtc.mt_op == MTSEEK) {
5138 if (STp->raw) 5139 if (STp->raw)
5139 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0); 5140 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
5140 else 5141 else
5141 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count); 5142 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
5142 if (!STp->can_partitions) 5143 if (!STp->can_partitions)
5143 STp->ps[0].rw = ST_IDLE; 5144 STp->ps[0].rw = ST_IDLE;
5144 retval = i; 5145 retval = i;
5145 goto out; 5146 goto out;
5146 } 5147 }
5147 5148
5148 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) { 5149 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
5149 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK)); 5150 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
5150 goto out; 5151 goto out;
5151 } 5152 }
5152 5153
5153 if (auto_weof) 5154 if (auto_weof)
5154 cross_eof(STp, &SRpnt, 0); 5155 cross_eof(STp, &SRpnt, 0);
5155 5156
5156 if (mtc.mt_op == MTCOMPRESSION) 5157 if (mtc.mt_op == MTCOMPRESSION)
5157 retval = -EINVAL; /* OnStream drives don't have compression hardware */ 5158 retval = -EINVAL; /* OnStream drives don't have compression hardware */
5158 else 5159 else
5159 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS 5160 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5160 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */ 5161 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5161 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count); 5162 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5162 goto out; 5163 goto out;
5163 } 5164 }
5164 5165
5165 if (!STm->defined) { 5166 if (!STm->defined) {
5166 retval = (-ENXIO); 5167 retval = (-ENXIO);
5167 goto out; 5168 goto out;
5168 } 5169 }
5169 5170
5170 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) { 5171 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5171 retval = i; 5172 retval = i;
5172 goto out; 5173 goto out;
5173 } 5174 }
5174 5175
5175 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) { 5176 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
5176 struct mtget mt_status; 5177 struct mtget mt_status;
5177 5178
5178 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) { 5179 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
5179 retval = (-EINVAL); 5180 retval = (-EINVAL);
5180 goto out; 5181 goto out;
5181 } 5182 }
5182 5183
5183 mt_status.mt_type = MT_ISONSTREAM_SC; 5184 mt_status.mt_type = MT_ISONSTREAM_SC;
5184 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT; 5185 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
5185 mt_status.mt_dsreg = 5186 mt_status.mt_dsreg =
5186 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) | 5187 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
5187 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK); 5188 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
5188 mt_status.mt_blkno = STps->drv_block; 5189 mt_status.mt_blkno = STps->drv_block;
5189 mt_status.mt_fileno = STps->drv_file; 5190 mt_status.mt_fileno = STps->drv_file;
5190 if (STp->block_size != 0) { 5191 if (STp->block_size != 0) {
5191 if (STps->rw == ST_WRITING) 5192 if (STps->rw == ST_WRITING)
5192 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size; 5193 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
5193 else if (STps->rw == ST_READING) 5194 else if (STps->rw == ST_READING)
5194 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes + 5195 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
5195 STp->block_size - 1) / STp->block_size; 5196 STp->block_size - 1) / STp->block_size;
5196 } 5197 }
5197 5198
5198 mt_status.mt_gstat = 0; 5199 mt_status.mt_gstat = 0;
5199 if (STp->drv_write_prot) 5200 if (STp->drv_write_prot)
5200 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff); 5201 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
5201 if (mt_status.mt_blkno == 0) { 5202 if (mt_status.mt_blkno == 0) {
5202 if (mt_status.mt_fileno == 0) 5203 if (mt_status.mt_fileno == 0)
5203 mt_status.mt_gstat |= GMT_BOT(0xffffffff); 5204 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
5204 else 5205 else
5205 mt_status.mt_gstat |= GMT_EOF(0xffffffff); 5206 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
5206 } 5207 }
5207 mt_status.mt_resid = STp->partition; 5208 mt_status.mt_resid = STp->partition;
5208 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR) 5209 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
5209 mt_status.mt_gstat |= GMT_EOT(0xffffffff); 5210 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
5210 else if (STps->eof >= ST_EOM_OK) 5211 else if (STps->eof >= ST_EOM_OK)
5211 mt_status.mt_gstat |= GMT_EOD(0xffffffff); 5212 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
5212 if (STp->density == 1) 5213 if (STp->density == 1)
5213 mt_status.mt_gstat |= GMT_D_800(0xffffffff); 5214 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
5214 else if (STp->density == 2) 5215 else if (STp->density == 2)
5215 mt_status.mt_gstat |= GMT_D_1600(0xffffffff); 5216 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
5216 else if (STp->density == 3) 5217 else if (STp->density == 3)
5217 mt_status.mt_gstat |= GMT_D_6250(0xffffffff); 5218 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
5218 if (STp->ready == ST_READY) 5219 if (STp->ready == ST_READY)
5219 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff); 5220 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
5220 if (STp->ready == ST_NO_TAPE) 5221 if (STp->ready == ST_NO_TAPE)
5221 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff); 5222 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
5222 if (STps->at_sm) 5223 if (STps->at_sm)
5223 mt_status.mt_gstat |= GMT_SM(0xffffffff); 5224 mt_status.mt_gstat |= GMT_SM(0xffffffff);
5224 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) || 5225 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
5225 STp->drv_buffer != 0) 5226 STp->drv_buffer != 0)
5226 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff); 5227 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
5227 5228
5228 i = copy_to_user(p, &mt_status, sizeof(struct mtget)); 5229 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
5229 if (i) { 5230 if (i) {
5230 retval = (-EFAULT); 5231 retval = (-EFAULT);
5231 goto out; 5232 goto out;
5232 } 5233 }
5233 5234
5234 STp->recover_erreg = 0; /* Clear after read */ 5235 STp->recover_erreg = 0; /* Clear after read */
5235 retval = 0; 5236 retval = 0;
5236 goto out; 5237 goto out;
5237 } /* End of MTIOCGET */ 5238 } /* End of MTIOCGET */
5238 5239
5239 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) { 5240 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5240 struct mtpos mt_pos; 5241 struct mtpos mt_pos;
5241 5242
5242 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) { 5243 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5243 retval = (-EINVAL); 5244 retval = (-EINVAL);
5244 goto out; 5245 goto out;
5245 } 5246 }
5246 if (STp->raw) 5247 if (STp->raw)
5247 blk = osst_get_frame_position(STp, &SRpnt); 5248 blk = osst_get_frame_position(STp, &SRpnt);
5248 else 5249 else
5249 blk = osst_get_sector(STp, &SRpnt); 5250 blk = osst_get_sector(STp, &SRpnt);
5250 if (blk < 0) { 5251 if (blk < 0) {
5251 retval = blk; 5252 retval = blk;
5252 goto out; 5253 goto out;
5253 } 5254 }
5254 mt_pos.mt_blkno = blk; 5255 mt_pos.mt_blkno = blk;
5255 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos)); 5256 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5256 if (i) 5257 if (i)
5257 retval = -EFAULT; 5258 retval = -EFAULT;
5258 goto out; 5259 goto out;
5259 } 5260 }
5260 if (SRpnt) osst_release_request(SRpnt); 5261 if (SRpnt) osst_release_request(SRpnt);
5261 5262
5262 mutex_unlock(&STp->lock); 5263 mutex_unlock(&STp->lock);
5263 5264
5264 retval = scsi_ioctl(STp->device, cmd_in, p); 5265 retval = scsi_ioctl(STp->device, cmd_in, p);
5265 mutex_unlock(&osst_int_mutex); 5266 mutex_unlock(&osst_int_mutex);
5266 return retval; 5267 return retval;
5267 5268
5268 out: 5269 out:
5269 if (SRpnt) osst_release_request(SRpnt); 5270 if (SRpnt) osst_release_request(SRpnt);
5270 5271
5271 mutex_unlock(&STp->lock); 5272 mutex_unlock(&STp->lock);
5272 mutex_unlock(&osst_int_mutex); 5273 mutex_unlock(&osst_int_mutex);
5273 5274
5274 return retval; 5275 return retval;
5275 } 5276 }
5276 5277
5277 #ifdef CONFIG_COMPAT 5278 #ifdef CONFIG_COMPAT
5278 static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg) 5279 static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg)
5279 { 5280 {
5280 struct osst_tape *STp = file->private_data; 5281 struct osst_tape *STp = file->private_data;
5281 struct scsi_device *sdev = STp->device; 5282 struct scsi_device *sdev = STp->device;
5282 int ret = -ENOIOCTLCMD; 5283 int ret = -ENOIOCTLCMD;
5283 if (sdev->host->hostt->compat_ioctl) { 5284 if (sdev->host->hostt->compat_ioctl) {
5284 5285
5285 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg); 5286 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
5286 5287
5287 } 5288 }
5288 return ret; 5289 return ret;
5289 } 5290 }
5290 #endif 5291 #endif
5291 5292
5292 5293
5293 5294
5294 /* Memory handling routines */ 5295 /* Memory handling routines */
5295 5296
5296 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */ 5297 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5297 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg ) 5298 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5298 { 5299 {
5299 int i; 5300 int i;
5300 gfp_t priority; 5301 gfp_t priority;
5301 struct osst_buffer *tb; 5302 struct osst_buffer *tb;
5302 5303
5303 if (from_initialization) 5304 if (from_initialization)
5304 priority = GFP_ATOMIC; 5305 priority = GFP_ATOMIC;
5305 else 5306 else
5306 priority = GFP_KERNEL; 5307 priority = GFP_KERNEL;
5307 5308
5308 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); 5309 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5309 tb = kzalloc(i, priority); 5310 tb = kzalloc(i, priority);
5310 if (!tb) { 5311 if (!tb) {
5311 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n"); 5312 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5312 return NULL; 5313 return NULL;
5313 } 5314 }
5314 5315
5315 tb->sg_segs = tb->orig_sg_segs = 0; 5316 tb->sg_segs = tb->orig_sg_segs = 0;
5316 tb->use_sg = max_sg; 5317 tb->use_sg = max_sg;
5317 tb->in_use = 1; 5318 tb->in_use = 1;
5318 tb->dma = need_dma; 5319 tb->dma = need_dma;
5319 tb->buffer_size = 0; 5320 tb->buffer_size = 0;
5320 #if DEBUG 5321 #if DEBUG
5321 if (debugging) 5322 if (debugging)
5322 printk(OSST_DEB_MSG 5323 printk(OSST_DEB_MSG
5323 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n", 5324 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5324 i, max_sg, need_dma); 5325 i, max_sg, need_dma);
5325 #endif 5326 #endif
5326 return tb; 5327 return tb;
5327 } 5328 }
5328 5329
5329 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */ 5330 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5330 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma) 5331 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5331 { 5332 {
5332 int segs, nbr, max_segs, b_size, order, got; 5333 int segs, nbr, max_segs, b_size, order, got;
5333 gfp_t priority; 5334 gfp_t priority;
5334 5335
5335 if (STbuffer->buffer_size >= OS_FRAME_SIZE) 5336 if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5336 return 1; 5337 return 1;
5337 5338
5338 if (STbuffer->sg_segs) { 5339 if (STbuffer->sg_segs) {
5339 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n"); 5340 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5340 normalize_buffer(STbuffer); 5341 normalize_buffer(STbuffer);
5341 } 5342 }
5342 /* See how many segments we can use -- need at least two */ 5343 /* See how many segments we can use -- need at least two */
5343 nbr = max_segs = STbuffer->use_sg; 5344 nbr = max_segs = STbuffer->use_sg;
5344 if (nbr <= 2) 5345 if (nbr <= 2)
5345 return 0; 5346 return 0;
5346 5347
5347 priority = GFP_KERNEL /* | __GFP_NOWARN */; 5348 priority = GFP_KERNEL /* | __GFP_NOWARN */;
5348 if (need_dma) 5349 if (need_dma)
5349 priority |= GFP_DMA; 5350 priority |= GFP_DMA;
5350 5351
5351 /* Try to allocate the first segment up to OS_DATA_SIZE and the others 5352 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5352 big enough to reach the goal (code assumes no segments in place) */ 5353 big enough to reach the goal (code assumes no segments in place) */
5353 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) { 5354 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5354 struct page *page = alloc_pages(priority, order); 5355 struct page *page = alloc_pages(priority, order);
5355 5356
5356 STbuffer->sg[0].offset = 0; 5357 STbuffer->sg[0].offset = 0;
5357 if (page != NULL) { 5358 if (page != NULL) {
5358 sg_set_page(&STbuffer->sg[0], page, b_size, 0); 5359 sg_set_page(&STbuffer->sg[0], page, b_size, 0);
5359 STbuffer->b_data = page_address(page); 5360 STbuffer->b_data = page_address(page);
5360 break; 5361 break;
5361 } 5362 }
5362 } 5363 }
5363 if (sg_page(&STbuffer->sg[0]) == NULL) { 5364 if (sg_page(&STbuffer->sg[0]) == NULL) {
5364 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n"); 5365 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5365 return 0; 5366 return 0;
5366 } 5367 }
5367 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */ 5368 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5368 for (segs=STbuffer->sg_segs=1, got=b_size; 5369 for (segs=STbuffer->sg_segs=1, got=b_size;
5369 segs < max_segs && got < OS_FRAME_SIZE; ) { 5370 segs < max_segs && got < OS_FRAME_SIZE; ) {
5370 struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order); 5371 struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5371 STbuffer->sg[segs].offset = 0; 5372 STbuffer->sg[segs].offset = 0;
5372 if (page == NULL) { 5373 if (page == NULL) {
5373 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n", 5374 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5374 OS_FRAME_SIZE); 5375 OS_FRAME_SIZE);
5375 #if DEBUG 5376 #if DEBUG
5376 STbuffer->buffer_size = got; 5377 STbuffer->buffer_size = got;
5377 #endif 5378 #endif
5378 normalize_buffer(STbuffer); 5379 normalize_buffer(STbuffer);
5379 return 0; 5380 return 0;
5380 } 5381 }
5381 sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0); 5382 sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0);
5382 got += STbuffer->sg[segs].length; 5383 got += STbuffer->sg[segs].length;
5383 STbuffer->buffer_size = got; 5384 STbuffer->buffer_size = got;
5384 STbuffer->sg_segs = ++segs; 5385 STbuffer->sg_segs = ++segs;
5385 } 5386 }
5386 #if DEBUG 5387 #if DEBUG
5387 if (debugging) { 5388 if (debugging) {
5388 printk(OSST_DEB_MSG 5389 printk(OSST_DEB_MSG
5389 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n", 5390 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5390 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data); 5391 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5391 printk(OSST_DEB_MSG 5392 printk(OSST_DEB_MSG
5392 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n", 5393 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5393 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page), 5394 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5394 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page)); 5395 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5395 } 5396 }
5396 #endif 5397 #endif
5397 5398
5398 return 1; 5399 return 1;
5399 } 5400 }
5400 5401
5401 5402
5402 /* Release the segments */ 5403 /* Release the segments */
5403 static void normalize_buffer(struct osst_buffer *STbuffer) 5404 static void normalize_buffer(struct osst_buffer *STbuffer)
5404 { 5405 {
5405 int i, order, b_size; 5406 int i, order, b_size;
5406 5407
5407 for (i=0; i < STbuffer->sg_segs; i++) { 5408 for (i=0; i < STbuffer->sg_segs; i++) {
5408 5409
5409 for (b_size = PAGE_SIZE, order = 0; 5410 for (b_size = PAGE_SIZE, order = 0;
5410 b_size < STbuffer->sg[i].length; 5411 b_size < STbuffer->sg[i].length;
5411 b_size *= 2, order++); 5412 b_size *= 2, order++);
5412 5413
5413 __free_pages(sg_page(&STbuffer->sg[i]), order); 5414 __free_pages(sg_page(&STbuffer->sg[i]), order);
5414 STbuffer->buffer_size -= STbuffer->sg[i].length; 5415 STbuffer->buffer_size -= STbuffer->sg[i].length;
5415 } 5416 }
5416 #if DEBUG 5417 #if DEBUG
5417 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs) 5418 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5418 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n", 5419 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5419 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs); 5420 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5420 #endif 5421 #endif
5421 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0; 5422 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5422 } 5423 }
5423 5424
5424 5425
5425 /* Move data from the user buffer to the tape buffer. Returns zero (success) or 5426 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5426 negative error code. */ 5427 negative error code. */
5427 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count) 5428 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
5428 { 5429 {
5429 int i, cnt, res, offset; 5430 int i, cnt, res, offset;
5430 5431
5431 for (i=0, offset=st_bp->buffer_bytes; 5432 for (i=0, offset=st_bp->buffer_bytes;
5432 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) 5433 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5433 offset -= st_bp->sg[i].length; 5434 offset -= st_bp->sg[i].length;
5434 if (i == st_bp->sg_segs) { /* Should never happen */ 5435 if (i == st_bp->sg_segs) { /* Should never happen */
5435 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n"); 5436 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5436 return (-EIO); 5437 return (-EIO);
5437 } 5438 }
5438 for ( ; i < st_bp->sg_segs && do_count > 0; i++) { 5439 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5439 cnt = st_bp->sg[i].length - offset < do_count ? 5440 cnt = st_bp->sg[i].length - offset < do_count ?
5440 st_bp->sg[i].length - offset : do_count; 5441 st_bp->sg[i].length - offset : do_count;
5441 res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt); 5442 res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
5442 if (res) 5443 if (res)
5443 return (-EFAULT); 5444 return (-EFAULT);
5444 do_count -= cnt; 5445 do_count -= cnt;
5445 st_bp->buffer_bytes += cnt; 5446 st_bp->buffer_bytes += cnt;
5446 ubp += cnt; 5447 ubp += cnt;
5447 offset = 0; 5448 offset = 0;
5448 } 5449 }
5449 if (do_count) { /* Should never happen */ 5450 if (do_count) { /* Should never happen */
5450 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n", 5451 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5451 do_count); 5452 do_count);
5452 return (-EIO); 5453 return (-EIO);
5453 } 5454 }
5454 return 0; 5455 return 0;
5455 } 5456 }
5456 5457
5457 5458
5458 /* Move data from the tape buffer to the user buffer. Returns zero (success) or 5459 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5459 negative error code. */ 5460 negative error code. */
5460 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count) 5461 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
5461 { 5462 {
5462 int i, cnt, res, offset; 5463 int i, cnt, res, offset;
5463 5464
5464 for (i=0, offset=st_bp->read_pointer; 5465 for (i=0, offset=st_bp->read_pointer;
5465 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) 5466 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5466 offset -= st_bp->sg[i].length; 5467 offset -= st_bp->sg[i].length;
5467 if (i == st_bp->sg_segs) { /* Should never happen */ 5468 if (i == st_bp->sg_segs) { /* Should never happen */
5468 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n"); 5469 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5469 return (-EIO); 5470 return (-EIO);
5470 } 5471 }
5471 for ( ; i < st_bp->sg_segs && do_count > 0; i++) { 5472 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5472 cnt = st_bp->sg[i].length - offset < do_count ? 5473 cnt = st_bp->sg[i].length - offset < do_count ?
5473 st_bp->sg[i].length - offset : do_count; 5474 st_bp->sg[i].length - offset : do_count;
5474 res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt); 5475 res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
5475 if (res) 5476 if (res)
5476 return (-EFAULT); 5477 return (-EFAULT);
5477 do_count -= cnt; 5478 do_count -= cnt;
5478 st_bp->buffer_bytes -= cnt; 5479 st_bp->buffer_bytes -= cnt;
5479 st_bp->read_pointer += cnt; 5480 st_bp->read_pointer += cnt;
5480 ubp += cnt; 5481 ubp += cnt;
5481 offset = 0; 5482 offset = 0;
5482 } 5483 }
5483 if (do_count) { /* Should never happen */ 5484 if (do_count) { /* Should never happen */
5484 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count); 5485 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5485 return (-EIO); 5486 return (-EIO);
5486 } 5487 }
5487 return 0; 5488 return 0;
5488 } 5489 }
5489 5490
5490 /* Sets the tail of the buffer after fill point to zero. 5491 /* Sets the tail of the buffer after fill point to zero.
5491 Returns zero (success) or negative error code. */ 5492 Returns zero (success) or negative error code. */
5492 static int osst_zero_buffer_tail(struct osst_buffer *st_bp) 5493 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
5493 { 5494 {
5494 int i, offset, do_count, cnt; 5495 int i, offset, do_count, cnt;
5495 5496
5496 for (i = 0, offset = st_bp->buffer_bytes; 5497 for (i = 0, offset = st_bp->buffer_bytes;
5497 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) 5498 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5498 offset -= st_bp->sg[i].length; 5499 offset -= st_bp->sg[i].length;
5499 if (i == st_bp->sg_segs) { /* Should never happen */ 5500 if (i == st_bp->sg_segs) { /* Should never happen */
5500 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n"); 5501 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5501 return (-EIO); 5502 return (-EIO);
5502 } 5503 }
5503 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes; 5504 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5504 i < st_bp->sg_segs && do_count > 0; i++) { 5505 i < st_bp->sg_segs && do_count > 0; i++) {
5505 cnt = st_bp->sg[i].length - offset < do_count ? 5506 cnt = st_bp->sg[i].length - offset < do_count ?
5506 st_bp->sg[i].length - offset : do_count ; 5507 st_bp->sg[i].length - offset : do_count ;
5507 memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt); 5508 memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
5508 do_count -= cnt; 5509 do_count -= cnt;
5509 offset = 0; 5510 offset = 0;
5510 } 5511 }
5511 if (do_count) { /* Should never happen */ 5512 if (do_count) { /* Should never happen */
5512 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count); 5513 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5513 return (-EIO); 5514 return (-EIO);
5514 } 5515 }
5515 return 0; 5516 return 0;
5516 } 5517 }
5517 5518
5518 /* Copy a osst 32K chunk of memory into the buffer. 5519 /* Copy a osst 32K chunk of memory into the buffer.
5519 Returns zero (success) or negative error code. */ 5520 Returns zero (success) or negative error code. */
5520 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr) 5521 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5521 { 5522 {
5522 int i, cnt, do_count = OS_DATA_SIZE; 5523 int i, cnt, do_count = OS_DATA_SIZE;
5523 5524
5524 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) { 5525 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5525 cnt = st_bp->sg[i].length < do_count ? 5526 cnt = st_bp->sg[i].length < do_count ?
5526 st_bp->sg[i].length : do_count ; 5527 st_bp->sg[i].length : do_count ;
5527 memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt); 5528 memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
5528 do_count -= cnt; 5529 do_count -= cnt;
5529 ptr += cnt; 5530 ptr += cnt;
5530 } 5531 }
5531 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */ 5532 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5532 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n", 5533 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5533 do_count, i); 5534 do_count, i);
5534 return (-EIO); 5535 return (-EIO);
5535 } 5536 }
5536 return 0; 5537 return 0;
5537 } 5538 }
5538 5539
5539 /* Copy a osst 32K chunk of memory from the buffer. 5540 /* Copy a osst 32K chunk of memory from the buffer.
5540 Returns zero (success) or negative error code. */ 5541 Returns zero (success) or negative error code. */
5541 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr) 5542 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5542 { 5543 {
5543 int i, cnt, do_count = OS_DATA_SIZE; 5544 int i, cnt, do_count = OS_DATA_SIZE;
5544 5545
5545 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) { 5546 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5546 cnt = st_bp->sg[i].length < do_count ? 5547 cnt = st_bp->sg[i].length < do_count ?
5547 st_bp->sg[i].length : do_count ; 5548 st_bp->sg[i].length : do_count ;
5548 memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt); 5549 memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
5549 do_count -= cnt; 5550 do_count -= cnt;
5550 ptr += cnt; 5551 ptr += cnt;
5551 } 5552 }
5552 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */ 5553 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5553 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n", 5554 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5554 do_count, i); 5555 do_count, i);
5555 return (-EIO); 5556 return (-EIO);
5556 } 5557 }
5557 return 0; 5558 return 0;
5558 } 5559 }
5559 5560
5560 5561
5561 /* Module housekeeping */ 5562 /* Module housekeeping */
5562 5563
5563 static void validate_options (void) 5564 static void validate_options (void)
5564 { 5565 {
5565 if (max_dev > 0) 5566 if (max_dev > 0)
5566 osst_max_dev = max_dev; 5567 osst_max_dev = max_dev;
5567 if (write_threshold_kbs > 0) 5568 if (write_threshold_kbs > 0)
5568 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE; 5569 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5569 if (osst_write_threshold > osst_buffer_size) 5570 if (osst_write_threshold > osst_buffer_size)
5570 osst_write_threshold = osst_buffer_size; 5571 osst_write_threshold = osst_buffer_size;
5571 if (max_sg_segs >= OSST_FIRST_SG) 5572 if (max_sg_segs >= OSST_FIRST_SG)
5572 osst_max_sg_segs = max_sg_segs; 5573 osst_max_sg_segs = max_sg_segs;
5573 #if DEBUG 5574 #if DEBUG
5574 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n", 5575 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5575 osst_max_dev, osst_write_threshold, osst_max_sg_segs); 5576 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5576 #endif 5577 #endif
5577 } 5578 }
5578 5579
5579 #ifndef MODULE 5580 #ifndef MODULE
5580 /* Set the boot options. Syntax: osst=xxx,yyy,... 5581 /* Set the boot options. Syntax: osst=xxx,yyy,...
5581 where xxx is write threshold in 1024 byte blocks, 5582 where xxx is write threshold in 1024 byte blocks,
5582 and yyy is number of s/g segments to use. */ 5583 and yyy is number of s/g segments to use. */
5583 static int __init osst_setup (char *str) 5584 static int __init osst_setup (char *str)
5584 { 5585 {
5585 int i, ints[5]; 5586 int i, ints[5];
5586 char *stp; 5587 char *stp;
5587 5588
5588 stp = get_options(str, ARRAY_SIZE(ints), ints); 5589 stp = get_options(str, ARRAY_SIZE(ints), ints);
5589 5590
5590 if (ints[0] > 0) { 5591 if (ints[0] > 0) {
5591 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++) 5592 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5592 *parms[i].val = ints[i + 1]; 5593 *parms[i].val = ints[i + 1];
5593 } else { 5594 } else {
5594 while (stp != NULL) { 5595 while (stp != NULL) {
5595 for (i = 0; i < ARRAY_SIZE(parms); i++) { 5596 for (i = 0; i < ARRAY_SIZE(parms); i++) {
5596 int len = strlen(parms[i].name); 5597 int len = strlen(parms[i].name);
5597 if (!strncmp(stp, parms[i].name, len) && 5598 if (!strncmp(stp, parms[i].name, len) &&
5598 (*(stp + len) == ':' || *(stp + len) == '=')) { 5599 (*(stp + len) == ':' || *(stp + len) == '=')) {
5599 *parms[i].val = 5600 *parms[i].val =
5600 simple_strtoul(stp + len + 1, NULL, 0); 5601 simple_strtoul(stp + len + 1, NULL, 0);
5601 break; 5602 break;
5602 } 5603 }
5603 } 5604 }
5604 if (i >= ARRAY_SIZE(parms)) 5605 if (i >= ARRAY_SIZE(parms))
5605 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n", 5606 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5606 stp); 5607 stp);
5607 stp = strchr(stp, ','); 5608 stp = strchr(stp, ',');
5608 if (stp) 5609 if (stp)
5609 stp++; 5610 stp++;
5610 } 5611 }
5611 } 5612 }
5612 5613
5613 return 1; 5614 return 1;
5614 } 5615 }
5615 5616
5616 __setup("osst=", osst_setup); 5617 __setup("osst=", osst_setup);
5617 5618
5618 #endif 5619 #endif
5619 5620
5620 static const struct file_operations osst_fops = { 5621 static const struct file_operations osst_fops = {
5621 .owner = THIS_MODULE, 5622 .owner = THIS_MODULE,
5622 .read = osst_read, 5623 .read = osst_read,
5623 .write = osst_write, 5624 .write = osst_write,
5624 .unlocked_ioctl = osst_ioctl, 5625 .unlocked_ioctl = osst_ioctl,
5625 #ifdef CONFIG_COMPAT 5626 #ifdef CONFIG_COMPAT
5626 .compat_ioctl = osst_compat_ioctl, 5627 .compat_ioctl = osst_compat_ioctl,
5627 #endif 5628 #endif
5628 .open = os_scsi_tape_open, 5629 .open = os_scsi_tape_open,
5629 .flush = os_scsi_tape_flush, 5630 .flush = os_scsi_tape_flush,
5630 .release = os_scsi_tape_close, 5631 .release = os_scsi_tape_close,
5631 .llseek = noop_llseek, 5632 .llseek = noop_llseek,
5632 }; 5633 };
5633 5634
5634 static int osst_supports(struct scsi_device * SDp) 5635 static int osst_supports(struct scsi_device * SDp)
5635 { 5636 {
5636 struct osst_support_data { 5637 struct osst_support_data {
5637 char *vendor; 5638 char *vendor;
5638 char *model; 5639 char *model;
5639 char *rev; 5640 char *rev;
5640 char *driver_hint; /* Name of the correct driver, NULL if unknown */ 5641 char *driver_hint; /* Name of the correct driver, NULL if unknown */
5641 }; 5642 };
5642 5643
5643 static struct osst_support_data support_list[] = { 5644 static struct osst_support_data support_list[] = {
5644 /* {"XXX", "Yy-", "", NULL}, example */ 5645 /* {"XXX", "Yy-", "", NULL}, example */
5645 SIGS_FROM_OSST, 5646 SIGS_FROM_OSST,
5646 {NULL, }}; 5647 {NULL, }};
5647 5648
5648 struct osst_support_data *rp; 5649 struct osst_support_data *rp;
5649 5650
5650 /* We are willing to drive OnStream SC-x0 as well as the 5651 /* We are willing to drive OnStream SC-x0 as well as the
5651 * * IDE, ParPort, FireWire, USB variants, if accessible by 5652 * * IDE, ParPort, FireWire, USB variants, if accessible by
5652 * * emulation layer (ide-scsi, usb-storage, ...) */ 5653 * * emulation layer (ide-scsi, usb-storage, ...) */
5653 5654
5654 for (rp=&(support_list[0]); rp->vendor != NULL; rp++) 5655 for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5655 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) && 5656 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5656 !strncmp(rp->model, SDp->model, strlen(rp->model)) && 5657 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5657 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) 5658 !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5658 return 1; 5659 return 1;
5659 return 0; 5660 return 0;
5660 } 5661 }
5661 5662
5662 /* 5663 /*
5663 * sysfs support for osst driver parameter information 5664 * sysfs support for osst driver parameter information
5664 */ 5665 */
5665 5666
5666 static ssize_t osst_version_show(struct device_driver *ddd, char *buf) 5667 static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
5667 { 5668 {
5668 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version); 5669 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
5669 } 5670 }
5670 5671
5671 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL); 5672 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
5672 5673
5673 static int osst_create_sysfs_files(struct device_driver *sysfs) 5674 static int osst_create_sysfs_files(struct device_driver *sysfs)
5674 { 5675 {
5675 return driver_create_file(sysfs, &driver_attr_version); 5676 return driver_create_file(sysfs, &driver_attr_version);
5676 } 5677 }
5677 5678
5678 static void osst_remove_sysfs_files(struct device_driver *sysfs) 5679 static void osst_remove_sysfs_files(struct device_driver *sysfs)
5679 { 5680 {
5680 driver_remove_file(sysfs, &driver_attr_version); 5681 driver_remove_file(sysfs, &driver_attr_version);
5681 } 5682 }
5682 5683
5683 /* 5684 /*
5684 * sysfs support for accessing ADR header information 5685 * sysfs support for accessing ADR header information
5685 */ 5686 */
5686 5687
5687 static ssize_t osst_adr_rev_show(struct device *dev, 5688 static ssize_t osst_adr_rev_show(struct device *dev,
5688 struct device_attribute *attr, char *buf) 5689 struct device_attribute *attr, char *buf)
5689 { 5690 {
5690 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5691 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5691 ssize_t l = 0; 5692 ssize_t l = 0;
5692 5693
5693 if (STp && STp->header_ok && STp->linux_media) 5694 if (STp && STp->header_ok && STp->linux_media)
5694 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev); 5695 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
5695 return l; 5696 return l;
5696 } 5697 }
5697 5698
5698 DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL); 5699 DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
5699 5700
5700 static ssize_t osst_linux_media_version_show(struct device *dev, 5701 static ssize_t osst_linux_media_version_show(struct device *dev,
5701 struct device_attribute *attr, 5702 struct device_attribute *attr,
5702 char *buf) 5703 char *buf)
5703 { 5704 {
5704 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5705 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5705 ssize_t l = 0; 5706 ssize_t l = 0;
5706 5707
5707 if (STp && STp->header_ok && STp->linux_media) 5708 if (STp && STp->header_ok && STp->linux_media)
5708 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version); 5709 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
5709 return l; 5710 return l;
5710 } 5711 }
5711 5712
5712 DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL); 5713 DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
5713 5714
5714 static ssize_t osst_capacity_show(struct device *dev, 5715 static ssize_t osst_capacity_show(struct device *dev,
5715 struct device_attribute *attr, char *buf) 5716 struct device_attribute *attr, char *buf)
5716 { 5717 {
5717 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5718 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5718 ssize_t l = 0; 5719 ssize_t l = 0;
5719 5720
5720 if (STp && STp->header_ok && STp->linux_media) 5721 if (STp && STp->header_ok && STp->linux_media)
5721 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity); 5722 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
5722 return l; 5723 return l;
5723 } 5724 }
5724 5725
5725 DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL); 5726 DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
5726 5727
5727 static ssize_t osst_first_data_ppos_show(struct device *dev, 5728 static ssize_t osst_first_data_ppos_show(struct device *dev,
5728 struct device_attribute *attr, 5729 struct device_attribute *attr,
5729 char *buf) 5730 char *buf)
5730 { 5731 {
5731 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5732 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5732 ssize_t l = 0; 5733 ssize_t l = 0;
5733 5734
5734 if (STp && STp->header_ok && STp->linux_media) 5735 if (STp && STp->header_ok && STp->linux_media)
5735 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos); 5736 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
5736 return l; 5737 return l;
5737 } 5738 }
5738 5739
5739 DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL); 5740 DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
5740 5741
5741 static ssize_t osst_eod_frame_ppos_show(struct device *dev, 5742 static ssize_t osst_eod_frame_ppos_show(struct device *dev,
5742 struct device_attribute *attr, 5743 struct device_attribute *attr,
5743 char *buf) 5744 char *buf)
5744 { 5745 {
5745 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5746 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5746 ssize_t l = 0; 5747 ssize_t l = 0;
5747 5748
5748 if (STp && STp->header_ok && STp->linux_media) 5749 if (STp && STp->header_ok && STp->linux_media)
5749 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos); 5750 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
5750 return l; 5751 return l;
5751 } 5752 }
5752 5753
5753 DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL); 5754 DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
5754 5755
5755 static ssize_t osst_filemark_cnt_show(struct device *dev, 5756 static ssize_t osst_filemark_cnt_show(struct device *dev,
5756 struct device_attribute *attr, char *buf) 5757 struct device_attribute *attr, char *buf)
5757 { 5758 {
5758 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev); 5759 struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5759 ssize_t l = 0; 5760 ssize_t l = 0;
5760 5761
5761 if (STp && STp->header_ok && STp->linux_media) 5762 if (STp && STp->header_ok && STp->linux_media)
5762 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt); 5763 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
5763 return l; 5764 return l;
5764 } 5765 }
5765 5766
5766 DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL); 5767 DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5767 5768
5768 static struct class *osst_sysfs_class; 5769 static struct class *osst_sysfs_class;
5769 5770
5770 static int osst_sysfs_init(void) 5771 static int osst_sysfs_init(void)
5771 { 5772 {
5772 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape"); 5773 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
5773 if (IS_ERR(osst_sysfs_class)) { 5774 if (IS_ERR(osst_sysfs_class)) {
5774 printk(KERN_ERR "osst :W: Unable to register sysfs class\n"); 5775 printk(KERN_ERR "osst :W: Unable to register sysfs class\n");
5775 return PTR_ERR(osst_sysfs_class); 5776 return PTR_ERR(osst_sysfs_class);
5776 } 5777 }
5777 5778
5778 return 0; 5779 return 0;
5779 } 5780 }
5780 5781
5781 static void osst_sysfs_destroy(dev_t dev) 5782 static void osst_sysfs_destroy(dev_t dev)
5782 { 5783 {
5783 device_destroy(osst_sysfs_class, dev); 5784 device_destroy(osst_sysfs_class, dev);
5784 } 5785 }
5785 5786
5786 static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name) 5787 static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5787 { 5788 {
5788 struct device *osst_member; 5789 struct device *osst_member;
5789 int err; 5790 int err;
5790 5791
5791 osst_member = device_create(osst_sysfs_class, device, dev, STp, 5792 osst_member = device_create(osst_sysfs_class, device, dev, STp,
5792 "%s", name); 5793 "%s", name);
5793 if (IS_ERR(osst_member)) { 5794 if (IS_ERR(osst_member)) {
5794 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); 5795 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5795 return PTR_ERR(osst_member); 5796 return PTR_ERR(osst_member);
5796 } 5797 }
5797 5798
5798 err = device_create_file(osst_member, &dev_attr_ADR_rev); 5799 err = device_create_file(osst_member, &dev_attr_ADR_rev);
5799 if (err) 5800 if (err)
5800 goto err_out; 5801 goto err_out;
5801 err = device_create_file(osst_member, &dev_attr_media_version); 5802 err = device_create_file(osst_member, &dev_attr_media_version);
5802 if (err) 5803 if (err)
5803 goto err_out; 5804 goto err_out;
5804 err = device_create_file(osst_member, &dev_attr_capacity); 5805 err = device_create_file(osst_member, &dev_attr_capacity);
5805 if (err) 5806 if (err)
5806 goto err_out; 5807 goto err_out;
5807 err = device_create_file(osst_member, &dev_attr_BOT_frame); 5808 err = device_create_file(osst_member, &dev_attr_BOT_frame);
5808 if (err) 5809 if (err)
5809 goto err_out; 5810 goto err_out;
5810 err = device_create_file(osst_member, &dev_attr_EOD_frame); 5811 err = device_create_file(osst_member, &dev_attr_EOD_frame);
5811 if (err) 5812 if (err)
5812 goto err_out; 5813 goto err_out;
5813 err = device_create_file(osst_member, &dev_attr_file_count); 5814 err = device_create_file(osst_member, &dev_attr_file_count);
5814 if (err) 5815 if (err)
5815 goto err_out; 5816 goto err_out;
5816 5817
5817 return 0; 5818 return 0;
5818 5819
5819 err_out: 5820 err_out:
5820 osst_sysfs_destroy(dev); 5821 osst_sysfs_destroy(dev);
5821 return err; 5822 return err;
5822 } 5823 }
5823 5824
5824 static void osst_sysfs_cleanup(void) 5825 static void osst_sysfs_cleanup(void)
5825 { 5826 {
5826 class_destroy(osst_sysfs_class); 5827 class_destroy(osst_sysfs_class);
5827 } 5828 }
5828 5829
5829 /* 5830 /*
5830 * osst startup / cleanup code 5831 * osst startup / cleanup code
5831 */ 5832 */
5832 5833
5833 static int osst_probe(struct device *dev) 5834 static int osst_probe(struct device *dev)
5834 { 5835 {
5835 struct scsi_device * SDp = to_scsi_device(dev); 5836 struct scsi_device * SDp = to_scsi_device(dev);
5836 struct osst_tape * tpnt; 5837 struct osst_tape * tpnt;
5837 struct st_modedef * STm; 5838 struct st_modedef * STm;
5838 struct st_partstat * STps; 5839 struct st_partstat * STps;
5839 struct osst_buffer * buffer; 5840 struct osst_buffer * buffer;
5840 struct gendisk * drive; 5841 struct gendisk * drive;
5841 int i, dev_num, err = -ENODEV; 5842 int i, dev_num, err = -ENODEV;
5842 5843
5843 if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) 5844 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5844 return -ENODEV; 5845 return -ENODEV;
5845 5846
5846 drive = alloc_disk(1); 5847 drive = alloc_disk(1);
5847 if (!drive) { 5848 if (!drive) {
5848 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n"); 5849 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5849 return -ENODEV; 5850 return -ENODEV;
5850 } 5851 }
5851 5852
5852 /* if this is the first attach, build the infrastructure */ 5853 /* if this is the first attach, build the infrastructure */
5853 write_lock(&os_scsi_tapes_lock); 5854 write_lock(&os_scsi_tapes_lock);
5854 if (os_scsi_tapes == NULL) { 5855 if (os_scsi_tapes == NULL) {
5855 os_scsi_tapes = kmalloc(osst_max_dev * sizeof(struct osst_tape *), GFP_ATOMIC); 5856 os_scsi_tapes = kmalloc(osst_max_dev * sizeof(struct osst_tape *), GFP_ATOMIC);
5856 if (os_scsi_tapes == NULL) { 5857 if (os_scsi_tapes == NULL) {
5857 write_unlock(&os_scsi_tapes_lock); 5858 write_unlock(&os_scsi_tapes_lock);
5858 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n"); 5859 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5859 goto out_put_disk; 5860 goto out_put_disk;
5860 } 5861 }
5861 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL; 5862 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5862 } 5863 }
5863 5864
5864 if (osst_nr_dev >= osst_max_dev) { 5865 if (osst_nr_dev >= osst_max_dev) {
5865 write_unlock(&os_scsi_tapes_lock); 5866 write_unlock(&os_scsi_tapes_lock);
5866 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev); 5867 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5867 goto out_put_disk; 5868 goto out_put_disk;
5868 } 5869 }
5869 5870
5870 /* find a free minor number */ 5871 /* find a free minor number */
5871 for (i = 0; i < osst_max_dev && os_scsi_tapes[i]; i++) 5872 for (i = 0; i < osst_max_dev && os_scsi_tapes[i]; i++)
5872 ; 5873 ;
5873 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)"); 5874 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5874 dev_num = i; 5875 dev_num = i;
5875 5876
5876 /* allocate a struct osst_tape for this device */ 5877 /* allocate a struct osst_tape for this device */
5877 tpnt = kzalloc(sizeof(struct osst_tape), GFP_ATOMIC); 5878 tpnt = kzalloc(sizeof(struct osst_tape), GFP_ATOMIC);
5878 if (!tpnt) { 5879 if (!tpnt) {
5879 write_unlock(&os_scsi_tapes_lock); 5880 write_unlock(&os_scsi_tapes_lock);
5880 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n"); 5881 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5881 goto out_put_disk; 5882 goto out_put_disk;
5882 } 5883 }
5883 5884
5884 /* allocate a buffer for this device */ 5885 /* allocate a buffer for this device */
5885 i = SDp->host->sg_tablesize; 5886 i = SDp->host->sg_tablesize;
5886 if (osst_max_sg_segs < i) 5887 if (osst_max_sg_segs < i)
5887 i = osst_max_sg_segs; 5888 i = osst_max_sg_segs;
5888 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i); 5889 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
5889 if (buffer == NULL) { 5890 if (buffer == NULL) {
5890 write_unlock(&os_scsi_tapes_lock); 5891 write_unlock(&os_scsi_tapes_lock);
5891 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n"); 5892 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5892 kfree(tpnt); 5893 kfree(tpnt);
5893 goto out_put_disk; 5894 goto out_put_disk;
5894 } 5895 }
5895 os_scsi_tapes[dev_num] = tpnt; 5896 os_scsi_tapes[dev_num] = tpnt;
5896 tpnt->buffer = buffer; 5897 tpnt->buffer = buffer;
5897 tpnt->device = SDp; 5898 tpnt->device = SDp;
5898 drive->private_data = &tpnt->driver; 5899 drive->private_data = &tpnt->driver;
5899 sprintf(drive->disk_name, "osst%d", dev_num); 5900 sprintf(drive->disk_name, "osst%d", dev_num);
5900 tpnt->driver = &osst_template; 5901 tpnt->driver = &osst_template;
5901 tpnt->drive = drive; 5902 tpnt->drive = drive;
5902 tpnt->in_use = 0; 5903 tpnt->in_use = 0;
5903 tpnt->capacity = 0xfffff; 5904 tpnt->capacity = 0xfffff;
5904 tpnt->dirty = 0; 5905 tpnt->dirty = 0;
5905 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */ 5906 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
5906 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma; 5907 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5907 tpnt->density = 0; 5908 tpnt->density = 0;
5908 tpnt->do_auto_lock = OSST_AUTO_LOCK; 5909 tpnt->do_auto_lock = OSST_AUTO_LOCK;
5909 tpnt->can_bsr = OSST_IN_FILE_POS; 5910 tpnt->can_bsr = OSST_IN_FILE_POS;
5910 tpnt->can_partitions = 0; 5911 tpnt->can_partitions = 0;
5911 tpnt->two_fm = OSST_TWO_FM; 5912 tpnt->two_fm = OSST_TWO_FM;
5912 tpnt->fast_mteom = OSST_FAST_MTEOM; 5913 tpnt->fast_mteom = OSST_FAST_MTEOM;
5913 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */ 5914 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5914 tpnt->write_threshold = osst_write_threshold; 5915 tpnt->write_threshold = osst_write_threshold;
5915 tpnt->default_drvbuffer = 0xff; /* No forced buffering */ 5916 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5916 tpnt->partition = 0; 5917 tpnt->partition = 0;
5917 tpnt->new_partition = 0; 5918 tpnt->new_partition = 0;
5918 tpnt->nbr_partitions = 0; 5919 tpnt->nbr_partitions = 0;
5919 tpnt->min_block = 512; 5920 tpnt->min_block = 512;
5920 tpnt->max_block = OS_DATA_SIZE; 5921 tpnt->max_block = OS_DATA_SIZE;
5921 tpnt->timeout = OSST_TIMEOUT; 5922 tpnt->timeout = OSST_TIMEOUT;
5922 tpnt->long_timeout = OSST_LONG_TIMEOUT; 5923 tpnt->long_timeout = OSST_LONG_TIMEOUT;
5923 5924
5924 /* Recognize OnStream tapes */ 5925 /* Recognize OnStream tapes */
5925 /* We don't need to test for OnStream, as this has been done in detect () */ 5926 /* We don't need to test for OnStream, as this has been done in detect () */
5926 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev); 5927 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5927 tpnt->omit_blklims = 1; 5928 tpnt->omit_blklims = 1;
5928 5929
5929 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || 5930 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5930 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp); 5931 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5931 tpnt->frame_in_buffer = 0; 5932 tpnt->frame_in_buffer = 0;
5932 tpnt->header_ok = 0; 5933 tpnt->header_ok = 0;
5933 tpnt->linux_media = 0; 5934 tpnt->linux_media = 0;
5934 tpnt->header_cache = NULL; 5935 tpnt->header_cache = NULL;
5935 5936
5936 for (i=0; i < ST_NBR_MODES; i++) { 5937 for (i=0; i < ST_NBR_MODES; i++) {
5937 STm = &(tpnt->modes[i]); 5938 STm = &(tpnt->modes[i]);
5938 STm->defined = 0; 5939 STm->defined = 0;
5939 STm->sysv = OSST_SYSV; 5940 STm->sysv = OSST_SYSV;
5940 STm->defaults_for_writes = 0; 5941 STm->defaults_for_writes = 0;
5941 STm->do_async_writes = OSST_ASYNC_WRITES; 5942 STm->do_async_writes = OSST_ASYNC_WRITES;
5942 STm->do_buffer_writes = OSST_BUFFER_WRITES; 5943 STm->do_buffer_writes = OSST_BUFFER_WRITES;
5943 STm->do_read_ahead = OSST_READ_AHEAD; 5944 STm->do_read_ahead = OSST_READ_AHEAD;
5944 STm->default_compression = ST_DONT_TOUCH; 5945 STm->default_compression = ST_DONT_TOUCH;
5945 STm->default_blksize = 512; 5946 STm->default_blksize = 512;
5946 STm->default_density = (-1); /* No forced density */ 5947 STm->default_density = (-1); /* No forced density */
5947 } 5948 }
5948 5949
5949 for (i=0; i < ST_NBR_PARTITIONS; i++) { 5950 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5950 STps = &(tpnt->ps[i]); 5951 STps = &(tpnt->ps[i]);
5951 STps->rw = ST_IDLE; 5952 STps->rw = ST_IDLE;
5952 STps->eof = ST_NOEOF; 5953 STps->eof = ST_NOEOF;
5953 STps->at_sm = 0; 5954 STps->at_sm = 0;
5954 STps->last_block_valid = 0; 5955 STps->last_block_valid = 0;
5955 STps->drv_block = (-1); 5956 STps->drv_block = (-1);
5956 STps->drv_file = (-1); 5957 STps->drv_file = (-1);
5957 } 5958 }
5958 5959
5959 tpnt->current_mode = 0; 5960 tpnt->current_mode = 0;
5960 tpnt->modes[0].defined = 1; 5961 tpnt->modes[0].defined = 1;
5961 tpnt->modes[2].defined = 1; 5962 tpnt->modes[2].defined = 1;
5962 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0; 5963 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
5963 5964
5964 mutex_init(&tpnt->lock); 5965 mutex_init(&tpnt->lock);
5965 osst_nr_dev++; 5966 osst_nr_dev++;
5966 write_unlock(&os_scsi_tapes_lock); 5967 write_unlock(&os_scsi_tapes_lock);
5967 5968
5968 { 5969 {
5969 char name[8]; 5970 char name[8];
5970 5971
5971 /* Rewind entry */ 5972 /* Rewind entry */
5972 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt)); 5973 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5973 if (err) 5974 if (err)
5974 goto out_free_buffer; 5975 goto out_free_buffer;
5975 5976
5976 /* No-rewind entry */ 5977 /* No-rewind entry */
5977 snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); 5978 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5978 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); 5979 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5979 if (err) 5980 if (err)
5980 goto out_free_sysfs1; 5981 goto out_free_sysfs1;
5981 } 5982 }
5982 5983
5983 sdev_printk(KERN_INFO, SDp, 5984 sdev_printk(KERN_INFO, SDp,
5984 "osst :I: Attached OnStream %.5s tape as %s\n", 5985 "osst :I: Attached OnStream %.5s tape as %s\n",
5985 SDp->model, tape_name(tpnt)); 5986 SDp->model, tape_name(tpnt));
5986 5987
5987 return 0; 5988 return 0;
5988 5989
5989 out_free_sysfs1: 5990 out_free_sysfs1:
5990 osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num)); 5991 osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num));
5991 out_free_buffer: 5992 out_free_buffer:
5992 kfree(buffer); 5993 kfree(buffer);
5993 out_put_disk: 5994 out_put_disk:
5994 put_disk(drive); 5995 put_disk(drive);
5995 return err; 5996 return err;
5996 }; 5997 };
5997 5998
5998 static int osst_remove(struct device *dev) 5999 static int osst_remove(struct device *dev)
5999 { 6000 {
6000 struct scsi_device * SDp = to_scsi_device(dev); 6001 struct scsi_device * SDp = to_scsi_device(dev);
6001 struct osst_tape * tpnt; 6002 struct osst_tape * tpnt;
6002 int i; 6003 int i;
6003 6004
6004 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0)) 6005 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
6005 return 0; 6006 return 0;
6006 6007
6007 write_lock(&os_scsi_tapes_lock); 6008 write_lock(&os_scsi_tapes_lock);
6008 for(i=0; i < osst_max_dev; i++) { 6009 for(i=0; i < osst_max_dev; i++) {
6009 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) { 6010 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
6010 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i)); 6011 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
6011 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128)); 6012 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
6012 tpnt->device = NULL; 6013 tpnt->device = NULL;
6013 put_disk(tpnt->drive); 6014 put_disk(tpnt->drive);
6014 os_scsi_tapes[i] = NULL; 6015 os_scsi_tapes[i] = NULL;
6015 osst_nr_dev--; 6016 osst_nr_dev--;
6016 write_unlock(&os_scsi_tapes_lock); 6017 write_unlock(&os_scsi_tapes_lock);
6017 vfree(tpnt->header_cache); 6018 vfree(tpnt->header_cache);
6018 if (tpnt->buffer) { 6019 if (tpnt->buffer) {
6019 normalize_buffer(tpnt->buffer); 6020 normalize_buffer(tpnt->buffer);
6020 kfree(tpnt->buffer); 6021 kfree(tpnt->buffer);
6021 } 6022 }
6022 kfree(tpnt); 6023 kfree(tpnt);
6023 return 0; 6024 return 0;
6024 } 6025 }
6025 } 6026 }
6026 write_unlock(&os_scsi_tapes_lock); 6027 write_unlock(&os_scsi_tapes_lock);
6027 return 0; 6028 return 0;
6028 } 6029 }
6029 6030
6030 static int __init init_osst(void) 6031 static int __init init_osst(void)
6031 { 6032 {
6032 int err; 6033 int err;
6033 6034
6034 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid); 6035 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
6035 6036
6036 validate_options(); 6037 validate_options();
6037 6038
6038 err = osst_sysfs_init(); 6039 err = osst_sysfs_init();
6039 if (err) 6040 if (err)
6040 return err; 6041 return err;
6041 6042
6042 err = register_chrdev(OSST_MAJOR, "osst", &osst_fops); 6043 err = register_chrdev(OSST_MAJOR, "osst", &osst_fops);
6043 if (err < 0) { 6044 if (err < 0) {
6044 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR); 6045 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
6045 goto err_out; 6046 goto err_out;
6046 } 6047 }
6047 6048
6048 err = scsi_register_driver(&osst_template.gendrv); 6049 err = scsi_register_driver(&osst_template.gendrv);
6049 if (err) 6050 if (err)
6050 goto err_out_chrdev; 6051 goto err_out_chrdev;
6051 6052
6052 err = osst_create_sysfs_files(&osst_template.gendrv); 6053 err = osst_create_sysfs_files(&osst_template.gendrv);
6053 if (err) 6054 if (err)
6054 goto err_out_scsidrv; 6055 goto err_out_scsidrv;
6055 6056
6056 return 0; 6057 return 0;
6057 6058
6058 err_out_scsidrv: 6059 err_out_scsidrv:
6059 scsi_unregister_driver(&osst_template.gendrv); 6060 scsi_unregister_driver(&osst_template.gendrv);
6060 err_out_chrdev: 6061 err_out_chrdev:
6061 unregister_chrdev(OSST_MAJOR, "osst"); 6062 unregister_chrdev(OSST_MAJOR, "osst");
6062 err_out: 6063 err_out:
6063 osst_sysfs_cleanup(); 6064 osst_sysfs_cleanup();
6064 return err; 6065 return err;
6065 } 6066 }
6066 6067
6067 static void __exit exit_osst (void) 6068 static void __exit exit_osst (void)
6068 { 6069 {
6069 int i; 6070 int i;
6070 struct osst_tape * STp; 6071 struct osst_tape * STp;
6071 6072
6072 osst_remove_sysfs_files(&osst_template.gendrv); 6073 osst_remove_sysfs_files(&osst_template.gendrv);
6073 scsi_unregister_driver(&osst_template.gendrv); 6074 scsi_unregister_driver(&osst_template.gendrv);
6074 unregister_chrdev(OSST_MAJOR, "osst"); 6075 unregister_chrdev(OSST_MAJOR, "osst");
6075 osst_sysfs_cleanup(); 6076 osst_sysfs_cleanup();
6076 6077
6077 if (os_scsi_tapes) { 6078 if (os_scsi_tapes) {
6078 for (i=0; i < osst_max_dev; ++i) { 6079 for (i=0; i < osst_max_dev; ++i) {
6079 if (!(STp = os_scsi_tapes[i])) continue; 6080 if (!(STp = os_scsi_tapes[i])) continue;
6080 /* This is defensive, supposed to happen during detach */ 6081 /* This is defensive, supposed to happen during detach */
6081 vfree(STp->header_cache); 6082 vfree(STp->header_cache);
6082 if (STp->buffer) { 6083 if (STp->buffer) {
6083 normalize_buffer(STp->buffer); 6084 normalize_buffer(STp->buffer);
6084 kfree(STp->buffer); 6085 kfree(STp->buffer);
6085 } 6086 }
6086 put_disk(STp->drive); 6087 put_disk(STp->drive);
6087 kfree(STp); 6088 kfree(STp);
6088 } 6089 }
6089 kfree(os_scsi_tapes); 6090 kfree(os_scsi_tapes);
6090 } 6091 }
6091 printk(KERN_INFO "osst :I: Unloaded.\n"); 6092 printk(KERN_INFO "osst :I: Unloaded.\n");
6092 } 6093 }
6093 6094
6094 module_init(init_osst); 6095 module_init(init_osst);
6095 module_exit(exit_osst); 6096 module_exit(exit_osst);