1 /*
2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
3 file Documentation/scsi/st.txt for more information.
4
5 History:
6
7 OnStream SCSI Tape support (osst) cloned from st.c by
8 Willem Riede (osst@riede.org) Feb 2000
9 Fixes ... Kurt Garloff <garloff@suse.de> Mar 2000
10
11 Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
12 Contribution and ideas from several people including (in alphabetical
13 order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
14 Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
15
16 Copyright 1992 - 2002 Kai Makisara / 2000 - 2004 Willem Riede
17 email osst@riede.org
18
19 $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
20
21 Microscopic alterations - Rik Ling, 2000/12/21
22 Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
23 Some small formal changes - aeb, 950809
24 */
25
26 static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $";
27 const char * osst_version = "0.99.3";
28
29 /* The "failure to reconnect" firmware bug */
30 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
31 #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/
32 #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
33
34 #include <linux/module.h>
35
36 #include <linux/fs.h>
37 #include <linux/kernel.h>
38 #include <linux/sched.h>
39 #include <linux/proc_fs.h>
40 #include <linux/mm.h>
41 #include <linux/init.h>
42 #include <linux/string.h>
43 #include <linux/errno.h>
44 #include <linux/mtio.h>
45 #include <linux/ioctl.h>
46 #include <linux/fcntl.h>
47 #include <linux/spinlock.h>
48 #include <linux/vmalloc.h>
49 #include <linux/blkdev.h>
50 #include <linux/moduleparam.h>
51 #include <linux/devfs_fs_kernel.h>
52 #include <linux/delay.h>
53 #include <asm/uaccess.h>
54 #include <asm/dma.h>
55 #include <asm/system.h>
56
57 /* The driver prints some debugging information on the console if DEBUG
58 is defined and non-zero. */
59 #define DEBUG 0
60
61 /* The message level for the debug messages is currently set to KERN_NOTICE
62 so that people can easily see the messages. Later when the debugging messages
63 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
64 #define OSST_DEB_MSG KERN_NOTICE
65
66 #include <scsi/scsi.h>
67 #include <scsi/scsi_dbg.h>
68 #include <scsi/scsi_device.h>
69 #include <scsi/scsi_driver.h>
70 #include <scsi/scsi_eh.h>
71 #include <scsi/scsi_host.h>
72 #include <scsi/scsi_ioctl.h>
73 #include <scsi/scsi_request.h>
74
75 #define ST_KILOBYTE 1024
76
77 #include "st.h"
78 #include "osst.h"
79 #include "osst_options.h"
80 #include "osst_detect.h"
81
82 static int max_dev = 0;
83 static int write_threshold_kbs = 0;
84 static int max_sg_segs = 0;
85
86 #ifdef MODULE
87 MODULE_AUTHOR("Willem Riede");
88 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
89 MODULE_LICENSE("GPL");
90
91 module_param(max_dev, int, 0444);
92 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
93
94 module_param(write_threshold_kbs, int, 0644);
95 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
96
97 module_param(max_sg_segs, int, 0644);
98 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
99 #else
100 static struct osst_dev_parm {
101 char *name;
102 int *val;
103 } parms[] __initdata = {
104 { "max_dev", &max_dev },
105 { "write_threshold_kbs", &write_threshold_kbs },
106 { "max_sg_segs", &max_sg_segs }
107 };
108 #endif
109
110 static char *osst_formats[ST_NBR_MODES] ={"", "l", "m", "a"};
111
112 /* Some default definitions have been moved to osst_options.h */
113 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
114 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
115
116 /* The buffer size should fit into the 24 bits for length in the
117 6-byte SCSI read and write commands. */
118 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
119 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
120 #endif
121
122 #if DEBUG
123 static int debugging = 1;
124 /* uncomment define below to test error recovery */
125 // #define OSST_INJECT_ERRORS 1
126 #endif
127
128 /* Do not retry! The drive firmware already retries when appropriate,
129 and when it tries to tell us something, we had better listen... */
130 #define MAX_RETRIES 0
131
132 #define NO_TAPE NOT_READY
133
134 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
135 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
136 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
137
138 #define OSST_TIMEOUT (200 * HZ)
139 #define OSST_LONG_TIMEOUT (1800 * HZ)
140
141 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
142 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
143 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
144 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
145
146 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
147 24 bits) */
148 #define SET_DENS_AND_BLK 0x10001
149
150 static int osst_buffer_size = OSST_BUFFER_SIZE;
151 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
152 static int osst_max_sg_segs = OSST_MAX_SG;
153 static int osst_max_dev = OSST_MAX_TAPES;
154 static int osst_nr_dev;
155
156 static struct osst_tape **os_scsi_tapes = NULL;
157 static DEFINE_RWLOCK(os_scsi_tapes_lock);
158
159 static int modes_defined = 0;
160
161 static struct osst_buffer *new_tape_buffer(int, int, int);
162 static int enlarge_buffer(struct osst_buffer *, int);
163 static void normalize_buffer(struct osst_buffer *);
164 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
165 static int from_buffer(struct osst_buffer *, char __user *, int);
166 static int osst_zero_buffer_tail(struct osst_buffer *);
167 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
168 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
169
170 static int osst_probe(struct device *);
171 static int osst_remove(struct device *);
172
173 struct scsi_driver osst_template = {
174 .owner = THIS_MODULE,
175 .gendrv = {
176 .name = "osst",
177 .probe = osst_probe,
178 .remove = osst_remove,
179 }
180 };
181
182 static int osst_int_ioctl(struct osst_tape *STp, struct scsi_request ** aSRpnt,
183 unsigned int cmd_in, unsigned long arg);
184
185 static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int frame, int skip);
186
187 static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt);
188
189 static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt);
190
191 static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending);
192
193 static inline char *tape_name(struct osst_tape *tape)
194 {
195 return tape->drive->disk_name;
196 }
197
198 /* Routines that handle the interaction with mid-layer SCSI routines */
199
200 /* Convert the result to success code */
201 static int osst_chk_result(struct osst_tape * STp, struct scsi_request * SRpnt)
202 {
203 char *name = tape_name(STp);
204 int result = SRpnt->sr_result;
205 unsigned char * sense = SRpnt->sr_sense_buffer, scode;
206 #if DEBUG
207 const char *stp;
208 #endif
209
210 if (!result) {
211 sense[0] = 0; /* We don't have sense data if this byte is zero */
212 return 0;
213 }
214 if ((driver_byte(result) & DRIVER_MASK) == DRIVER_SENSE)
215 scode = sense[2] & 0x0f;
216 else {
217 sense[0] = 0; /* We don't have sense data if this byte is zero */
218 scode = 0;
219 }
220 #if DEBUG
221 if (debugging) {
222 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
223 name, result,
224 SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
225 SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
226 SRpnt->sr_bufflen);
227 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
228 name, scode, sense[12], sense[13]);
229 if (driver_byte(result) & DRIVER_SENSE)
230 scsi_print_req_sense("osst ", SRpnt);
231 }
232 else
233 #endif
234 if (!(driver_byte(result) & DRIVER_SENSE) ||
235 ((sense[0] & 0x70) == 0x70 &&
236 scode != NO_SENSE &&
237 scode != RECOVERED_ERROR &&
238 /* scode != UNIT_ATTENTION && */
239 scode != BLANK_CHECK &&
240 scode != VOLUME_OVERFLOW &&
241 SRpnt->sr_cmnd[0] != MODE_SENSE &&
242 SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
243 if (driver_byte(result) & DRIVER_SENSE) {
244 printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
245 scsi_print_req_sense("osst:", SRpnt);
246 }
247 else {
248 static int notyetprinted = 1;
249
250 printk(KERN_WARNING
251 "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
252 name, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
253 host_byte(result));
254 if (notyetprinted) {
255 notyetprinted = 0;
256 printk(KERN_INFO
257 "%s:I: This warning may be caused by your scsi controller,\n", name);
258 printk(KERN_INFO
259 "%s:I: it has been reported with some Buslogic cards.\n", name);
260 }
261 }
262 }
263 STp->pos_unknown |= STp->device->was_reset;
264
265 if ((sense[0] & 0x70) == 0x70 &&
266 scode == RECOVERED_ERROR) {
267 STp->recover_count++;
268 STp->recover_erreg++;
269 #if DEBUG
270 if (debugging) {
271 if (SRpnt->sr_cmnd[0] == READ_6)
272 stp = "read";
273 else if (SRpnt->sr_cmnd[0] == WRITE_6)
274 stp = "write";
275 else
276 stp = "ioctl";
277 printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
278 STp->recover_count);
279 }
280 #endif
281 if ((sense[2] & 0xe0) == 0)
282 return 0;
283 }
284 return (-EIO);
285 }
286
287
288 /* Wakeup from interrupt */
289 static void osst_sleep_done (struct scsi_cmnd * SCpnt)
290 {
291 struct osst_tape * STp = container_of(SCpnt->request->rq_disk->private_data, struct osst_tape, driver);
292
293 if ((STp->buffer)->writing &&
294 (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
295 (SCpnt->sense_buffer[2] & 0x40)) {
296 /* EOM at write-behind, has all been written? */
297 if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
298 STp->buffer->midlevel_result = SCpnt->result; /* Error */
299 else
300 STp->buffer->midlevel_result = INT_MAX; /* OK */
301 }
302 else
303 STp->buffer->midlevel_result = SCpnt->result;
304 SCpnt->request->rq_status = RQ_SCSI_DONE;
305 STp->buffer->last_SRpnt = SCpnt->sc_request;
306
307 #if DEBUG
308 STp->write_pending = 0;
309 #endif
310 complete(SCpnt->request->waiting);
311 }
312
313
314 /* Do the scsi command. Waits until command performed if do_wait is true.
315 Otherwise osst_write_behind_check() is used to check that the command
316 has finished. */
317 static struct scsi_request * osst_do_scsi(struct scsi_request *SRpnt, struct osst_tape *STp,
318 unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
319 {
320 unsigned char *bp;
321 #ifdef OSST_INJECT_ERRORS
322 static int inject = 0;
323 static int repeat = 0;
324 #endif
325 if (SRpnt == NULL) {
326 if ((SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC)) == NULL) {
327 printk(KERN_ERR "%s:E: Can't get SCSI request.\n", tape_name(STp));
328 if (signal_pending(current))
329 (STp->buffer)->syscall_result = (-EINTR);
330 else
331 (STp->buffer)->syscall_result = (-EBUSY);
332 return NULL;
333 }
334 }
335
336 init_completion(&STp->wait);
337 SRpnt->sr_use_sg = (bytes > (STp->buffer)->sg[0].length) ?
338 (STp->buffer)->use_sg : 0;
339 if (SRpnt->sr_use_sg) {
340 bp = (char *)&(STp->buffer->sg[0]);
341 if (STp->buffer->sg_segs < SRpnt->sr_use_sg)
342 SRpnt->sr_use_sg = STp->buffer->sg_segs;
343 }
344 else
345 bp = (STp->buffer)->b_data;
346 SRpnt->sr_data_direction = direction;
347 SRpnt->sr_cmd_len = 0;
348 SRpnt->sr_request->waiting = &(STp->wait);
349 SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
350 SRpnt->sr_request->rq_disk = STp->drive;
351
352 scsi_do_req(SRpnt, (void *)cmd, bp, bytes, osst_sleep_done, timeout, retries);
353
354 if (do_wait) {
355 wait_for_completion(SRpnt->sr_request->waiting);
356 SRpnt->sr_request->waiting = NULL;
357 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
358 #ifdef OSST_INJECT_ERRORS
359 if (STp->buffer->syscall_result == 0 &&
360 cmd[0] == READ_6 &&
361 cmd[4] &&
362 ( (++ inject % 83) == 29 ||
363 (STp->first_frame_position == 240
364 /* or STp->read_error_frame to fail again on the block calculated above */ &&
365 ++repeat < 3))) {
366 printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
367 STp->buffer->last_result_fatal = 1;
368 }
369 #endif
370 }
371 return SRpnt;
372 }
373
374
375 /* Handle the write-behind checking (downs the semaphore) */
376 static void osst_write_behind_check(struct osst_tape *STp)
377 {
378 struct osst_buffer * STbuffer;
379
380 STbuffer = STp->buffer;
381
382 #if DEBUG
383 if (STp->write_pending)
384 STp->nbr_waits++;
385 else
386 STp->nbr_finished++;
387 #endif
388 wait_for_completion(&(STp->wait));
389 (STp->buffer)->last_SRpnt->sr_request->waiting = NULL;
390
391 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
392
393 if ((STp->buffer)->syscall_result)
394 (STp->buffer)->syscall_result =
395 osst_write_error_recovery(STp, &((STp->buffer)->last_SRpnt), 1);
396 else
397 STp->first_frame_position++;
398
399 scsi_release_request((STp->buffer)->last_SRpnt);
400
401 if (STbuffer->writing < STbuffer->buffer_bytes)
402 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
403
404 STbuffer->buffer_bytes -= STbuffer->writing;
405 STbuffer->writing = 0;
406
407 return;
408 }
409
410
411
412 /* Onstream specific Routines */
413 /*
414 * Initialize the OnStream AUX
415 */
416 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
417 int logical_blk_num, int blk_sz, int blk_cnt)
418 {
419 os_aux_t *aux = STp->buffer->aux;
420 os_partition_t *par = &aux->partition;
421 os_dat_t *dat = &aux->dat;
422
423 if (STp->raw) return;
424
425 memset(aux, 0, sizeof(*aux));
426 aux->format_id = htonl(0);
427 memcpy(aux->application_sig, "LIN4", 4);
428 aux->hdwr = htonl(0);
429 aux->frame_type = frame_type;
430
431 switch (frame_type) {
432 case OS_FRAME_TYPE_HEADER:
433 aux->update_frame_cntr = htonl(STp->update_frame_cntr);
434 par->partition_num = OS_CONFIG_PARTITION;
435 par->par_desc_ver = OS_PARTITION_VERSION;
436 par->wrt_pass_cntr = htons(0xffff);
437 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
438 par->first_frame_ppos = htonl(0);
439 par->last_frame_ppos = htonl(0xbb7);
440 aux->frame_seq_num = htonl(0);
441 aux->logical_blk_num_high = htonl(0);
442 aux->logical_blk_num = htonl(0);
443 aux->next_mark_ppos = htonl(STp->first_mark_ppos);
444 break;
445 case OS_FRAME_TYPE_DATA:
446 case OS_FRAME_TYPE_MARKER:
447 dat->dat_sz = 8;
448 dat->reserved1 = 0;
449 dat->entry_cnt = 1;
450 dat->reserved3 = 0;
451 dat->dat_list[0].blk_sz = htonl(blk_sz);
452 dat->dat_list[0].blk_cnt = htons(blk_cnt);
453 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
454 OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
455 dat->dat_list[0].reserved = 0;
456 case OS_FRAME_TYPE_EOD:
457 aux->update_frame_cntr = htonl(0);
458 par->partition_num = OS_DATA_PARTITION;
459 par->par_desc_ver = OS_PARTITION_VERSION;
460 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
461 par->first_frame_ppos = htonl(STp->first_data_ppos);
462 par->last_frame_ppos = htonl(STp->capacity);
463 aux->frame_seq_num = htonl(frame_seq_number);
464 aux->logical_blk_num_high = htonl(0);
465 aux->logical_blk_num = htonl(logical_blk_num);
466 break;
467 default: ; /* probably FILL */
468 }
469 aux->filemark_cnt = ntohl(STp->filemark_cnt);
470 aux->phys_fm = ntohl(0xffffffff);
471 aux->last_mark_ppos = ntohl(STp->last_mark_ppos);
472 aux->last_mark_lbn = ntohl(STp->last_mark_lbn);
473 }
474
475 /*
476 * Verify that we have the correct tape frame
477 */
478 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
479 {
480 char * name = tape_name(STp);
481 os_aux_t * aux = STp->buffer->aux;
482 os_partition_t * par = &(aux->partition);
483 struct st_partstat * STps = &(STp->ps[STp->partition]);
484 int blk_cnt, blk_sz, i;
485
486 if (STp->raw) {
487 if (STp->buffer->syscall_result) {
488 for (i=0; i < STp->buffer->sg_segs; i++)
489 memset(page_address(STp->buffer->sg[i].page),
490 0, STp->buffer->sg[i].length);
491 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
492 } else
493 STp->buffer->buffer_bytes = OS_FRAME_SIZE;
494 return 1;
495 }
496 if (STp->buffer->syscall_result) {
497 #if DEBUG
498 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
499 #endif
500 return 0;
501 }
502 if (ntohl(aux->format_id) != 0) {
503 #if DEBUG
504 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
505 #endif
506 goto err_out;
507 }
508 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
509 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
510 #if DEBUG
511 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
512 #endif
513 goto err_out;
514 }
515 if (par->partition_num != OS_DATA_PARTITION) {
516 if (!STp->linux_media || STp->linux_media_version != 2) {
517 #if DEBUG
518 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
519 name, par->partition_num);
520 #endif
521 goto err_out;
522 }
523 }
524 if (par->par_desc_ver != OS_PARTITION_VERSION) {
525 #if DEBUG
526 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
527 #endif
528 goto err_out;
529 }
530 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
531 #if DEBUG
532 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
533 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
534 #endif
535 goto err_out;
536 }
537 if (aux->frame_type != OS_FRAME_TYPE_DATA &&
538 aux->frame_type != OS_FRAME_TYPE_EOD &&
539 aux->frame_type != OS_FRAME_TYPE_MARKER) {
540 if (!quiet)
541 #if DEBUG
542 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
543 #endif
544 goto err_out;
545 }
546 if (aux->frame_type == OS_FRAME_TYPE_EOD &&
547 STp->first_frame_position < STp->eod_frame_ppos) {
548 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
549 STp->first_frame_position);
550 goto err_out;
551 }
552 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
553 if (!quiet)
554 #if DEBUG
555 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
556 name, ntohl(aux->frame_seq_num), frame_seq_number);
557 #endif
558 goto err_out;
559 }
560 if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
561 STps->eof = ST_FM_HIT;
562
563 i = ntohl(aux->filemark_cnt);
564 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
565 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
566 #if DEBUG
567 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
568 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
569 i, STp->first_frame_position - 1);
570 #endif
571 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
572 if (i >= STp->filemark_cnt)
573 STp->filemark_cnt = i+1;
574 }
575 }
576 if (aux->frame_type == OS_FRAME_TYPE_EOD) {
577 STps->eof = ST_EOD_1;
578 STp->frame_in_buffer = 1;
579 }
580 if (aux->frame_type == OS_FRAME_TYPE_DATA) {
581 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
582 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
583 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
584 STp->buffer->read_pointer = 0;
585 STp->frame_in_buffer = 1;
586
587 /* See what block size was used to write file */
588 if (STp->block_size != blk_sz && blk_sz > 0) {
589 printk(KERN_INFO
590 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
591 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
592 STp->block_size<1024?STp->block_size:STp->block_size/1024,
593 STp->block_size<1024?'b':'k');
594 STp->block_size = blk_sz;
595 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
596 }
597 STps->eof = ST_NOEOF;
598 }
599 STp->frame_seq_number = ntohl(aux->frame_seq_num);
600 STp->logical_blk_num = ntohl(aux->logical_blk_num);
601 return 1;
602
603 err_out:
604 if (STp->read_error_frame == 0)
605 STp->read_error_frame = STp->first_frame_position - 1;
606 return 0;
607 }
608
609 /*
610 * Wait for the unit to become Ready
611 */
612 static int osst_wait_ready(struct osst_tape * STp, struct scsi_request ** aSRpnt,
613 unsigned timeout, int initial_delay)
614 {
615 unsigned char cmd[MAX_COMMAND_SIZE];
616 struct scsi_request * SRpnt;
617 unsigned long startwait = jiffies;
618 #if DEBUG
619 int dbg = debugging;
620 char * name = tape_name(STp);
621
622 printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
623 #endif
624
625 if (initial_delay > 0)
626 msleep(jiffies_to_msecs(initial_delay));
627
628 memset(cmd, 0, MAX_COMMAND_SIZE);
629 cmd[0] = TEST_UNIT_READY;
630
631 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
632 *aSRpnt = SRpnt;
633 if (!SRpnt) return (-EBUSY);
634
635 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
636 (( SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
637 (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8) ) ||
638 ( SRpnt->sr_sense_buffer[2] == 6 && SRpnt->sr_sense_buffer[12] == 0x28 &&
639 SRpnt->sr_sense_buffer[13] == 0 ) )) {
640 #if DEBUG
641 if (debugging) {
642 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
643 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
644 debugging = 0;
645 }
646 #endif
647 msleep(100);
648
649 memset(cmd, 0, MAX_COMMAND_SIZE);
650 cmd[0] = TEST_UNIT_READY;
651
652 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
653 }
654 *aSRpnt = SRpnt;
655 #if DEBUG
656 debugging = dbg;
657 #endif
658 if ( STp->buffer->syscall_result &&
659 osst_write_error_recovery(STp, aSRpnt, 0) ) {
660 #if DEBUG
661 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
662 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
663 STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
664 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
665 #endif
666 return (-EIO);
667 }
668 #if DEBUG
669 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
670 #endif
671 return 0;
672 }
673
674 /*
675 * Wait for a tape to be inserted in the unit
676 */
677 static int osst_wait_for_medium(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned timeout)
678 {
679 unsigned char cmd[MAX_COMMAND_SIZE];
680 struct scsi_request * SRpnt;
681 unsigned long startwait = jiffies;
682 #if DEBUG
683 int dbg = debugging;
684 char * name = tape_name(STp);
685
686 printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
687 #endif
688
689 memset(cmd, 0, MAX_COMMAND_SIZE);
690 cmd[0] = TEST_UNIT_READY;
691
692 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
693 *aSRpnt = SRpnt;
694 if (!SRpnt) return (-EBUSY);
695
696 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
697 SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 0x3a &&
698 SRpnt->sr_sense_buffer[13] == 0 ) {
699 #if DEBUG
700 if (debugging) {
701 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
702 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
703 debugging = 0;
704 }
705 #endif
706 msleep(100);
707
708 memset(cmd, 0, MAX_COMMAND_SIZE);
709 cmd[0] = TEST_UNIT_READY;
710
711 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
712 }
713 *aSRpnt = SRpnt;
714 #if DEBUG
715 debugging = dbg;
716 #endif
717 if ( STp->buffer->syscall_result && SRpnt->sr_sense_buffer[2] != 2 &&
718 SRpnt->sr_sense_buffer[12] != 4 && SRpnt->sr_sense_buffer[13] == 1) {
719 #if DEBUG
720 printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
721 printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
722 STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
723 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
724 #endif
725 return 0;
726 }
727 #if DEBUG
728 printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
729 #endif
730 return 1;
731 }
732
733 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct scsi_request ** aSRpnt, int frame)
734 {
735 int retval;
736
737 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
738 retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
739 if (retval) return (retval);
740 osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
741 return (osst_get_frame_position(STp, aSRpnt));
742 }
743
744 /*
745 * Wait for write(s) to complete
746 */
747 static int osst_flush_drive_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt)
748 {
749 unsigned char cmd[MAX_COMMAND_SIZE];
750 struct scsi_request * SRpnt;
751 int result = 0;
752 int delay = OSST_WAIT_WRITE_COMPLETE;
753 #if DEBUG
754 char * name = tape_name(STp);
755
756 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
757 #endif
758
759 memset(cmd, 0, MAX_COMMAND_SIZE);
760 cmd[0] = WRITE_FILEMARKS;
761 cmd[1] = 1;
762
763 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
764 *aSRpnt = SRpnt;
765 if (!SRpnt) return (-EBUSY);
766 if (STp->buffer->syscall_result) {
767 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == 2 && SRpnt->sr_sense_buffer[12] == 4) {
768 if (SRpnt->sr_sense_buffer[13] == 8) {
769 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
770 }
771 } else
772 result = osst_write_error_recovery(STp, aSRpnt, 0);
773 }
774 result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
775 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
776
777 return (result);
778 }
779
780 #define OSST_POLL_PER_SEC 10
781 static int osst_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int curr, int minlast, int to)
782 {
783 unsigned long startwait = jiffies;
784 char * name = tape_name(STp);
785 #if DEBUG
786 char notyetprinted = 1;
787 #endif
788 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
789 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
790
791 while (time_before (jiffies, startwait + to*HZ))
792 {
793 int result;
794 result = osst_get_frame_position(STp, aSRpnt);
795 if (result == -EIO)
796 if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
797 return 0; /* successful recovery leaves drive ready for frame */
798 if (result < 0) break;
799 if (STp->first_frame_position == curr &&
800 ((minlast < 0 &&
801 (signed)STp->last_frame_position > (signed)curr + minlast) ||
802 (minlast >= 0 && STp->cur_frames > minlast)
803 ) && result >= 0)
804 {
805 #if DEBUG
806 if (debugging || jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC)
807 printk (OSST_DEB_MSG
808 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
809 name, curr, curr+minlast, STp->first_frame_position,
810 STp->last_frame_position, STp->cur_frames,
811 result, (jiffies-startwait)/HZ,
812 (((jiffies-startwait)%HZ)*10)/HZ);
813 #endif
814 return 0;
815 }
816 #if DEBUG
817 if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted)
818 {
819 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
820 name, curr, curr+minlast, STp->first_frame_position,
821 STp->last_frame_position, STp->cur_frames, result);
822 notyetprinted--;
823 }
824 #endif
825 msleep(1000 / OSST_POLL_PER_SEC);
826 }
827 #if DEBUG
828 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
829 name, curr, curr+minlast, STp->first_frame_position,
830 STp->last_frame_position, STp->cur_frames,
831 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
832 #endif
833 return -EBUSY;
834 }
835
836 static int osst_recover_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int writing)
837 {
838 struct scsi_request * SRpnt;
839 unsigned char cmd[MAX_COMMAND_SIZE];
840 unsigned long startwait = jiffies;
841 int retval = 1;
842 char * name = tape_name(STp);
843
844 if (writing) {
845 char mybuf[24];
846 char * olddata = STp->buffer->b_data;
847 int oldsize = STp->buffer->buffer_size;
848
849 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
850
851 memset(cmd, 0, MAX_COMMAND_SIZE);
852 cmd[0] = WRITE_FILEMARKS;
853 cmd[1] = 1;
854 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
855 MAX_RETRIES, 1);
856
857 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
858
859 if (STp->buffer->syscall_result && (SRpnt->sr_sense_buffer[2] & 0x0f) != 2) {
860
861 /* some failure - not just not-ready */
862 retval = osst_write_error_recovery(STp, aSRpnt, 0);
863 break;
864 }
865 set_current_state(TASK_INTERRUPTIBLE);
866 schedule_timeout (HZ / OSST_POLL_PER_SEC);
867
868 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
869 memset(cmd, 0, MAX_COMMAND_SIZE);
870 cmd[0] = READ_POSITION;
871
872 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
873 MAX_RETRIES, 1);
874
875 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
876 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
877 }
878 if (retval)
879 printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
880 } else
881 /* TODO - figure out which error conditions can be handled */
882 if (STp->buffer->syscall_result)
883 printk(KERN_WARNING
884 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
885 (*aSRpnt)->sr_sense_buffer[ 2] & 0x0f,
886 (*aSRpnt)->sr_sense_buffer[12],
887 (*aSRpnt)->sr_sense_buffer[13]);
888
889 return retval;
890 }
891
892 /*
893 * Read the next OnStream tape frame at the current location
894 */
895 static int osst_read_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int timeout)
896 {
897 unsigned char cmd[MAX_COMMAND_SIZE];
898 struct scsi_request * SRpnt;
899 int retval = 0;
900 #if DEBUG
901 os_aux_t * aux = STp->buffer->aux;
902 char * name = tape_name(STp);
903 #endif
904
905 if (STp->poll)
906 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
907 retval = osst_recover_wait_frame(STp, aSRpnt, 0);
908
909 memset(cmd, 0, MAX_COMMAND_SIZE);
910 cmd[0] = READ_6;
911 cmd[1] = 1;
912 cmd[4] = 1;
913
914 #if DEBUG
915 if (debugging)
916 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
917 #endif
918 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
919 STp->timeout, MAX_RETRIES, 1);
920 *aSRpnt = SRpnt;
921 if (!SRpnt)
922 return (-EBUSY);
923
924 if ((STp->buffer)->syscall_result) {
925 retval = 1;
926 if (STp->read_error_frame == 0) {
927 STp->read_error_frame = STp->first_frame_position;
928 #if DEBUG
929 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
930 #endif
931 }
932 #if DEBUG
933 if (debugging)
934 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
935 name,
936 SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],
937 SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],
938 SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5],
939 SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7]);
940 #endif
941 }
942 else
943 STp->first_frame_position++;
944 #if DEBUG
945 if (debugging) {
946 char sig[8]; int i;
947 for (i=0;i<4;i++)
948 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
949 sig[4] = '\0';
950 printk(OSST_DEB_MSG
951 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
952 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
953 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
954 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
955 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
956 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
957 if (aux->frame_type==2)
958 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
959 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
960 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
961 }
962 #endif
963 return (retval);
964 }
965
966 static int osst_initiate_read(struct osst_tape * STp, struct scsi_request ** aSRpnt)
967 {
968 struct st_partstat * STps = &(STp->ps[STp->partition]);
969 struct scsi_request * SRpnt ;
970 unsigned char cmd[MAX_COMMAND_SIZE];
971 int retval = 0;
972 char * name = tape_name(STp);
973
974 if (STps->rw != ST_READING) { /* Initialize read operation */
975 if (STps->rw == ST_WRITING || STp->dirty) {
976 STp->write_type = OS_WRITE_DATA;
977 osst_flush_write_buffer(STp, aSRpnt);
978 osst_flush_drive_buffer(STp, aSRpnt);
979 }
980 STps->rw = ST_READING;
981 STp->frame_in_buffer = 0;
982
983 /*
984 * Issue a read 0 command to get the OnStream drive
985 * read frames into its buffer.
986 */
987 memset(cmd, 0, MAX_COMMAND_SIZE);
988 cmd[0] = READ_6;
989 cmd[1] = 1;
990
991 #if DEBUG
992 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
993 #endif
994 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
995 *aSRpnt = SRpnt;
996 if ((retval = STp->buffer->syscall_result))
997 printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
998 }
999
1000 return retval;
1001 }
1002
1003 static int osst_get_logical_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1004 int frame_seq_number, int quiet)
1005 {
1006 struct st_partstat * STps = &(STp->ps[STp->partition]);
1007 char * name = tape_name(STp);
1008 int cnt = 0,
1009 bad = 0,
1010 past = 0,
1011 x,
1012 position;
1013
1014 /*
1015 * If we want just any frame (-1) and there is a frame in the buffer, return it
1016 */
1017 if (frame_seq_number == -1 && STp->frame_in_buffer) {
1018 #if DEBUG
1019 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1020 #endif
1021 return (STps->eof);
1022 }
1023 /*
1024 * Search and wait for the next logical tape frame
1025 */
1026 while (1) {
1027 if (cnt++ > 400) {
1028 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1029 name, frame_seq_number);
1030 if (STp->read_error_frame) {
1031 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1032 #if DEBUG
1033 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1034 name, STp->read_error_frame);
1035 #endif
1036 STp->read_error_frame = 0;
1037 STp->abort_count++;
1038 }
1039 return (-EIO);
1040 }
1041 #if DEBUG
1042 if (debugging)
1043 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1044 name, frame_seq_number, cnt);
1045 #endif
1046 if ( osst_initiate_read(STp, aSRpnt)
1047 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1048 if (STp->raw)
1049 return (-EIO);
1050 position = osst_get_frame_position(STp, aSRpnt);
1051 if (position >= 0xbae && position < 0xbb8)
1052 position = 0xbb8;
1053 else if (position > STp->eod_frame_ppos || ++bad == 10) {
1054 position = STp->read_error_frame - 1;
1055 bad = 0;
1056 }
1057 else {
1058 position += 29;
1059 cnt += 19;
1060 }
1061 #if DEBUG
1062 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1063 name, position);
1064 #endif
1065 osst_set_frame_position(STp, aSRpnt, position, 0);
1066 continue;
1067 }
1068 if (osst_verify_frame(STp, frame_seq_number, quiet))
1069 break;
1070 if (osst_verify_frame(STp, -1, quiet)) {
1071 x = ntohl(STp->buffer->aux->frame_seq_num);
1072 if (STp->fast_open) {
1073 printk(KERN_WARNING
1074 "%s:W: Found logical frame %d instead of %d after fast open\n",
1075 name, x, frame_seq_number);
1076 STp->header_ok = 0;
1077 STp->read_error_frame = 0;
1078 return (-EIO);
1079 }
1080 if (x > frame_seq_number) {
1081 if (++past > 3) {
1082 /* positioning backwards did not bring us to the desired frame */
1083 position = STp->read_error_frame - 1;
1084 }
1085 else {
1086 position = osst_get_frame_position(STp, aSRpnt)
1087 + frame_seq_number - x - 1;
1088
1089 if (STp->first_frame_position >= 3000 && position < 3000)
1090 position -= 10;
1091 }
1092 #if DEBUG
1093 printk(OSST_DEB_MSG
1094 "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1095 name, x, frame_seq_number,
1096 STp->first_frame_position - position);
1097 #endif
1098 osst_set_frame_position(STp, aSRpnt, position, 0);
1099 cnt += 10;
1100 }
1101 else
1102 past = 0;
1103 }
1104 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1105 #if DEBUG
1106 printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1107 #endif
1108 osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1109 cnt--;
1110 }
1111 STp->frame_in_buffer = 0;
1112 }
1113 if (cnt > 1) {
1114 STp->recover_count++;
1115 STp->recover_erreg++;
1116 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1117 name, STp->read_error_frame);
1118 }
1119 STp->read_count++;
1120
1121 #if DEBUG
1122 if (debugging || STps->eof)
1123 printk(OSST_DEB_MSG
1124 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1125 name, frame_seq_number, STp->frame_seq_number, STps->eof);
1126 #endif
1127 STp->fast_open = 0;
1128 STp->read_error_frame = 0;
1129 return (STps->eof);
1130 }
1131
1132 static int osst_seek_logical_blk(struct osst_tape * STp, struct scsi_request ** aSRpnt, int logical_blk_num)
1133 {
1134 struct st_partstat * STps = &(STp->ps[STp->partition]);
1135 char * name = tape_name(STp);
1136 int retries = 0;
1137 int frame_seq_estimate, ppos_estimate, move;
1138
1139 if (logical_blk_num < 0) logical_blk_num = 0;
1140 #if DEBUG
1141 printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1142 name, logical_blk_num, STp->logical_blk_num,
1143 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1144 STp->block_size<1024?'b':'k');
1145 #endif
1146 /* Do we know where we are? */
1147 if (STps->drv_block >= 0) {
1148 move = logical_blk_num - STp->logical_blk_num;
1149 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1150 move /= (OS_DATA_SIZE / STp->block_size);
1151 frame_seq_estimate = STp->frame_seq_number + move;
1152 } else
1153 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1154
1155 if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1156 else ppos_estimate = frame_seq_estimate + 20;
1157 while (++retries < 10) {
1158 if (ppos_estimate > STp->eod_frame_ppos-2) {
1159 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1160 ppos_estimate = STp->eod_frame_ppos - 2;
1161 }
1162 if (frame_seq_estimate < 0) {
1163 frame_seq_estimate = 0;
1164 ppos_estimate = 10;
1165 }
1166 osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1167 if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1168 /* we've located the estimated frame, now does it have our block? */
1169 if (logical_blk_num < STp->logical_blk_num ||
1170 logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1171 if (STps->eof == ST_FM_HIT)
1172 move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1173 else {
1174 move = logical_blk_num - STp->logical_blk_num;
1175 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1176 move /= (OS_DATA_SIZE / STp->block_size);
1177 }
1178 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1179 #if DEBUG
1180 printk(OSST_DEB_MSG
1181 "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1182 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1183 STp->logical_blk_num, logical_blk_num, move);
1184 #endif
1185 frame_seq_estimate += move;
1186 ppos_estimate += move;
1187 continue;
1188 } else {
1189 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1190 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1191 STp->logical_blk_num = logical_blk_num;
1192 #if DEBUG
1193 printk(OSST_DEB_MSG
1194 "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1195 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1196 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1197 STp->block_size);
1198 #endif
1199 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1200 if (STps->eof == ST_FM_HIT) {
1201 STps->drv_file++;
1202 STps->drv_block = 0;
1203 } else {
1204 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1205 STp->logical_blk_num -
1206 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1207 -1;
1208 }
1209 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1210 return 0;
1211 }
1212 }
1213 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1214 goto error;
1215 /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1216 #if DEBUG
1217 printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1218 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1219 STp->logical_blk_num, logical_blk_num);
1220 #endif
1221 if (frame_seq_estimate != STp->frame_seq_number)
1222 ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1223 else
1224 break;
1225 }
1226 error:
1227 printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1228 name, logical_blk_num, STp->logical_blk_num, retries);
1229 return (-EIO);
1230 }
1231
1232 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1233 * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1234 * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1235 * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1236 */
1237 #define OSST_FRAME_SHIFT 6
1238 #define OSST_SECTOR_SHIFT 9
1239 #define OSST_SECTOR_MASK 0x03F
1240
1241 static int osst_get_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt)
1242 {
1243 int sector;
1244 #if DEBUG
1245 char * name = tape_name(STp);
1246
1247 printk(OSST_DEB_MSG
1248 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1249 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1250 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1251 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1252 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1253 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1254 #endif
1255 /* do we know where we are inside a file? */
1256 if (STp->ps[STp->partition].drv_block >= 0) {
1257 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1258 STp->first_frame_position) << OSST_FRAME_SHIFT;
1259 if (STp->ps[STp->partition].rw == ST_WRITING)
1260 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1261 else
1262 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1263 } else {
1264 sector = osst_get_frame_position(STp, aSRpnt);
1265 if (sector > 0)
1266 sector <<= OSST_FRAME_SHIFT;
1267 }
1268 return sector;
1269 }
1270
1271 static int osst_seek_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt, int sector)
1272 {
1273 struct st_partstat * STps = &(STp->ps[STp->partition]);
1274 int frame = sector >> OSST_FRAME_SHIFT,
1275 offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1276 r;
1277 #if DEBUG
1278 char * name = tape_name(STp);
1279
1280 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1281 name, sector, frame, offset);
1282 #endif
1283 if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1284
1285 if (frame <= STp->first_data_ppos) {
1286 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1287 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1288 }
1289 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1290 if (r < 0) return r;
1291
1292 r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1293 if (r < 0) return r;
1294
1295 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1296
1297 if (offset) {
1298 STp->logical_blk_num += offset / STp->block_size;
1299 STp->buffer->read_pointer = offset;
1300 STp->buffer->buffer_bytes -= offset;
1301 } else {
1302 STp->frame_seq_number++;
1303 STp->frame_in_buffer = 0;
1304 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1305 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1306 }
1307 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1308 if (STps->eof == ST_FM_HIT) {
1309 STps->drv_file++;
1310 STps->drv_block = 0;
1311 } else {
1312 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1313 STp->logical_blk_num -
1314 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1315 -1;
1316 }
1317 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1318 #if DEBUG
1319 printk(OSST_DEB_MSG
1320 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1321 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1322 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1323 #endif
1324 return 0;
1325 }
1326
1327 /*
1328 * Read back the drive's internal buffer contents, as a part
1329 * of the write error recovery mechanism for old OnStream
1330 * firmware revisions.
1331 * Precondition for this function to work: all frames in the
1332 * drive's buffer must be of one type (DATA, MARK or EOD)!
1333 */
1334 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1335 unsigned int frame, unsigned int skip, int pending)
1336 {
1337 struct scsi_request * SRpnt = * aSRpnt;
1338 unsigned char * buffer, * p;
1339 unsigned char cmd[MAX_COMMAND_SIZE];
1340 int flag, new_frame, i;
1341 int nframes = STp->cur_frames;
1342 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1343 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1344 - (nframes + pending - 1);
1345 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1346 - (nframes + pending - 1) * blks_per_frame;
1347 char * name = tape_name(STp);
1348 unsigned long startwait = jiffies;
1349 #if DEBUG
1350 int dbg = debugging;
1351 #endif
1352
1353 if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
1354 return (-EIO);
1355
1356 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1357 name, nframes, pending?" and one that was pending":"");
1358
1359 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1360 #if DEBUG
1361 if (pending && debugging)
1362 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1363 name, frame_seq_number + nframes,
1364 logical_blk_num + nframes * blks_per_frame,
1365 p[0], p[1], p[2], p[3]);
1366 #endif
1367 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1368
1369 memset(cmd, 0, MAX_COMMAND_SIZE);
1370 cmd[0] = 0x3C; /* Buffer Read */
1371 cmd[1] = 6; /* Retrieve Faulty Block */
1372 cmd[7] = 32768 >> 8;
1373 cmd[8] = 32768 & 0xff;
1374
1375 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1376 STp->timeout, MAX_RETRIES, 1);
1377
1378 if ((STp->buffer)->syscall_result || !SRpnt) {
1379 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1380 vfree((void *)buffer);
1381 *aSRpnt = SRpnt;
1382 return (-EIO);
1383 }
1384 osst_copy_from_buffer(STp->buffer, p);
1385 #if DEBUG
1386 if (debugging)
1387 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1388 name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1389 #endif
1390 }
1391 *aSRpnt = SRpnt;
1392 osst_get_frame_position(STp, aSRpnt);
1393
1394 #if DEBUG
1395 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1396 #endif
1397 /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1398 /* In the header we don't actually re-write the frames that fail, just the ones after them */
1399
1400 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1401
1402 if (flag) {
1403 if (STp->write_type == OS_WRITE_HEADER) {
1404 i += skip;
1405 p += skip * OS_DATA_SIZE;
1406 }
1407 else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1408 new_frame = 3000-i;
1409 else
1410 new_frame += skip;
1411 #if DEBUG
1412 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1413 name, new_frame+i, frame_seq_number+i);
1414 #endif
1415 osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1416 osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1417 osst_get_frame_position(STp, aSRpnt);
1418 SRpnt = * aSRpnt;
1419
1420 if (new_frame > frame + 1000) {
1421 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1422 vfree((void *)buffer);
1423 return (-EIO);
1424 }
1425 if ( i >= nframes + pending ) break;
1426 flag = 0;
1427 }
1428 osst_copy_to_buffer(STp->buffer, p);
1429 /*
1430 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1431 */
1432 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1433 logical_blk_num + i*blks_per_frame,
1434 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1435 memset(cmd, 0, MAX_COMMAND_SIZE);
1436 cmd[0] = WRITE_6;
1437 cmd[1] = 1;
1438 cmd[4] = 1;
1439
1440 #if DEBUG
1441 if (debugging)
1442 printk(OSST_DEB_MSG
1443 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1444 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1445 p[0], p[1], p[2], p[3]);
1446 #endif
1447 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1448 STp->timeout, MAX_RETRIES, 1);
1449
1450 if (STp->buffer->syscall_result)
1451 flag = 1;
1452 else {
1453 p += OS_DATA_SIZE; i++;
1454
1455 /* if we just sent the last frame, wait till all successfully written */
1456 if ( i == nframes + pending ) {
1457 #if DEBUG
1458 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1459 #endif
1460 memset(cmd, 0, MAX_COMMAND_SIZE);
1461 cmd[0] = WRITE_FILEMARKS;
1462 cmd[1] = 1;
1463 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1464 STp->timeout, MAX_RETRIES, 1);
1465 #if DEBUG
1466 if (debugging) {
1467 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1468 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1469 debugging = 0;
1470 }
1471 #endif
1472 flag = STp->buffer->syscall_result;
1473 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1474
1475 memset(cmd, 0, MAX_COMMAND_SIZE);
1476 cmd[0] = TEST_UNIT_READY;
1477
1478 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1479 MAX_RETRIES, 1);
1480
1481 if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
1482 (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) {
1483 /* in the process of becoming ready */
1484 msleep(100);
1485 continue;
1486 }
1487 if (STp->buffer->syscall_result)
1488 flag = 1;
1489 break;
1490 }
1491 #if DEBUG
1492 debugging = dbg;
1493 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1494 #endif
1495 }
1496 }
1497 *aSRpnt = SRpnt;
1498 if (flag) {
1499 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
1500 SRpnt->sr_sense_buffer[12] == 0 &&
1501 SRpnt->sr_sense_buffer[13] == 2) {
1502 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1503 vfree((void *)buffer);
1504 return (-EIO); /* hit end of tape = fail */
1505 }
1506 i = ((SRpnt->sr_sense_buffer[3] << 24) |
1507 (SRpnt->sr_sense_buffer[4] << 16) |
1508 (SRpnt->sr_sense_buffer[5] << 8) |
1509 SRpnt->sr_sense_buffer[6] ) - new_frame;
1510 p = &buffer[i * OS_DATA_SIZE];
1511 #if DEBUG
1512 printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1513 #endif
1514 osst_get_frame_position(STp, aSRpnt);
1515 #if DEBUG
1516 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1517 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1518 #endif
1519 }
1520 }
1521 if (flag) {
1522 /* error recovery did not successfully complete */
1523 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1524 STp->write_type == OS_WRITE_HEADER?"header":"body");
1525 }
1526 if (!pending)
1527 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1528 vfree((void *)buffer);
1529 return 0;
1530 }
1531
1532 static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1533 unsigned int frame, unsigned int skip, int pending)
1534 {
1535 unsigned char cmd[MAX_COMMAND_SIZE];
1536 struct scsi_request * SRpnt;
1537 char * name = tape_name(STp);
1538 int expected = 0;
1539 int attempts = 1000 / skip;
1540 int flag = 1;
1541 unsigned long startwait = jiffies;
1542 #if DEBUG
1543 int dbg = debugging;
1544 #endif
1545
1546 while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1547 if (flag) {
1548 #if DEBUG
1549 debugging = dbg;
1550 #endif
1551 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1552 frame = 3000-skip;
1553 expected = frame+skip+STp->cur_frames+pending;
1554 #if DEBUG
1555 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1556 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1557 #endif
1558 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1559 flag = 0;
1560 attempts--;
1561 set_current_state(TASK_INTERRUPTIBLE);
1562 schedule_timeout(HZ / 10);
1563 }
1564 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1565 #if DEBUG
1566 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1567 name, STp->first_frame_position,
1568 STp->last_frame_position, STp->cur_frames);
1569 #endif
1570 frame = STp->last_frame_position;
1571 flag = 1;
1572 continue;
1573 }
1574 if (pending && STp->cur_frames < 50) {
1575
1576 memset(cmd, 0, MAX_COMMAND_SIZE);
1577 cmd[0] = WRITE_6;
1578 cmd[1] = 1;
1579 cmd[4] = 1;
1580 #if DEBUG
1581 printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1582 name, STp->frame_seq_number-1, STp->first_frame_position);
1583 #endif
1584 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1585 STp->timeout, MAX_RETRIES, 1);
1586 *aSRpnt = SRpnt;
1587
1588 if (STp->buffer->syscall_result) { /* additional write error */
1589 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
1590 SRpnt->sr_sense_buffer[12] == 0 &&
1591 SRpnt->sr_sense_buffer[13] == 2) {
1592 printk(KERN_ERR
1593 "%s:E: Volume overflow in write error recovery\n",
1594 name);
1595 break; /* hit end of tape = fail */
1596 }
1597 flag = 1;
1598 }
1599 else
1600 pending = 0;
1601
1602 continue;
1603 }
1604 if (STp->cur_frames == 0) {
1605 #if DEBUG
1606 debugging = dbg;
1607 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1608 #endif
1609 if (STp->first_frame_position != expected) {
1610 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1611 name, STp->first_frame_position, expected);
1612 return (-EIO);
1613 }
1614 return 0;
1615 }
1616 #if DEBUG
1617 if (debugging) {
1618 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1619 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1620 debugging = 0;
1621 }
1622 #endif
1623 set_current_state(TASK_INTERRUPTIBLE);
1624 schedule_timeout(HZ / 10);
1625 }
1626 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1627 #if DEBUG
1628 debugging = dbg;
1629 #endif
1630 return (-EIO);
1631 }
1632
1633 /*
1634 * Error recovery algorithm for the OnStream tape.
1635 */
1636
1637 static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending)
1638 {
1639 struct scsi_request * SRpnt = * aSRpnt;
1640 struct st_partstat * STps = & STp->ps[STp->partition];
1641 char * name = tape_name(STp);
1642 int retval = 0;
1643 int rw_state;
1644 unsigned int frame, skip;
1645
1646 rw_state = STps->rw;
1647
1648 if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) != 3
1649 || SRpnt->sr_sense_buffer[12] != 12
1650 || SRpnt->sr_sense_buffer[13] != 0) {
1651 #if DEBUG
1652 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1653 SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
1654 #endif
1655 return (-EIO);
1656 }
1657 frame = (SRpnt->sr_sense_buffer[3] << 24) |
1658 (SRpnt->sr_sense_buffer[4] << 16) |
1659 (SRpnt->sr_sense_buffer[5] << 8) |
1660 SRpnt->sr_sense_buffer[6];
1661 skip = SRpnt->sr_sense_buffer[9];
1662
1663 #if DEBUG
1664 printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1665 #endif
1666 osst_get_frame_position(STp, aSRpnt);
1667 #if DEBUG
1668 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1669 name, STp->first_frame_position, STp->last_frame_position);
1670 #endif
1671 switch (STp->write_type) {
1672 case OS_WRITE_DATA:
1673 case OS_WRITE_EOD:
1674 case OS_WRITE_NEW_MARK:
1675 printk(KERN_WARNING
1676 "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1677 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1678 if (STp->os_fw_rev >= 10600)
1679 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1680 else
1681 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1682 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1683 retval?"E" :"I",
1684 retval?"" :"Don't worry, ",
1685 retval?" not ":" ");
1686 break;
1687 case OS_WRITE_LAST_MARK:
1688 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1689 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1690 retval = -EIO;
1691 break;
1692 case OS_WRITE_HEADER:
1693 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1694 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1695 break;
1696 default:
1697 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1698 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1699 }
1700 osst_get_frame_position(STp, aSRpnt);
1701 #if DEBUG
1702 printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1703 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1704 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1705 #endif
1706 if (retval == 0) {
1707 STp->recover_count++;
1708 STp->recover_erreg++;
1709 } else
1710 STp->abort_count++;
1711
1712 STps->rw = rw_state;
1713 return retval;
1714 }
1715
1716 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1717 int mt_op, int mt_count)
1718 {
1719 char * name = tape_name(STp);
1720 int cnt;
1721 int last_mark_ppos = -1;
1722
1723 #if DEBUG
1724 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1725 #endif
1726 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1727 #if DEBUG
1728 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1729 #endif
1730 return -EIO;
1731 }
1732 if (STp->linux_media_version >= 4) {
1733 /*
1734 * direct lookup in header filemark list
1735 */
1736 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1737 if (STp->header_ok &&
1738 STp->header_cache != NULL &&
1739 (cnt - mt_count) >= 0 &&
1740 (cnt - mt_count) < OS_FM_TAB_MAX &&
1741 (cnt - mt_count) < STp->filemark_cnt &&
1742 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1743
1744 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1745 #if DEBUG
1746 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1747 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1748 STp->header_cache == NULL?"lack of header cache":"count out of range");
1749 else
1750 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1751 name, cnt,
1752 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1753 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1754 STp->buffer->aux->last_mark_ppos))?"match":"error",
1755 mt_count, last_mark_ppos);
1756 #endif
1757 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1758 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1759 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1760 #if DEBUG
1761 printk(OSST_DEB_MSG
1762 "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1763 #endif
1764 return (-EIO);
1765 }
1766 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1767 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1768 name, last_mark_ppos);
1769 return (-EIO);
1770 }
1771 goto found;
1772 }
1773 #if DEBUG
1774 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1775 #endif
1776 }
1777 cnt = 0;
1778 while (cnt != mt_count) {
1779 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1780 if (last_mark_ppos == -1)
1781 return (-EIO);
1782 #if DEBUG
1783 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1784 #endif
1785 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1786 cnt++;
1787 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1788 #if DEBUG
1789 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1790 #endif
1791 return (-EIO);
1792 }
1793 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1794 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1795 name, last_mark_ppos);
1796 return (-EIO);
1797 }
1798 }
1799 found:
1800 if (mt_op == MTBSFM) {
1801 STp->frame_seq_number++;
1802 STp->frame_in_buffer = 0;
1803 STp->buffer->buffer_bytes = 0;
1804 STp->buffer->read_pointer = 0;
1805 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1806 }
1807 return 0;
1808 }
1809
1810 /*
1811 * ADRL 1.1 compatible "slow" space filemarks fwd version
1812 *
1813 * Just scans for the filemark sequentially.
1814 */
1815 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1816 int mt_op, int mt_count)
1817 {
1818 int cnt = 0;
1819 #if DEBUG
1820 char * name = tape_name(STp);
1821
1822 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1823 #endif
1824 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1825 #if DEBUG
1826 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1827 #endif
1828 return (-EIO);
1829 }
1830 while (1) {
1831 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1832 #if DEBUG
1833 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1834 #endif
1835 return (-EIO);
1836 }
1837 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1838 cnt++;
1839 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1840 #if DEBUG
1841 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1842 #endif
1843 if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1844 #if DEBUG
1845 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1846 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1847 #endif
1848 STp->eod_frame_ppos = STp->first_frame_position-1;
1849 }
1850 return (-EIO);
1851 }
1852 if (cnt == mt_count)
1853 break;
1854 STp->frame_in_buffer = 0;
1855 }
1856 if (mt_op == MTFSF) {
1857 STp->frame_seq_number++;
1858 STp->frame_in_buffer = 0;
1859 STp->buffer->buffer_bytes = 0;
1860 STp->buffer->read_pointer = 0;
1861 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1862 }
1863 return 0;
1864 }
1865
1866 /*
1867 * Fast linux specific version of OnStream FSF
1868 */
1869 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct scsi_request ** aSRpnt,
1870 int mt_op, int mt_count)
1871 {
1872 char * name = tape_name(STp);
1873 int cnt = 0,
1874 next_mark_ppos = -1;
1875
1876 #if DEBUG
1877 printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
1878 #endif
1879 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1880 #if DEBUG
1881 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1882 #endif
1883 return (-EIO);
1884 }
1885
1886 if (STp->linux_media_version >= 4) {
1887 /*
1888 * direct lookup in header filemark list
1889 */
1890 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
1891 if (STp->header_ok &&
1892 STp->header_cache != NULL &&
1893 (cnt + mt_count) < OS_FM_TAB_MAX &&
1894 (cnt + mt_count) < STp->filemark_cnt &&
1895 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1896 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
1897
1898 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
1899 #if DEBUG
1900 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
1901 printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1902 STp->header_cache == NULL?"lack of header cache":"count out of range");
1903 else
1904 printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1905 name, cnt,
1906 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1907 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
1908 STp->buffer->aux->last_mark_ppos))?"match":"error",
1909 mt_count, next_mark_ppos);
1910 #endif
1911 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
1912 #if DEBUG
1913 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1914 #endif
1915 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1916 } else {
1917 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
1918 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1919 #if DEBUG
1920 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
1921 name);
1922 #endif
1923 return (-EIO);
1924 }
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",
1927 name, next_mark_ppos);
1928 return (-EIO);
1929 }
1930 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
1931 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
1932 name, cnt+mt_count, next_mark_ppos,
1933 ntohl(STp->buffer->aux->filemark_cnt));
1934 return (-EIO);
1935 }
1936 }
1937 } else {
1938 /*
1939 * Find nearest (usually previous) marker, then jump from marker to marker
1940 */
1941 while (1) {
1942 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1943 break;
1944 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1945 #if DEBUG
1946 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1947 #endif
1948 return (-EIO);
1949 }
1950 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
1951 if (STp->first_mark_ppos == -1) {
1952 #if DEBUG
1953 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1954 #endif
1955 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
1956 }
1957 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
1958 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1959 #if DEBUG
1960 printk(OSST_DEB_MSG
1961 "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
1962 name);
1963 #endif
1964 return (-EIO);
1965 }
1966 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1967 printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
1968 name, STp->first_mark_ppos);
1969 return (-EIO);
1970 }
1971 } else {
1972 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
1973 return (-EIO);
1974 mt_count++;
1975 }
1976 }
1977 cnt++;
1978 while (cnt != mt_count) {
1979 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
1980 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
1981 #if DEBUG
1982 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
1983 #endif
1984 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
1985 }
1986 #if DEBUG
1987 else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
1988 #endif
1989 osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
1990 cnt++;
1991 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1992 #if DEBUG
1993 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
1994 name);
1995 #endif
1996 return (-EIO);
1997 }
1998 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1999 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2000 name, next_mark_ppos);
2001 return (-EIO);
2002 }
2003 }
2004 }
2005 if (mt_op == MTFSF) {
2006 STp->frame_seq_number++;
2007 STp->frame_in_buffer = 0;
2008 STp->buffer->buffer_bytes = 0;
2009 STp->buffer->read_pointer = 0;
2010 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2011 }
2012 return 0;
2013 }
2014
2015 /*
2016 * In debug mode, we want to see as many errors as possible
2017 * to test the error recovery mechanism.
2018 */
2019 #if DEBUG
2020 static void osst_set_retries(struct osst_tape * STp, struct scsi_request ** aSRpnt, int retries)
2021 {
2022 unsigned char cmd[MAX_COMMAND_SIZE];
2023 struct scsi_request * SRpnt = * aSRpnt;
2024 char * name = tape_name(STp);
2025
2026 memset(cmd, 0, MAX_COMMAND_SIZE);
2027 cmd[0] = MODE_SELECT;
2028 cmd[1] = 0x10;
2029 cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2030
2031 (STp->buffer)->b_data[0] = cmd[4] - 1;
2032 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
2033 (STp->buffer)->b_data[2] = 0; /* Reserved */
2034 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
2035 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2036 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2037 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2038 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2039
2040 if (debugging)
2041 printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2042
2043 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2044 *aSRpnt = SRpnt;
2045
2046 if ((STp->buffer)->syscall_result)
2047 printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2048 }
2049 #endif
2050
2051
2052 static int osst_write_filemark(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2053 {
2054 int result;
2055 int this_mark_ppos = STp->first_frame_position;
2056 int this_mark_lbn = STp->logical_blk_num;
2057 #if DEBUG
2058 char * name = tape_name(STp);
2059 #endif
2060
2061 if (STp->raw) return 0;
2062
2063 STp->write_type = OS_WRITE_NEW_MARK;
2064 #if DEBUG
2065 printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2066 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2067 #endif
2068 STp->dirty = 1;
2069 result = osst_flush_write_buffer(STp, aSRpnt);
2070 result |= osst_flush_drive_buffer(STp, aSRpnt);
2071 STp->last_mark_ppos = this_mark_ppos;
2072 STp->last_mark_lbn = this_mark_lbn;
2073 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2074 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2075 if (STp->filemark_cnt++ == 0)
2076 STp->first_mark_ppos = this_mark_ppos;
2077 return result;
2078 }
2079
2080 static int osst_write_eod(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2081 {
2082 int result;
2083 #if DEBUG
2084 char * name = tape_name(STp);
2085 #endif
2086
2087 if (STp->raw) return 0;
2088
2089 STp->write_type = OS_WRITE_EOD;
2090 STp->eod_frame_ppos = STp->first_frame_position;
2091 #if DEBUG
2092 printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2093 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2094 #endif
2095 STp->dirty = 1;
2096
2097 result = osst_flush_write_buffer(STp, aSRpnt);
2098 result |= osst_flush_drive_buffer(STp, aSRpnt);
2099 STp->eod_frame_lfa = --(STp->frame_seq_number);
2100 return result;
2101 }
2102
2103 static int osst_write_filler(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count)
2104 {
2105 char * name = tape_name(STp);
2106
2107 #if DEBUG
2108 printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2109 #endif
2110 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2111 osst_set_frame_position(STp, aSRpnt, where, 0);
2112 STp->write_type = OS_WRITE_FILLER;
2113 while (count--) {
2114 memcpy(STp->buffer->b_data, "Filler", 6);
2115 STp->buffer->buffer_bytes = 6;
2116 STp->dirty = 1;
2117 if (osst_flush_write_buffer(STp, aSRpnt)) {
2118 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2119 return (-EIO);
2120 }
2121 }
2122 #if DEBUG
2123 printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2124 #endif
2125 return osst_flush_drive_buffer(STp, aSRpnt);
2126 }
2127
2128 static int __osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count)
2129 {
2130 char * name = tape_name(STp);
2131 int result;
2132
2133 #if DEBUG
2134 printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2135 #endif
2136 osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2137 osst_set_frame_position(STp, aSRpnt, where, 0);
2138 STp->write_type = OS_WRITE_HEADER;
2139 while (count--) {
2140 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2141 STp->buffer->buffer_bytes = sizeof(os_header_t);
2142 STp->dirty = 1;
2143 if (osst_flush_write_buffer(STp, aSRpnt)) {
2144 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2145 return (-EIO);
2146 }
2147 }
2148 result = osst_flush_drive_buffer(STp, aSRpnt);
2149 #if DEBUG
2150 printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2151 #endif
2152 return result;
2153 }
2154
2155 static int osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int locate_eod)
2156 {
2157 os_header_t * header;
2158 int result;
2159 char * name = tape_name(STp);
2160
2161 #if DEBUG
2162 printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2163 #endif
2164 if (STp->raw) return 0;
2165
2166 if (STp->header_cache == NULL) {
2167 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2168 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2169 return (-ENOMEM);
2170 }
2171 memset(STp->header_cache, 0, sizeof(os_header_t));
2172 #if DEBUG
2173 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2174 #endif
2175 }
2176 if (STp->header_ok) STp->update_frame_cntr++;
2177 else STp->update_frame_cntr = 0;
2178
2179 header = STp->header_cache;
2180 strcpy(header->ident_str, "ADR_SEQ");
2181 header->major_rev = 1;
2182 header->minor_rev = 4;
2183 header->ext_trk_tb_off = htons(17192);
2184 header->pt_par_num = 1;
2185 header->partition[0].partition_num = OS_DATA_PARTITION;
2186 header->partition[0].par_desc_ver = OS_PARTITION_VERSION;
2187 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2188 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2189 header->partition[0].last_frame_ppos = htonl(STp->capacity);
2190 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2191 header->cfg_col_width = htonl(20);
2192 header->dat_col_width = htonl(1500);
2193 header->qfa_col_width = htonl(0);
2194 header->ext_track_tb.nr_stream_part = 1;
2195 header->ext_track_tb.et_ent_sz = 32;
2196 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2197 header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2198 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2199 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2200 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa);
2201 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
2202 header->dat_fm_tab.fm_part_num = 0;
2203 header->dat_fm_tab.fm_tab_ent_sz = 4;
2204 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2205 STp->filemark_cnt:OS_FM_TAB_MAX);
2206
2207 result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2208 if (STp->update_frame_cntr == 0)
2209 osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2210 result &= __osst_write_header(STp, aSRpnt, 5, 5);
2211
2212 if (locate_eod) {
2213 #if DEBUG
2214 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2215 #endif
2216 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2217 }
2218 if (result)
2219 printk(KERN_ERR "%s:E: Write header failed\n", name);
2220 else {
2221 memcpy(STp->application_sig, "LIN4", 4);
2222 STp->linux_media = 1;
2223 STp->linux_media_version = 4;
2224 STp->header_ok = 1;
2225 }
2226 return result;
2227 }
2228
2229 static int osst_reset_header(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2230 {
2231 if (STp->header_cache != NULL)
2232 memset(STp->header_cache, 0, sizeof(os_header_t));
2233
2234 STp->logical_blk_num = STp->frame_seq_number = 0;
2235 STp->frame_in_buffer = 0;
2236 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2237 STp->filemark_cnt = 0;
2238 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2239 return osst_write_header(STp, aSRpnt, 1);
2240 }
2241
2242 static int __osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt, int ppos)
2243 {
2244 char * name = tape_name(STp);
2245 os_header_t * header;
2246 os_aux_t * aux;
2247 char id_string[8];
2248 int linux_media_version,
2249 update_frame_cntr;
2250
2251 if (STp->raw)
2252 return 1;
2253
2254 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2255 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2256 printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2257 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2258 if (osst_initiate_read (STp, aSRpnt)) {
2259 printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2260 return 0;
2261 }
2262 }
2263 if (osst_read_frame(STp, aSRpnt, 180)) {
2264 #if DEBUG
2265 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2266 #endif
2267 return 0;
2268 }
2269 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2270 aux = STp->buffer->aux;
2271 if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2272 #if DEBUG
2273 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2274 #endif
2275 return 0;
2276 }
2277 if (ntohl(aux->frame_seq_num) != 0 ||
2278 ntohl(aux->logical_blk_num) != 0 ||
2279 aux->partition.partition_num != OS_CONFIG_PARTITION ||
2280 ntohl(aux->partition.first_frame_ppos) != 0 ||
2281 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2282 #if DEBUG
2283 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2284 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2285 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2286 ntohl(aux->partition.last_frame_ppos));
2287 #endif
2288 return 0;
2289 }
2290 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2291 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2292 strlcpy(id_string, header->ident_str, 8);
2293 #if DEBUG
2294 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2295 #endif
2296 return 0;
2297 }
2298 update_frame_cntr = ntohl(aux->update_frame_cntr);
2299 if (update_frame_cntr < STp->update_frame_cntr) {
2300 #if DEBUG
2301 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2302 name, ppos, update_frame_cntr, STp->update_frame_cntr);
2303 #endif
2304 return 0;
2305 }
2306 if (header->major_rev != 1 || header->minor_rev != 4 ) {
2307 #if DEBUG
2308 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2309 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2310 header->minor_rev > 4 )? "Invalid" : "Warning:",
2311 header->major_rev, header->minor_rev);
2312 #endif
2313 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2314 return 0;
2315 }
2316 #if DEBUG
2317 if (header->pt_par_num != 1)
2318 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2319 name, header->pt_par_num);
2320 #endif
2321 memcpy(id_string, aux->application_sig, 4);
2322 id_string[4] = 0;
2323 if (memcmp(id_string, "LIN", 3) == 0) {
2324 STp->linux_media = 1;
2325 linux_media_version = id_string[3] - '';
2326 if (linux_media_version != 4)
2327 printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2328 name, linux_media_version);
2329 } else {
2330 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2331 return 0;
2332 }
2333 if (linux_media_version < STp->linux_media_version) {
2334 #if DEBUG
2335 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2336 name, ppos, linux_media_version);
2337 #endif
2338 return 0;
2339 }
2340 if (linux_media_version > STp->linux_media_version) {
2341 #if DEBUG
2342 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2343 name, ppos, linux_media_version);
2344 #endif
2345 memcpy(STp->application_sig, id_string, 5);
2346 STp->linux_media_version = linux_media_version;
2347 STp->update_frame_cntr = -1;
2348 }
2349 if (update_frame_cntr > STp->update_frame_cntr) {
2350 #if DEBUG
2351 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2352 name, ppos, update_frame_cntr);
2353 #endif
2354 if (STp->header_cache == NULL) {
2355 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2356 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2357 return 0;
2358 }
2359 #if DEBUG
2360 printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2361 #endif
2362 }
2363 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2364 header = STp->header_cache; /* further accesses from cached (full) copy */
2365
2366 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2367 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2368 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2369 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2370 STp->filemark_cnt = ntohl(aux->filemark_cnt);
2371 STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2372 STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2373 STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2374 STp->update_frame_cntr = update_frame_cntr;
2375 #if DEBUG
2376 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2377 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2378 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2379 STp->first_data_ppos,
2380 ntohl(header->partition[0].last_frame_ppos),
2381 ntohl(header->partition[0].eod_frame_ppos));
2382 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2383 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2384 #endif
2385 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2386 #if DEBUG
2387 printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2388 #endif
2389 memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2390 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2391 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2392 }
2393 if (header->minor_rev == 4 &&
2394 (header->ext_trk_tb_off != htons(17192) ||
2395 header->partition[0].partition_num != OS_DATA_PARTITION ||
2396 header->partition[0].par_desc_ver != OS_PARTITION_VERSION ||
2397 header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2398 header->cfg_col_width != htonl(20) ||
2399 header->dat_col_width != htonl(1500) ||
2400 header->qfa_col_width != htonl(0) ||
2401 header->ext_track_tb.nr_stream_part != 1 ||
2402 header->ext_track_tb.et_ent_sz != 32 ||
2403 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION ||
2404 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2405 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2406 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2407 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) ||
2408 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION ||
2409 header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2410 header->dat_fm_tab.fm_tab_ent_cnt !=
2411 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2412 printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2413
2414 }
2415
2416 return 1;
2417 }
2418
2419 static int osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2420 {
2421 int position, ppos;
2422 int first, last;
2423 int valid = 0;
2424 char * name = tape_name(STp);
2425
2426 position = osst_get_frame_position(STp, aSRpnt);
2427
2428 if (STp->raw) {
2429 STp->header_ok = STp->linux_media = 1;
2430 STp->linux_media_version = 0;
2431 return 1;
2432 }
2433 STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2434 STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2435 STp->eod_frame_ppos = STp->first_data_ppos = -1;
2436 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2437 #if DEBUG
2438 printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2439 #endif
2440
2441 /* optimization for speed - if we are positioned at ppos 10, read second group first */
2442 /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2443
2444 first = position==10?0xbae: 5;
2445 last = position==10?0xbb3:10;
2446
2447 for (ppos = first; ppos < last; ppos++)
2448 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2449 valid = 1;
2450
2451 first = position==10? 5:0xbae;
2452 last = position==10?10:0xbb3;
2453
2454 for (ppos = first; ppos < last; ppos++)
2455 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2456 valid = 1;
2457
2458 if (!valid) {
2459 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2460 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2461 osst_set_frame_position(STp, aSRpnt, 10, 0);
2462 return 0;
2463 }
2464 if (position <= STp->first_data_ppos) {
2465 position = STp->first_data_ppos;
2466 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2467 }
2468 osst_set_frame_position(STp, aSRpnt, position, 0);
2469 STp->header_ok = 1;
2470
2471 return 1;
2472 }
2473
2474 static int osst_verify_position(struct osst_tape * STp, struct scsi_request ** aSRpnt)
2475 {
2476 int frame_position = STp->first_frame_position;
2477 int frame_seq_numbr = STp->frame_seq_number;
2478 int logical_blk_num = STp->logical_blk_num;
2479 int halfway_frame = STp->frame_in_buffer;
2480 int read_pointer = STp->buffer->read_pointer;
2481 int prev_mark_ppos = -1;
2482 int actual_mark_ppos, i, n;
2483 #if DEBUG
2484 char * name = tape_name(STp);
2485
2486 printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2487 #endif
2488 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2489 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2490 #if DEBUG
2491 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2492 #endif
2493 return (-EIO);
2494 }
2495 if (STp->linux_media_version >= 4) {
2496 for (i=0; i<STp->filemark_cnt; i++)
2497 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2498 prev_mark_ppos = n;
2499 } else
2500 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2501 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2502 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2503 if (frame_position != STp->first_frame_position ||
2504 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2505 prev_mark_ppos != actual_mark_ppos ) {
2506 #if DEBUG
2507 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2508 STp->first_frame_position, frame_position,
2509 STp->frame_seq_number + (halfway_frame?0:1),
2510 frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2511 #endif
2512 return (-EIO);
2513 }
2514 if (halfway_frame) {
2515 /* prepare buffer for append and rewrite on top of original */
2516 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2517 STp->buffer->buffer_bytes = read_pointer;
2518 STp->ps[STp->partition].rw = ST_WRITING;
2519 STp->dirty = 1;
2520 }
2521 STp->frame_in_buffer = halfway_frame;
2522 STp->frame_seq_number = frame_seq_numbr;
2523 STp->logical_blk_num = logical_blk_num;
2524 return 0;
2525 }
2526
2527 /* Acc. to OnStream, the vers. numbering is the following:
2528 * X.XX for released versions (X=digit),
2529 * XXXY for unreleased versions (Y=letter)
2530 * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2531 * This fn makes monoton numbers out of this scheme ...
2532 */
2533 static unsigned int osst_parse_firmware_rev (const char * str)
2534 {
2535 if (str[1] == '.') {
2536 return (str[0]-'')*10000
2537 +(str[2]-'')*1000
2538 +(str[3]-'')*100;
2539 } else {
2540 return (str[0]-'')*10000
2541 +(str[1]-'')*1000
2542 +(str[2]-'')*100 - 100
2543 +(str[3]-'@');
2544 }
2545 }
2546
2547 /*
2548 * Configure the OnStream SCII tape drive for default operation
2549 */
2550 static int osst_configure_onstream(struct osst_tape *STp, struct scsi_request ** aSRpnt)
2551 {
2552 unsigned char cmd[MAX_COMMAND_SIZE];
2553 char * name = tape_name(STp);
2554 struct scsi_request * SRpnt = * aSRpnt;
2555 osst_mode_parameter_header_t * header;
2556 osst_block_size_page_t * bs;
2557 osst_capabilities_page_t * cp;
2558 osst_tape_paramtr_page_t * prm;
2559 int drive_buffer_size;
2560
2561 if (STp->ready != ST_READY) {
2562 #if DEBUG
2563 printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2564 #endif
2565 return (-EIO);
2566 }
2567
2568 if (STp->os_fw_rev < 10600) {
2569 printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2570 printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2571 }
2572
2573 /*
2574 * Configure 32.5KB (data+aux) frame size.
2575 * Get the current frame size from the block size mode page
2576 */
2577 memset(cmd, 0, MAX_COMMAND_SIZE);
2578 cmd[0] = MODE_SENSE;
2579 cmd[1] = 8;
2580 cmd[2] = BLOCK_SIZE_PAGE;
2581 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2582
2583 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2584 if (SRpnt == NULL) {
2585 #if DEBUG
2586 printk(OSST_DEB_MSG "osst :D: Busy\n");
2587 #endif
2588 return (-EBUSY);
2589 }
2590 *aSRpnt = SRpnt;
2591 if ((STp->buffer)->syscall_result != 0) {
2592 printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2593 return (-EIO);
2594 }
2595
2596 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2597 bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2598
2599 #if DEBUG
2600 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2601 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No");
2602 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2603 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2604 #endif
2605
2606 /*
2607 * Configure default auto columns mode, 32.5KB transfer mode
2608 */
2609 bs->one = 1;
2610 bs->play32 = 0;
2611 bs->play32_5 = 1;
2612 bs->record32 = 0;
2613 bs->record32_5 = 1;
2614
2615 memset(cmd, 0, MAX_COMMAND_SIZE);
2616 cmd[0] = MODE_SELECT;
2617 cmd[1] = 0x10;
2618 cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2619
2620 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2621 *aSRpnt = SRpnt;
2622 if ((STp->buffer)->syscall_result != 0) {
2623 printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2624 return (-EIO);
2625 }
2626
2627 #if DEBUG
2628 printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2629 /*
2630 * In debug mode, we want to see as many errors as possible
2631 * to test the error recovery mechanism.
2632 */
2633 osst_set_retries(STp, aSRpnt, 0);
2634 SRpnt = * aSRpnt;
2635 #endif
2636
2637 /*
2638 * Set vendor name to 'LIN4' for "Linux support version 4".
2639 */
2640
2641 memset(cmd, 0, MAX_COMMAND_SIZE);
2642 cmd[0] = MODE_SELECT;
2643 cmd[1] = 0x10;
2644 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2645
2646 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2647 header->medium_type = 0; /* Medium Type - ignoring */
2648 header->dsp = 0; /* Reserved */
2649 header->bdl = 0; /* Block Descriptor Length */
2650
2651 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2652 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2653 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2654 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2655 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2656 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2657 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2658 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2659
2660 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2661 *aSRpnt = SRpnt;
2662
2663 if ((STp->buffer)->syscall_result != 0) {
2664 printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2665 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2666 return (-EIO);
2667 }
2668
2669 memset(cmd, 0, MAX_COMMAND_SIZE);
2670 cmd[0] = MODE_SENSE;
2671 cmd[1] = 8;
2672 cmd[2] = CAPABILITIES_PAGE;
2673 cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2674
2675 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2676 *aSRpnt = SRpnt;
2677
2678 if ((STp->buffer)->syscall_result != 0) {
2679 printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2680 return (-EIO);
2681 }
2682
2683 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2684 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2685 sizeof(osst_mode_parameter_header_t) + header->bdl);
2686
2687 drive_buffer_size = ntohs(cp->buffer_size) / 2;
2688
2689 memset(cmd, 0, MAX_COMMAND_SIZE);
2690 cmd[0] = MODE_SENSE;
2691 cmd[1] = 8;
2692 cmd[2] = TAPE_PARAMTR_PAGE;
2693 cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2694
2695 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2696 *aSRpnt = SRpnt;
2697
2698 if ((STp->buffer)->syscall_result != 0) {
2699 printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2700 return (-EIO);
2701 }
2702
2703 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2704 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2705 sizeof(osst_mode_parameter_header_t) + header->bdl);
2706
2707 STp->density = prm->density;
2708 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2709 #if DEBUG
2710 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2711 name, STp->density, STp->capacity / 32, drive_buffer_size);
2712 #endif
2713
2714 return 0;
2715
2716 }
2717
2718
2719 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2720 it messes up the block number). */
2721 static int cross_eof(struct osst_tape *STp, struct scsi_request ** aSRpnt, int forward)
2722 {
2723 int result;
2724 char * name = tape_name(STp);
2725
2726 #if DEBUG
2727 if (debugging)
2728 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2729 name, forward ? "forward" : "backward");
2730 #endif
2731
2732 if (forward) {
2733 /* assumes that the filemark is already read by the drive, so this is low cost */
2734 result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2735 }
2736 else
2737 /* assumes this is only called if we just read the filemark! */
2738 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2739
2740 if (result < 0)
2741 printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2742 name, forward ? "forward" : "backward");
2743
2744 return result;
2745 }
2746
2747
2748 /* Get the tape position. */
2749
2750 static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt)
2751 {
2752 unsigned char scmd[MAX_COMMAND_SIZE];
2753 struct scsi_request * SRpnt;
2754 int result = 0;
2755 char * name = tape_name(STp);
2756
2757 /* KG: We want to be able to use it for checking Write Buffer availability
2758 * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2759 char mybuf[24];
2760 char * olddata = STp->buffer->b_data;
2761 int oldsize = STp->buffer->buffer_size;
2762
2763 if (STp->ready != ST_READY) return (-EIO);
2764
2765 memset (scmd, 0, MAX_COMMAND_SIZE);
2766 scmd[0] = READ_POSITION;
2767
2768 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2769 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2770 STp->timeout, MAX_RETRIES, 1);
2771 if (!SRpnt) {
2772 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2773 return (-EBUSY);
2774 }
2775 *aSRpnt = SRpnt;
2776
2777 if (STp->buffer->syscall_result)
2778 result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */
2779
2780 if (result == -EINVAL)
2781 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2782 else {
2783 if (result == -EIO) { /* re-read position - this needs to preserve media errors */
2784 unsigned char mysense[16];
2785 memcpy (mysense, SRpnt->sr_sense_buffer, 16);
2786 memset (scmd, 0, MAX_COMMAND_SIZE);
2787 scmd[0] = READ_POSITION;
2788 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2789 SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2790 STp->timeout, MAX_RETRIES, 1);
2791 #if DEBUG
2792 printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2793 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2794 SRpnt->sr_sense_buffer[2],SRpnt->sr_sense_buffer[12],SRpnt->sr_sense_buffer[13]);
2795 #endif
2796 if (!STp->buffer->syscall_result)
2797 memcpy (SRpnt->sr_sense_buffer, mysense, 16);
2798 else
2799 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2800 }
2801 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2802 + ((STp->buffer)->b_data[5] << 16)
2803 + ((STp->buffer)->b_data[6] << 8)
2804 + (STp->buffer)->b_data[7];
2805 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2806 + ((STp->buffer)->b_data[ 9] << 16)
2807 + ((STp->buffer)->b_data[10] << 8)
2808 + (STp->buffer)->b_data[11];
2809 STp->cur_frames = (STp->buffer)->b_data[15];
2810 #if DEBUG
2811 if (debugging) {
2812 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2813 STp->first_frame_position, STp->last_frame_position,
2814 ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2815 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2816 STp->cur_frames);
2817 }
2818 #endif
2819 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2820 #if DEBUG
2821 printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2822 STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2823 #endif
2824 STp->first_frame_position = STp->last_frame_position;
2825 }
2826 }
2827 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2828
2829 return (result == 0 ? STp->first_frame_position : result);
2830 }
2831
2832
2833 /* Set the tape block */
2834 static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int ppos, int skip)
2835 {
2836 unsigned char scmd[MAX_COMMAND_SIZE];
2837 struct scsi_request * SRpnt;
2838 struct st_partstat * STps;
2839 int result = 0;
2840 int pp = (ppos == 3000 && !skip)? 0 : ppos;
2841 char * name = tape_name(STp);
2842
2843 if (STp->ready != ST_READY) return (-EIO);
2844
2845 STps = &(STp->ps[STp->partition]);
2846
2847 if (ppos < 0 || ppos > STp->capacity) {
2848 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2849 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2850 result = (-EINVAL);
2851 }
2852
2853 do {
2854 #if DEBUG
2855 if (debugging)
2856 printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2857 #endif
2858 memset (scmd, 0, MAX_COMMAND_SIZE);
2859 scmd[0] = SEEK_10;
2860 scmd[1] = 1;
2861 scmd[3] = (pp >> 24);
2862 scmd[4] = (pp >> 16);
2863 scmd[5] = (pp >> 8);
2864 scmd[6] = pp;
2865 if (skip)
2866 scmd[9] = 0x80;
2867
2868 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
2869 MAX_RETRIES, 1);
2870 if (!SRpnt)
2871 return (-EBUSY);
2872 *aSRpnt = SRpnt;
2873
2874 if ((STp->buffer)->syscall_result != 0) {
2875 #if DEBUG
2876 printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
2877 name, STp->first_frame_position, pp);
2878 #endif
2879 result = (-EIO);
2880 }
2881 if (pp != ppos)
2882 osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
2883 } while ((pp != ppos) && (pp = ppos));
2884 STp->first_frame_position = STp->last_frame_position = ppos;
2885 STps->eof = ST_NOEOF;
2886 STps->at_sm = 0;
2887 STps->rw = ST_IDLE;
2888 STp->frame_in_buffer = 0;
2889 return result;
2890 }
2891
2892 static int osst_write_trailer(struct osst_tape *STp, struct scsi_request ** aSRpnt, int leave_at_EOT)
2893 {
2894 struct st_partstat * STps = &(STp->ps[STp->partition]);
2895 int result = 0;
2896
2897 if (STp->write_type != OS_WRITE_NEW_MARK) {
2898 /* true unless the user wrote the filemark for us */
2899 result = osst_flush_drive_buffer(STp, aSRpnt);
2900 if (result < 0) goto out;
2901 result = osst_write_filemark(STp, aSRpnt);
2902 if (result < 0) goto out;
2903
2904 if (STps->drv_file >= 0)
2905 STps->drv_file++ ;
2906 STps->drv_block = 0;
2907 }
2908 result = osst_write_eod(STp, aSRpnt);
2909 osst_write_header(STp, aSRpnt, leave_at_EOT);
2910
2911 STps->eof = ST_FM;
2912 out:
2913 return result;
2914 }
2915
2916 /* osst versions of st functions - augmented and stripped to suit OnStream only */
2917
2918 /* Flush the write buffer (never need to write if variable blocksize). */
2919 static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt)
2920 {
2921 int offset, transfer, blks = 0;
2922 int result = 0;
2923 unsigned char cmd[MAX_COMMAND_SIZE];
2924 struct scsi_request * SRpnt = *aSRpnt;
2925 struct st_partstat * STps;
2926 char * name = tape_name(STp);
2927
2928 if ((STp->buffer)->writing) {
2929 if (SRpnt == (STp->buffer)->last_SRpnt)
2930 #if DEBUG
2931 { printk(OSST_DEB_MSG
2932 "%s:D: aSRpnt points to scsi_request that write_behind_check will release -- cleared\n", name);
2933 #endif
2934 *aSRpnt = SRpnt = NULL;
2935 #if DEBUG
2936 } else if (SRpnt)
2937 printk(OSST_DEB_MSG
2938 "%s:D: aSRpnt does not point to scsi_request that write_behind_check will release -- strange\n", name);
2939 #endif
2940 osst_write_behind_check(STp);
2941 if ((STp->buffer)->syscall_result) {
2942 #if DEBUG
2943 if (debugging)
2944 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
2945 name, (STp->buffer)->midlevel_result);
2946 #endif
2947 if ((STp->buffer)->midlevel_result == INT_MAX)
2948 return (-ENOSPC);
2949 return (-EIO);
2950 }
2951 }
2952
2953 result = 0;
2954 if (STp->dirty == 1) {
2955
2956 STp->write_count++;
2957 STps = &(STp->ps[STp->partition]);
2958 STps->rw = ST_WRITING;
2959 offset = STp->buffer->buffer_bytes;
2960 blks = (offset + STp->block_size - 1) / STp->block_size;
2961 transfer = OS_FRAME_SIZE;
2962
2963 if (offset < OS_DATA_SIZE)
2964 osst_zero_buffer_tail(STp->buffer);
2965
2966 if (STp->poll)
2967 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
2968 result = osst_recover_wait_frame(STp, aSRpnt, 1);
2969
2970 memset(cmd, 0, MAX_COMMAND_SIZE);
2971 cmd[0] = WRITE_6;
2972 cmd[1] = 1;
2973 cmd[4] = 1;
2974
2975 switch (STp->write_type) {
2976 case OS_WRITE_DATA:
2977 #if DEBUG
2978 if (debugging)
2979 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
2980 name, blks, STp->frame_seq_number,
2981 STp->logical_blk_num - blks, STp->logical_blk_num - 1);
2982 #endif
2983 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
2984 STp->logical_blk_num - blks, STp->block_size, blks);
2985 break;
2986 case OS_WRITE_EOD:
2987 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
2988 STp->logical_blk_num, 0, 0);
2989 break;
2990 case OS_WRITE_NEW_MARK:
2991 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
2992 STp->logical_blk_num++, 0, blks=1);
2993 break;
2994 case OS_WRITE_HEADER:
2995 osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
2996 break;
2997 default: /* probably FILLER */
2998 osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
2999 }
3000 #if DEBUG
3001 if (debugging)
3002 printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
3003 name, offset, transfer, blks);
3004 #endif
3005
3006 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3007 STp->timeout, MAX_RETRIES, 1);
3008 *aSRpnt = SRpnt;
3009 if (!SRpnt)
3010 return (-EBUSY);
3011
3012 if ((STp->buffer)->syscall_result != 0) {
3013 #if DEBUG
3014 printk(OSST_DEB_MSG
3015 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3016 name, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
3017 SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
3018 #endif
3019 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
3020 (SRpnt->sr_sense_buffer[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3021 (SRpnt->sr_sense_buffer[2] & 0x0f) == NO_SENSE) {
3022 STp->dirty = 0;
3023 (STp->buffer)->buffer_bytes = 0;
3024 result = (-ENOSPC);
3025 }
3026 else {
3027 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3028 printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3029 result = (-EIO);
3030 }
3031 }
3032 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
3033 }
3034 else {
3035 STp->first_frame_position++;
3036 STp->dirty = 0;
3037 (STp->buffer)->buffer_bytes = 0;
3038 }
3039 }
3040 #if DEBUG
3041 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3042 #endif
3043 return result;
3044 }
3045
3046
3047 /* Flush the tape buffer. The tape will be positioned correctly unless
3048 seek_next is true. */
3049 static int osst_flush_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt, int seek_next)
3050 {
3051 struct st_partstat * STps;
3052 int backspace = 0, result = 0;
3053 #if DEBUG
3054 char * name = tape_name(STp);
3055 #endif
3056
3057 /*
3058 * If there was a bus reset, block further access
3059 * to this device.
3060 */
3061 if( STp->pos_unknown)
3062 return (-EIO);
3063
3064 if (STp->ready != ST_READY)
3065 return 0;
3066
3067 STps = &(STp->ps[STp->partition]);
3068 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
3069 STp->write_type = OS_WRITE_DATA;
3070 return osst_flush_write_buffer(STp, aSRpnt);
3071 }
3072 if (STp->block_size == 0)
3073 return 0;
3074
3075 #if DEBUG
3076 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3077 #endif
3078
3079 if (!STp->can_bsr) {
3080 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3081 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3082 (STp->buffer)->buffer_bytes = 0;
3083 (STp->buffer)->read_pointer = 0;
3084 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3085 }
3086
3087 if (!seek_next) {
3088 if (STps->eof == ST_FM_HIT) {
3089 result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3090 if (!result)
3091 STps->eof = ST_NOEOF;
3092 else {
3093 if (STps->drv_file >= 0)
3094 STps->drv_file++;
3095 STps->drv_block = 0;
3096 }
3097 }
3098 if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3099 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3100 }
3101 else if (STps->eof == ST_FM_HIT) {
3102 if (STps->drv_file >= 0)
3103 STps->drv_file++;
3104 STps->drv_block = 0;
3105 STps->eof = ST_NOEOF;
3106 }
3107
3108 return result;
3109 }
3110
3111 static int osst_write_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int synchronous)
3112 {
3113 unsigned char cmd[MAX_COMMAND_SIZE];
3114 struct scsi_request * SRpnt;
3115 int blks;
3116 #if DEBUG
3117 char * name = tape_name(STp);
3118 #endif
3119
3120 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3121 #if DEBUG
3122 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3123 #endif
3124 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3125 return (-EIO);
3126 }
3127 /* error recovery may have bumped us past the header partition */
3128 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3129 #if DEBUG
3130 printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3131 #endif
3132 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3133 }
3134 }
3135
3136 if (STp->poll)
3137 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3138 if (osst_recover_wait_frame(STp, aSRpnt, 1))
3139 return (-EIO);
3140
3141 // osst_build_stats(STp, &SRpnt);
3142
3143 STp->ps[STp->partition].rw = ST_WRITING;
3144 STp->write_type = OS_WRITE_DATA;
3145
3146 memset(cmd, 0, MAX_COMMAND_SIZE);
3147 cmd[0] = WRITE_6;
3148 cmd[1] = 1;
3149 cmd[4] = 1; /* one frame at a time... */
3150 blks = STp->buffer->buffer_bytes / STp->block_size;
3151 #if DEBUG
3152 if (debugging)
3153 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3154 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3155 #endif
3156 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3157 STp->logical_blk_num - blks, STp->block_size, blks);
3158
3159 #if DEBUG
3160 if (!synchronous)
3161 STp->write_pending = 1;
3162 #endif
3163 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3164 MAX_RETRIES, synchronous);
3165 if (!SRpnt)
3166 return (-EBUSY);
3167 *aSRpnt = SRpnt;
3168
3169 if (synchronous) {
3170 if (STp->buffer->syscall_result != 0) {
3171 #if DEBUG
3172 if (debugging)
3173 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3174 #endif
3175 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
3176 (SRpnt->sr_sense_buffer[2] & 0x40)) {
3177 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
3178 return (-ENOSPC);
3179 }
3180 else {
3181 if (osst_write_error_recovery(STp, aSRpnt, 1))
3182 return (-EIO);
3183 }
3184 }
3185 else
3186 STp->first_frame_position++;
3187 }
3188
3189 STp->write_count++;
3190
3191 return 0;
3192 }
3193
3194 /* Lock or unlock the drive door. Don't use when struct scsi_request allocated. */
3195 static int do_door_lock(struct osst_tape * STp, int do_lock)
3196 {
3197 int retval, cmd;
3198
3199 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
3200 #if DEBUG
3201 printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3202 #endif
3203 retval = scsi_ioctl(STp->device, cmd, NULL);
3204 if (!retval) {
3205 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3206 }
3207 else {
3208 STp->door_locked = ST_LOCK_FAILS;
3209 }
3210 return retval;
3211 }
3212
3213 /* Set the internal state after reset */
3214 static void reset_state(struct osst_tape *STp)
3215 {
3216 int i;
3217 struct st_partstat *STps;
3218
3219 STp->pos_unknown = 0;
3220 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3221 STps = &(STp->ps[i]);
3222 STps->rw = ST_IDLE;
3223 STps->eof = ST_NOEOF;
3224 STps->at_sm = 0;
3225 STps->last_block_valid = 0;
3226 STps->drv_block = -1;
3227 STps->drv_file = -1;
3228 }
3229 }
3230
3231
3232 /* Entry points to osst */
3233
3234 /* Write command */
3235 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3236 {
3237 ssize_t total, retval = 0;
3238 ssize_t i, do_count, blks, transfer;
3239 int write_threshold;
3240 int doing_write = 0;
3241 const char __user * b_point;
3242 struct scsi_request * SRpnt = NULL;
3243 struct st_modedef * STm;
3244 struct st_partstat * STps;
3245 struct osst_tape * STp = filp->private_data;
3246 char * name = tape_name(STp);
3247
3248
3249 if (down_interruptible(&STp->lock))
3250 return (-ERESTARTSYS);
3251
3252 /*
3253 * If we are in the middle of error recovery, don't let anyone
3254 * else try and use this device. Also, if error recovery fails, it
3255 * may try and take the device offline, in which case all further
3256 * access to the device is prohibited.
3257 */
3258 if( !scsi_block_when_processing_errors(STp->device) ) {
3259 retval = (-ENXIO);
3260 goto out;
3261 }
3262
3263 if (STp->ready != ST_READY) {
3264 if (STp->ready == ST_NO_TAPE)
3265 retval = (-ENOMEDIUM);
3266 else
3267 retval = (-EIO);
3268 goto out;
3269 }
3270 STm = &(STp->modes[STp->current_mode]);
3271 if (!STm->defined) {
3272 retval = (-ENXIO);
3273 goto out;
3274 }
3275 if (count == 0)
3276 goto out;
3277
3278 /*
3279 * If there was a bus reset, block further access
3280 * to this device.
3281 */
3282 if (STp->pos_unknown) {
3283 retval = (-EIO);
3284 goto out;
3285 }
3286
3287 #if DEBUG
3288 if (!STp->in_use) {
3289 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3290 retval = (-EIO);
3291 goto out;
3292 }
3293 #endif
3294
3295 if (STp->write_prot) {
3296 retval = (-EACCES);
3297 goto out;
3298 }
3299
3300 /* Write must be integral number of blocks */
3301 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3302 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3303 name, count, STp->block_size<1024?
3304 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3305 retval = (-EINVAL);
3306 goto out;
3307 }
3308
3309 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3310 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3311 name, STp->first_frame_position);
3312 retval = (-ENOSPC);
3313 goto out;
3314 }
3315
3316 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3317 STp->door_locked = ST_LOCKED_AUTO;
3318
3319 STps = &(STp->ps[STp->partition]);
3320
3321 if (STps->rw == ST_READING) {
3322 #if DEBUG
3323 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3324 STps->drv_file, STps->drv_block);
3325 #endif
3326 retval = osst_flush_buffer(STp, &SRpnt, 0);
3327 if (retval)
3328 goto out;
3329 STps->rw = ST_IDLE;
3330 }
3331 if (STps->rw != ST_WRITING) {
3332 /* Are we totally rewriting this tape? */
3333 if (!STp->header_ok ||
3334 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3335 (STps->drv_file == 0 && STps->drv_block == 0)) {
3336 STp->wrt_pass_cntr++;
3337 #if DEBUG
3338 printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3339 name, STp->wrt_pass_cntr);
3340 #endif
3341 osst_reset_header(STp, &SRpnt);
3342 STps->drv_file = STps->drv_block = 0;
3343 }
3344 /* Do we know where we'll be writing on the tape? */
3345 else {
3346 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3347 STps->drv_file < 0 || STps->drv_block < 0) {
3348 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3349 STps->drv_file = STp->filemark_cnt;
3350 STps->drv_block = 0;
3351 }
3352 else {
3353 /* We have no idea where the tape is positioned - give up */
3354 #if DEBUG
3355 printk(OSST_DEB_MSG
3356 "%s:D: Cannot write at indeterminate position.\n", name);
3357 #endif
3358 retval = (-EIO);
3359 goto out;
3360 }
3361 }
3362 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3363 STp->filemark_cnt = STps->drv_file;
3364 STp->last_mark_ppos =
3365 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3366 printk(KERN_WARNING
3367 "%s:W: Overwriting file %d with old write pass counter %d\n",
3368 name, STps->drv_file, STp->wrt_pass_cntr);
3369 printk(KERN_WARNING
3370 "%s:W: may lead to stale data being accepted on reading back!\n",
3371 name);
3372 #if DEBUG
3373 printk(OSST_DEB_MSG
3374 "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3375 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3376 #endif
3377 }
3378 }
3379 STp->fast_open = 0;
3380 }
3381 if (!STp->header_ok) {
3382 #if DEBUG
3383 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3384 #endif
3385 retval = (-EIO);
3386 goto out;
3387 }
3388
3389 if ((STp->buffer)->writing) {
3390 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3391 osst_write_behind_check(STp);
3392 if ((STp->buffer)->syscall_result) {
3393 #if DEBUG
3394 if (debugging)
3395 printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3396 (STp->buffer)->midlevel_result);
3397 #endif
3398 if ((STp->buffer)->midlevel_result == INT_MAX)
3399 STps->eof = ST_EOM_OK;
3400 else
3401 STps->eof = ST_EOM_ERROR;
3402 }
3403 }
3404 if (STps->eof == ST_EOM_OK) {
3405 retval = (-ENOSPC);
3406 goto out;
3407 }
3408 else if (STps->eof == ST_EOM_ERROR) {
3409 retval = (-EIO);
3410 goto out;
3411 }
3412
3413 /* Check the buffer readability in cases where copy_user might catch
3414 the problems after some tape movement. */
3415 if ((copy_from_user(&i, buf, 1) != 0 ||
3416 copy_from_user(&i, buf + count - 1, 1) != 0)) {
3417 retval = (-EFAULT);
3418 goto out;
3419 }
3420
3421 if (!STm->do_buffer_writes) {
3422 write_threshold = 1;
3423 }
3424 else
3425 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3426 if (!STm->do_async_writes)
3427 write_threshold--;
3428
3429 total = count;
3430 #if DEBUG
3431 if (debugging)
3432 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3433 name, count, STps->drv_file, STps->drv_block,
3434 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3435 #endif
3436 b_point = buf;
3437 while ((STp->buffer)->buffer_bytes + count > write_threshold)
3438 {
3439 doing_write = 1;
3440 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3441 (STp->buffer)->buffer_bytes;
3442 if (do_count > count)
3443 do_count = count;
3444
3445 i = append_to_buffer(b_point, STp->buffer, do_count);
3446 if (i) {
3447 retval = i;
3448 goto out;
3449 }
3450
3451 blks = do_count / STp->block_size;
3452 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3453
3454 i = osst_write_frame(STp, &SRpnt, 1);
3455
3456 if (i == (-ENOSPC)) {
3457 transfer = STp->buffer->writing; /* FIXME -- check this logic */
3458 if (transfer <= do_count) {
3459 filp->f_pos += do_count - transfer;
3460 count -= do_count - transfer;
3461 if (STps->drv_block >= 0) {
3462 STps->drv_block += (do_count - transfer) / STp->block_size;
3463 }
3464 STps->eof = ST_EOM_OK;
3465 retval = (-ENOSPC); /* EOM within current request */
3466 #if DEBUG
3467 if (debugging)
3468 printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3469 name, transfer);
3470 #endif
3471 }
3472 else {
3473 STps->eof = ST_EOM_ERROR;
3474 STps->drv_block = (-1); /* Too cautious? */
3475 retval = (-EIO); /* EOM for old data */
3476 #if DEBUG
3477 if (debugging)
3478 printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3479 #endif
3480 }
3481 }
3482 else
3483 retval = i;
3484
3485 if (retval < 0) {
3486 if (SRpnt != NULL) {
3487 scsi_release_request(SRpnt);
3488 SRpnt = NULL;
3489 }
3490 STp->buffer->buffer_bytes = 0;
3491 STp->dirty = 0;
3492 if (count < total)
3493 retval = total - count;
3494 goto out;
3495 }
3496
3497 filp->f_pos += do_count;
3498 b_point += do_count;
3499 count -= do_count;
3500 if (STps->drv_block >= 0) {
3501 STps->drv_block += blks;
3502 }
3503 STp->buffer->buffer_bytes = 0;
3504 STp->dirty = 0;
3505 } /* end while write threshold exceeded */
3506
3507 if (count != 0) {
3508 STp->dirty = 1;
3509 i = append_to_buffer(b_point, STp->buffer, count);
3510 if (i) {
3511 retval = i;
3512 goto out;
3513 }
3514 blks = count / STp->block_size;
3515 STp->logical_blk_num += blks;
3516 if (STps->drv_block >= 0) {
3517 STps->drv_block += blks;
3518 }
3519 filp->f_pos += count;
3520 count = 0;
3521 }
3522
3523 if (doing_write && (STp->buffer)->syscall_result != 0) {
3524 retval = (STp->buffer)->syscall_result;
3525 goto out;
3526 }
3527
3528 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3529 /* Schedule an asynchronous write */
3530 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3531 STp->block_size) * STp->block_size;
3532 STp->dirty = !((STp->buffer)->writing ==
3533 (STp->buffer)->buffer_bytes);
3534
3535 i = osst_write_frame(STp, &SRpnt, 0);
3536 if (i < 0) {
3537 retval = (-EIO);
3538 goto out;
3539 }
3540 SRpnt = NULL; /* Prevent releasing this request! */
3541 }
3542 STps->at_sm &= (total == 0);
3543 if (total > 0)
3544 STps->eof = ST_NOEOF;
3545
3546 retval = total;
3547
3548 out:
3549 if (SRpnt != NULL) scsi_release_request(SRpnt);
3550
3551 up(&STp->lock);
3552
3553 return retval;
3554 }
3555
3556
3557 /* Read command */
3558 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3559 {
3560 ssize_t total, retval = 0;
3561 ssize_t i, transfer;
3562 int special;
3563 struct st_modedef * STm;
3564 struct st_partstat * STps;
3565 struct scsi_request * SRpnt = NULL;
3566 struct osst_tape * STp = filp->private_data;
3567 char * name = tape_name(STp);
3568
3569
3570 if (down_interruptible(&STp->lock))
3571 return (-ERESTARTSYS);
3572
3573 /*
3574 * If we are in the middle of error recovery, don't let anyone
3575 * else try and use this device. Also, if error recovery fails, it
3576 * may try and take the device offline, in which case all further
3577 * access to the device is prohibited.
3578 */
3579 if( !scsi_block_when_processing_errors(STp->device) ) {
3580 retval = (-ENXIO);
3581 goto out;
3582 }
3583
3584 if (STp->ready != ST_READY) {
3585 if (STp->ready == ST_NO_TAPE)
3586 retval = (-ENOMEDIUM);
3587 else
3588 retval = (-EIO);
3589 goto out;
3590 }
3591 STm = &(STp->modes[STp->current_mode]);
3592 if (!STm->defined) {
3593 retval = (-ENXIO);
3594 goto out;
3595 }
3596 #if DEBUG
3597 if (!STp->in_use) {
3598 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3599 retval = (-EIO);
3600 goto out;
3601 }
3602 #endif
3603 /* Must have initialized medium */
3604 if (!STp->header_ok) {
3605 retval = (-EIO);
3606 goto out;
3607 }
3608
3609 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3610 STp->door_locked = ST_LOCKED_AUTO;
3611
3612 STps = &(STp->ps[STp->partition]);
3613 if (STps->rw == ST_WRITING) {
3614 retval = osst_flush_buffer(STp, &SRpnt, 0);
3615 if (retval)
3616 goto out;
3617 STps->rw = ST_IDLE;
3618 /* FIXME -- this may leave the tape without EOD and up2date headers */
3619 }
3620
3621 if ((count % STp->block_size) != 0) {
3622 printk(KERN_WARNING
3623 "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3624 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3625 }
3626
3627 #if DEBUG
3628 if (debugging && STps->eof != ST_NOEOF)
3629 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3630 STps->eof, (STp->buffer)->buffer_bytes);
3631 #endif
3632 if ((STp->buffer)->buffer_bytes == 0 &&
3633 STps->eof >= ST_EOD_1) {
3634 if (STps->eof < ST_EOD) {
3635 STps->eof += 1;
3636 retval = 0;
3637 goto out;
3638 }
3639 retval = (-EIO); /* EOM or Blank Check */
3640 goto out;
3641 }
3642
3643 /* Check the buffer writability before any tape movement. Don't alter
3644 buffer data. */
3645 if (copy_from_user(&i, buf, 1) != 0 ||
3646 copy_to_user (buf, &i, 1) != 0 ||
3647 copy_from_user(&i, buf + count - 1, 1) != 0 ||
3648 copy_to_user (buf + count - 1, &i, 1) != 0) {
3649 retval = (-EFAULT);
3650 goto out;
3651 }
3652
3653 /* Loop until enough data in buffer or a special condition found */
3654 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3655
3656 /* Get new data if the buffer is empty */
3657 if ((STp->buffer)->buffer_bytes == 0) {
3658 if (STps->eof == ST_FM_HIT)
3659 break;
3660 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3661 if (special < 0) { /* No need to continue read */
3662 STp->frame_in_buffer = 0;
3663 retval = special;
3664 goto out;
3665 }
3666 }
3667
3668 /* Move the data from driver buffer to user buffer */
3669 if ((STp->buffer)->buffer_bytes > 0) {
3670 #if DEBUG
3671 if (debugging && STps->eof != ST_NOEOF)
3672 printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3673 STps->eof, (STp->buffer)->buffer_bytes, count - total);
3674 #endif
3675 /* force multiple of block size, note block_size may have been adjusted */
3676 transfer = (((STp->buffer)->buffer_bytes < count - total ?
3677 (STp->buffer)->buffer_bytes : count - total)/
3678 STp->block_size) * STp->block_size;
3679
3680 if (transfer == 0) {
3681 printk(KERN_WARNING
3682 "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
3683 name, count, STp->block_size < 1024?
3684 STp->block_size:STp->block_size/1024,
3685 STp->block_size<1024?'b':'k');
3686 break;
3687 }
3688 i = from_buffer(STp->buffer, buf, transfer);
3689 if (i) {
3690 retval = i;
3691 goto out;
3692 }
3693 STp->logical_blk_num += transfer / STp->block_size;
3694 STps->drv_block += transfer / STp->block_size;
3695 filp->f_pos += transfer;
3696 buf += transfer;
3697 total += transfer;
3698 }
3699
3700 if ((STp->buffer)->buffer_bytes == 0) {
3701 #if DEBUG
3702 if (debugging)
3703 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3704 name, STp->frame_seq_number);
3705 #endif
3706 STp->frame_in_buffer = 0;
3707 STp->frame_seq_number++; /* frame to look for next time */
3708 }
3709 } /* for (total = 0, special = 0; total < count && !special; ) */
3710
3711 /* Change the eof state if no data from tape or buffer */
3712 if (total == 0) {
3713 if (STps->eof == ST_FM_HIT) {
3714 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3715 STps->drv_block = 0;
3716 if (STps->drv_file >= 0)
3717 STps->drv_file++;
3718 }
3719 else if (STps->eof == ST_EOD_1) {
3720 STps->eof = ST_EOD_2;
3721 if (STps->drv_block > 0 && STps->drv_file >= 0)
3722 STps->drv_file++;
3723 STps->drv_block = 0;
3724 }
3725 else if (STps->eof == ST_EOD_2)
3726 STps->eof = ST_EOD;
3727 }
3728 else if (STps->eof == ST_FM)
3729 STps->eof = ST_NOEOF;
3730
3731 retval = total;
3732
3733 out:
3734 if (SRpnt != NULL) scsi_release_request(SRpnt);
3735
3736 up(&STp->lock);
3737
3738 return retval;
3739 }
3740
3741
3742 /* Set the driver options */
3743 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3744 {
3745 printk(KERN_INFO
3746 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3747 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3748 STm->do_read_ahead);
3749 printk(KERN_INFO
3750 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3751 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3752 printk(KERN_INFO
3753 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3754 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3755 STp->scsi2_logical);
3756 printk(KERN_INFO
3757 "%s:I: sysv: %d\n", name, STm->sysv);
3758 #if DEBUG
3759 printk(KERN_INFO
3760 "%s:D: debugging: %d\n",
3761 name, debugging);
3762 #endif
3763 }
3764
3765
3766 static int osst_set_options(struct osst_tape *STp, long options)
3767 {
3768 int value;
3769 long code;
3770 struct st_modedef * STm;
3771 char * name = tape_name(STp);
3772
3773 STm = &(STp->modes[STp->current_mode]);
3774 if (!STm->defined) {
3775 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3776 modes_defined = 1;
3777 #if DEBUG
3778 if (debugging)
3779 printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3780 name, STp->current_mode);
3781 #endif
3782 }
3783
3784 code = options & MT_ST_OPTIONS;
3785 if (code == MT_ST_BOOLEANS) {
3786 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3787 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3788 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3789 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3790 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3791 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3792 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3793 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3794 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3795 if ((STp->device)->scsi_level >= SCSI_2)
3796 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3797 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3798 STm->sysv = (options & MT_ST_SYSV) != 0;
3799 #if DEBUG
3800 debugging = (options & MT_ST_DEBUGGING) != 0;
3801 #endif
3802 osst_log_options(STp, STm, name);
3803 }
3804 else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3805 value = (code == MT_ST_SETBOOLEANS);
3806 if ((options & MT_ST_BUFFER_WRITES) != 0)
3807 STm->do_buffer_writes = value;
3808 if ((options & MT_ST_ASYNC_WRITES) != 0)
3809 STm->do_async_writes = value;
3810 if ((options & MT_ST_DEF_WRITES) != 0)
3811 STm->defaults_for_writes = value;
3812 if ((options & MT_ST_READ_AHEAD) != 0)
3813 STm->do_read_ahead = value;
3814 if ((options & MT_ST_TWO_FM) != 0)
3815 STp->two_fm = value;
3816 if ((options & MT_ST_FAST_MTEOM) != 0)
3817 STp->fast_mteom = value;
3818 if ((options & MT_ST_AUTO_LOCK) != 0)
3819 STp->do_auto_lock = value;
3820 if ((options & MT_ST_CAN_BSR) != 0)
3821 STp->can_bsr = value;
3822 if ((options & MT_ST_NO_BLKLIMS) != 0)
3823 STp->omit_blklims = value;
3824 if ((STp->device)->scsi_level >= SCSI_2 &&
3825 (options & MT_ST_CAN_PARTITIONS) != 0)
3826 STp->can_partitions = value;
3827 if ((options & MT_ST_SCSI2LOGICAL) != 0)
3828 STp->scsi2_logical = value;
3829 if ((options & MT_ST_SYSV) != 0)
3830 STm->sysv = value;
3831 #if DEBUG
3832 if ((options & MT_ST_DEBUGGING) != 0)
3833 debugging = value;
3834 #endif
3835 osst_log_options(STp, STm, name);
3836 }
3837 else if (code == MT_ST_WRITE_THRESHOLD) {
3838 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3839 if (value < 1 || value > osst_buffer_size) {
3840 printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3841 name, value);
3842 return (-EIO);
3843 }
3844 STp->write_threshold = value;
3845 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3846 name, value);
3847 }
3848 else if (code == MT_ST_DEF_BLKSIZE) {
3849 value = (options & ~MT_ST_OPTIONS);
3850 if (value == ~MT_ST_OPTIONS) {
3851 STm->default_blksize = (-1);
3852 printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3853 }
3854 else {
3855 if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3856 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3857 name, value);
3858 return (-EINVAL);
3859 }
3860 STm->default_blksize = value;
3861 printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
3862 name, STm->default_blksize);
3863 }
3864 }
3865 else if (code == MT_ST_TIMEOUTS) {
3866 value = (options & ~MT_ST_OPTIONS);
3867 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
3868 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
3869 printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
3870 (value & ~MT_ST_SET_LONG_TIMEOUT));
3871 }
3872 else {
3873 STp->timeout = value * HZ;
3874 printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
3875 }
3876 }
3877 else if (code == MT_ST_DEF_OPTIONS) {
3878 code = (options & ~MT_ST_CLEAR_DEFAULT);
3879 value = (options & MT_ST_CLEAR_DEFAULT);
3880 if (code == MT_ST_DEF_DENSITY) {
3881 if (value == MT_ST_CLEAR_DEFAULT) {
3882 STm->default_density = (-1);
3883 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
3884 }
3885 else {
3886 STm->default_density = value & 0xff;
3887 printk(KERN_INFO "%s:I: Density default set to %x\n",
3888 name, STm->default_density);
3889 }
3890 }
3891 else if (code == MT_ST_DEF_DRVBUFFER) {
3892 if (value == MT_ST_CLEAR_DEFAULT) {
3893 STp->default_drvbuffer = 0xff;
3894 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
3895 }
3896 else {
3897 STp->default_drvbuffer = value & 7;
3898 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
3899 name, STp->default_drvbuffer);
3900 }
3901 }
3902 else if (code == MT_ST_DEF_COMPRESSION) {
3903 if (value == MT_ST_CLEAR_DEFAULT) {
3904 STm->default_compression = ST_DONT_TOUCH;
3905 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
3906 }
3907 else {
3908 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
3909 printk(KERN_INFO "%s:I: Compression default set to %x\n",
3910 name, (value & 1));
3911 }
3912 }
3913 }
3914 else
3915 return (-EIO);
3916
3917 return 0;
3918 }
3919
3920
3921 /* Internal ioctl function */
3922 static int osst_int_ioctl(struct osst_tape * STp, struct scsi_request ** aSRpnt,
3923 unsigned int cmd_in, unsigned long arg)
3924 {
3925 int timeout;
3926 long ltmp;
3927 int i, ioctl_result;
3928 int chg_eof = 1;
3929 unsigned char cmd[MAX_COMMAND_SIZE];
3930 struct scsi_request * SRpnt = * aSRpnt;
3931 struct st_partstat * STps;
3932 int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
3933 int datalen = 0, direction = DMA_NONE;
3934 char * name = tape_name(STp);
3935
3936 if (STp->ready != ST_READY && cmd_in != MTLOAD) {
3937 if (STp->ready == ST_NO_TAPE)
3938 return (-ENOMEDIUM);
3939 else
3940 return (-EIO);
3941 }
3942 timeout = STp->long_timeout;
3943 STps = &(STp->ps[STp->partition]);
3944 fileno = STps->drv_file;
3945 blkno = STps->drv_block;
3946 at_sm = STps->at_sm;
3947 frame_seq_numbr = STp->frame_seq_number;
3948 logical_blk_num = STp->logical_blk_num;
3949
3950 memset(cmd, 0, MAX_COMMAND_SIZE);
3951 switch (cmd_in) {
3952 case MTFSFM:
3953 chg_eof = 0; /* Changed from the FSF after this */
3954 case MTFSF:
3955 if (STp->raw)
3956 return (-EIO);
3957 if (STp->linux_media)
3958 ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
3959 else
3960 ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
3961 if (fileno >= 0)
3962 fileno += arg;
3963 blkno = 0;
3964 at_sm &= (arg == 0);
3965 goto os_bypass;
3966
3967 case MTBSF:
3968 chg_eof = 0; /* Changed from the FSF after this */
3969 case MTBSFM:
3970 if (STp->raw)
3971 return (-EIO);
3972 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
3973 if (fileno >= 0)
3974 fileno -= arg;
3975 blkno = (-1); /* We can't know the block number */
3976 at_sm &= (arg == 0);
3977 goto os_bypass;
3978
3979 case MTFSR:
3980 case MTBSR:
3981 #if DEBUG
3982 if (debugging)
3983 printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
3984 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
3985 #endif
3986 if (cmd_in == MTFSR) {
3987 logical_blk_num += arg;
3988 if (blkno >= 0) blkno += arg;
3989 }
3990 else {
3991 logical_blk_num -= arg;
3992 if (blkno >= 0) blkno -= arg;
3993 }
3994 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
3995 fileno = STps->drv_file;
3996 blkno = STps->drv_block;
3997 at_sm &= (arg == 0);
3998 goto os_bypass;
3999
4000 case MTFSS:
4001 cmd[0] = SPACE;
4002 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4003 cmd[2] = (arg >> 16);
4004 cmd[3] = (arg >> 8);
4005 cmd[4] = arg;
4006 #if DEBUG
4007 if (debugging)
4008 printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4009 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4010 #endif
4011 if (arg != 0) {
4012 blkno = fileno = (-1);
4013 at_sm = 1;
4014 }
4015 break;
4016 case MTBSS:
4017 cmd[0] = SPACE;
4018 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4019 ltmp = (-arg);
4020 cmd[2] = (ltmp >> 16);
4021 cmd[3] = (ltmp >> 8);
4022 cmd[4] = ltmp;
4023 #if DEBUG
4024 if (debugging) {
4025 if (cmd[2] & 0x80)
4026 ltmp = 0xff000000;
4027 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4028 printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4029 name, (-ltmp));
4030 }
4031 #endif
4032 if (arg != 0) {
4033 blkno = fileno = (-1);
4034 at_sm = 1;
4035 }
4036 break;
4037 case MTWEOF:
4038 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4039 STp->write_type = OS_WRITE_DATA;
4040 ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4041 } else
4042 ioctl_result = 0;
4043 #if DEBUG
4044 if (debugging)
4045 printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4046 #endif
4047 for (i=0; i<arg; i++)
4048 ioctl_result |= osst_write_filemark(STp, &SRpnt);
4049 if (fileno >= 0) fileno += arg;
4050 if (blkno >= 0) blkno = 0;
4051 goto os_bypass;
4052
4053 case MTWSM:
4054 if (STp->write_prot)
4055 return (-EACCES);
4056 if (!STp->raw)
4057 return 0;
4058 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
4059 if (cmd_in == MTWSM)
4060 cmd[1] = 2;
4061 cmd[2] = (arg >> 16);
4062 cmd[3] = (arg >> 8);
4063 cmd[4] = arg;
4064 timeout = STp->timeout;
4065 #if DEBUG
4066 if (debugging)
4067 printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4068 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4069 #endif
4070 if (fileno >= 0)
4071 fileno += arg;
4072 blkno = 0;
4073 at_sm = (cmd_in == MTWSM);
4074 break;
4075 case MTOFFL:
4076 case MTLOAD:
4077 case MTUNLOAD:
4078 case MTRETEN:
4079 cmd[0] = START_STOP;
4080 cmd[1] = 1; /* Don't wait for completion */
4081 if (cmd_in == MTLOAD) {
4082 if (STp->ready == ST_NO_TAPE)
4083 cmd[4] = 4; /* open tray */
4084 else
4085 cmd[4] = 1; /* load */
4086 }
4087 if (cmd_in == MTRETEN)
4088 cmd[4] = 3; /* retension then mount */
4089 if (cmd_in == MTOFFL)
4090 cmd[4] = 4; /* rewind then eject */
4091 timeout = STp->timeout;
4092 #if DEBUG
4093 if (debugging) {
4094 switch (cmd_in) {
4095 case MTUNLOAD:
4096 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4097 break;
4098 case MTLOAD:
4099 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4100 break;
4101 case MTRETEN:
4102 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4103 break;
4104 case MTOFFL:
4105 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4106 break;
4107 }
4108 }
4109 #endif
4110 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4111 break;
4112 case MTNOP:
4113 #if DEBUG
4114 if (debugging)
4115 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4116 #endif
4117 return 0; /* Should do something ? */
4118 break;
4119 case MTEOM:
4120 #if DEBUG
4121 if (debugging)
4122 printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4123 #endif
4124 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4125 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4126 ioctl_result = -EIO;
4127 goto os_bypass;
4128 }
4129 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4130 #if DEBUG
4131 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4132 #endif
4133 ioctl_result = -EIO;
4134 goto os_bypass;
4135 }
4136 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4137 fileno = STp->filemark_cnt;
4138 blkno = at_sm = 0;
4139 goto os_bypass;
4140
4141 case MTERASE:
4142 if (STp->write_prot)
4143 return (-EACCES);
4144 ioctl_result = osst_reset_header(STp, &SRpnt);
4145 i = osst_write_eod(STp, &SRpnt);
4146 if (i < ioctl_result) ioctl_result = i;
4147 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4148 if (i < ioctl_result) ioctl_result = i;
4149 fileno = blkno = at_sm = 0 ;
4150 goto os_bypass;
4151
4152 case MTREW:
4153 cmd[0] = REZERO_UNIT; /* rewind */
4154 cmd[1] = 1;
4155 #if DEBUG
4156 if (debugging)
4157 printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4158 #endif
4159 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4160 break;
4161
4162 case MTSETBLK: /* Set block length */
4163 if ((STps->drv_block == 0 ) &&
4164 !STp->dirty &&
4165 ((STp->buffer)->buffer_bytes == 0) &&
4166 ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4167 ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4168 !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4169 /*
4170 * Only allowed to change the block size if you opened the
4171 * device at the beginning of a file before writing anything.
4172 * Note, that when reading, changing block_size is futile,
4173 * as the size used when writing overrides it.
4174 */
4175 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4176 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4177 name, STp->block_size);
4178 return 0;
4179 }
4180 case MTSETDENSITY: /* Set tape density */
4181 case MTSETDRVBUFFER: /* Set drive buffering */
4182 case SET_DENS_AND_BLK: /* Set density and block size */
4183 chg_eof = 0;
4184 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4185 return (-EIO); /* Not allowed if data in buffer */
4186 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4187 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4188 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4189 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4190 name, (int)(arg & MT_ST_BLKSIZE_MASK),
4191 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4192 return (-EINVAL);
4193 }
4194 return 0; /* FIXME silently ignore if block size didn't change */
4195
4196 default:
4197 return (-ENOSYS);
4198 }
4199
4200 SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4201
4202 ioctl_result = (STp->buffer)->syscall_result;
4203
4204 if (!SRpnt) {
4205 #if DEBUG
4206 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4207 #endif
4208 return ioctl_result;
4209 }
4210
4211 if (!ioctl_result) { /* SCSI command successful */
4212 STp->frame_seq_number = frame_seq_numbr;
4213 STp->logical_blk_num = logical_blk_num;
4214 }
4215
4216 os_bypass:
4217 #if DEBUG
4218 if (debugging)
4219 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4220 #endif
4221
4222 if (!ioctl_result) { /* success */
4223
4224 if (cmd_in == MTFSFM) {
4225 fileno--;
4226 blkno--;
4227 }
4228 if (cmd_in == MTBSFM) {
4229 fileno++;
4230 blkno++;
4231 }
4232 STps->drv_block = blkno;
4233 STps->drv_file = fileno;
4234 STps->at_sm = at_sm;
4235
4236 if (cmd_in == MTEOM)
4237 STps->eof = ST_EOD;
4238 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4239 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4240 STps->drv_block++;
4241 STp->logical_blk_num++;
4242 STp->frame_seq_number++;
4243 STp->frame_in_buffer = 0;
4244 STp->buffer->read_pointer = 0;
4245 }
4246 else if (cmd_in == MTFSF)
4247 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4248 else if (chg_eof)
4249 STps->eof = ST_NOEOF;
4250
4251 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4252 STp->rew_at_close = 0;
4253 else if (cmd_in == MTLOAD) {
4254 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4255 STp->ps[i].rw = ST_IDLE;
4256 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4257 }
4258 STp->partition = 0;
4259 }
4260
4261 if (cmd_in == MTREW) {
4262 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4263 if (ioctl_result > 0)
4264 ioctl_result = 0;
4265 }
4266
4267 } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4268 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4269 STps->drv_file = STps->drv_block = -1;
4270 else
4271 STps->drv_file = STps->drv_block = 0;
4272 STps->eof = ST_NOEOF;
4273 } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4274 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4275 STps->drv_file = STps->drv_block = -1;
4276 else {
4277 STps->drv_file = STp->filemark_cnt;
4278 STps->drv_block = 0;
4279 }
4280 STps->eof = ST_EOD;
4281 } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4282 STps->drv_file = STps->drv_block = (-1);
4283 STps->eof = ST_NOEOF;
4284 STp->header_ok = 0;
4285 } else if (cmd_in == MTERASE) {
4286 STp->header_ok = 0;
4287 } else if (SRpnt) { /* SCSI command was not completely successful. */
4288 if (SRpnt->sr_sense_buffer[2] & 0x40) {
4289 STps->eof = ST_EOM_OK;
4290 STps->drv_block = 0;
4291 }
4292 if (chg_eof)
4293 STps->eof = ST_NOEOF;
4294
4295 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == BLANK_CHECK)
4296 STps->eof = ST_EOD;
4297
4298 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4299 ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4300 }
4301 *aSRpnt = SRpnt;
4302
4303 return ioctl_result;
4304 }
4305
4306
4307 /* Open the device */
4308 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4309 {
4310 unsigned short flags;
4311 int i, b_size, new_session = 0, retval = 0;
4312 unsigned char cmd[MAX_COMMAND_SIZE];
4313 struct scsi_request * SRpnt = NULL;
4314 struct osst_tape * STp;
4315 struct st_modedef * STm;
4316 struct st_partstat * STps;
4317 char * name;
4318 int dev = TAPE_NR(inode);
4319 int mode = TAPE_MODE(inode);
4320
4321 nonseekable_open(inode, filp);
4322 write_lock(&os_scsi_tapes_lock);
4323 if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4324 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4325 write_unlock(&os_scsi_tapes_lock);
4326 return (-ENXIO);
4327 }
4328
4329 name = tape_name(STp);
4330
4331 if (STp->in_use) {
4332 write_unlock(&os_scsi_tapes_lock);
4333 #if DEBUG
4334 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4335 #endif
4336 return (-EBUSY);
4337 }
4338 if (scsi_device_get(STp->device)) {
4339 write_unlock(&os_scsi_tapes_lock);
4340 #if DEBUG
4341 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4342 #endif
4343 return (-ENXIO);
4344 }
4345 filp->private_data = STp;
4346 STp->in_use = 1;
4347 write_unlock(&os_scsi_tapes_lock);
4348 STp->rew_at_close = TAPE_REWIND(inode);
4349
4350 if( !scsi_block_when_processing_errors(STp->device) ) {
4351 return -ENXIO;
4352 }
4353
4354 if (mode != STp->current_mode) {
4355 #if DEBUG
4356 if (debugging)
4357 printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4358 name, STp->current_mode, mode);
4359 #endif
4360 new_session = 1;
4361 STp->current_mode = mode;
4362 }
4363 STm = &(STp->modes[STp->current_mode]);
4364
4365 flags = filp->f_flags;
4366 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4367
4368 STp->raw = TAPE_IS_RAW(inode);
4369 if (STp->raw)
4370 STp->header_ok = 0;
4371
4372 /* Allocate data segments for this device's tape buffer */
4373 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4374 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4375 retval = (-EOVERFLOW);
4376 goto err_out;
4377 }
4378 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4379 for (i = 0, b_size = 0;
4380 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4381 b_size += STp->buffer->sg[i++].length);
4382 STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
4383 #if DEBUG
4384 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4385 STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4386 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4387 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4388 #endif
4389 } else {
4390 STp->buffer->aux = NULL; /* this had better never happen! */
4391 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4392 retval = (-EIO);
4393 goto err_out;
4394 }
4395 STp->buffer->writing = 0;
4396 STp->buffer->syscall_result = 0;
4397 STp->dirty = 0;
4398 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4399 STps = &(STp->ps[i]);
4400 STps->rw = ST_IDLE;
4401 }
4402 STp->ready = ST_READY;
4403 #if DEBUG
4404 STp->nbr_waits = STp->nbr_finished = 0;
4405 #endif
4406
4407 memset (cmd, 0, MAX_COMMAND_SIZE);
4408 cmd[0] = TEST_UNIT_READY;
4409
4410 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4411 if (!SRpnt) {
4412 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
4413 goto err_out;
4414 }
4415 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4416 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
4417 SRpnt->sr_sense_buffer[12] == 4 ) {
4418 #if DEBUG
4419 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sr_sense_buffer[13]);
4420 #endif
4421 if (filp->f_flags & O_NONBLOCK) {
4422 retval = -EAGAIN;
4423 goto err_out;
4424 }
4425 if (SRpnt->sr_sense_buffer[13] == 2) { /* initialize command required (LOAD) */
4426 memset (cmd, 0, MAX_COMMAND_SIZE);
4427 cmd[0] = START_STOP;
4428 cmd[1] = 1;
4429 cmd[4] = 1;
4430 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4431 STp->timeout, MAX_RETRIES, 1);
4432 }
4433 osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0);
4434 }
4435 if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4436 (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4437 #if DEBUG
4438 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4439 #endif
4440 STp->header_ok = 0;
4441
4442 for (i=0; i < 10; i++) {
4443
4444 memset (cmd, 0, MAX_COMMAND_SIZE);
4445 cmd[0] = TEST_UNIT_READY;
4446
4447 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4448 STp->timeout, MAX_RETRIES, 1);
4449 if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
4450 (SRpnt->sr_sense_buffer[2] & 0x0f) != UNIT_ATTENTION)
4451 break;
4452 }
4453
4454 STp->pos_unknown = 0;
4455 STp->partition = STp->new_partition = 0;
4456 if (STp->can_partitions)
4457 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4458 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4459 STps = &(STp->ps[i]);
4460 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4461 STps->eof = ST_NOEOF;
4462 STps->at_sm = 0;
4463 STps->last_block_valid = 0;
4464 STps->drv_block = 0;
4465 STps->drv_file = 0 ;
4466 }
4467 new_session = 1;
4468 STp->recover_count = 0;
4469 STp->abort_count = 0;
4470 }
4471 /*
4472 * if we have valid headers from before, and the drive/tape seem untouched,
4473 * open without reconfiguring and re-reading the headers
4474 */
4475 if (!STp->buffer->syscall_result && STp->header_ok &&
4476 !SRpnt->sr_result && SRpnt->sr_sense_buffer[0] == 0) {
4477
4478 memset(cmd, 0, MAX_COMMAND_SIZE);
4479 cmd[0] = MODE_SENSE;
4480 cmd[1] = 8;
4481 cmd[2] = VENDOR_IDENT_PAGE;
4482 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4483
4484 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4485
4486 if (STp->buffer->syscall_result ||
4487 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4488 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4489 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4490 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4491 #if DEBUG
4492 printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4493 STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4494 STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4495 STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4496 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4497 #endif
4498 STp->header_ok = 0;
4499 }
4500 i = STp->first_frame_position;
4501 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4502 if (STp->door_locked == ST_UNLOCKED) {
4503 if (do_door_lock(STp, 1))
4504 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4505 else
4506 STp->door_locked = ST_LOCKED_AUTO;
4507 }
4508 if (!STp->frame_in_buffer) {
4509 STp->block_size = (STm->default_blksize > 0) ?
4510 STm->default_blksize : OS_DATA_SIZE;
4511 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4512 }
4513 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4514 STp->fast_open = 1;
4515 scsi_release_request(SRpnt);
4516 return 0;
4517 }
4518 #if DEBUG
4519 if (i != STp->first_frame_position)
4520 printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4521 name, i, STp->first_frame_position);
4522 #endif
4523 STp->header_ok = 0;
4524 }
4525 STp->fast_open = 0;
4526
4527 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4528 (SRpnt->sr_sense_buffer[2] != 2 || SRpnt->sr_sense_buffer[12] != 0x3A) ) {
4529
4530 memset(cmd, 0, MAX_COMMAND_SIZE);
4531 cmd[0] = MODE_SELECT;
4532 cmd[1] = 0x10;
4533 cmd[4] = 4 + MODE_HEADER_LENGTH;
4534
4535 (STp->buffer)->b_data[0] = cmd[4] - 1;
4536 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4537 (STp->buffer)->b_data[2] = 0; /* Reserved */
4538 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4539 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4540 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4541 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4542 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4543
4544 #if DEBUG
4545 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4546 #endif
4547 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4548
4549 STp->header_ok = 0;
4550
4551 for (i=0; i < 10; i++) {
4552
4553 memset (cmd, 0, MAX_COMMAND_SIZE);
4554 cmd[0] = TEST_UNIT_READY;
4555
4556 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4557 STp->timeout, MAX_RETRIES, 1);
4558 if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
4559 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY)
4560 break;
4561
4562 if ((SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) {
4563 STp->pos_unknown = 0;
4564 STp->partition = STp->new_partition = 0;
4565 if (STp->can_partitions)
4566 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4567 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4568 STps = &(STp->ps[i]);
4569 STps->rw = ST_IDLE;
4570 STps->eof = ST_NOEOF;
4571 STps->at_sm = 0;
4572 STps->last_block_valid = 0;
4573 STps->drv_block = 0;
4574 STps->drv_file = 0 ;
4575 }
4576 new_session = 1;
4577 }
4578 }
4579 }
4580
4581 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4582 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4583
4584 if ((STp->buffer)->syscall_result != 0) {
4585 if ((STp->device)->scsi_level >= SCSI_2 &&
4586 (SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
4587 (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
4588 SRpnt->sr_sense_buffer[12] == 0x3a) { /* Check ASC */
4589 STp->ready = ST_NO_TAPE;
4590 } else
4591 STp->ready = ST_NOT_READY;
4592 scsi_release_request(SRpnt);
4593 SRpnt = NULL;
4594 STp->density = 0; /* Clear the erroneous "residue" */
4595 STp->write_prot = 0;
4596 STp->block_size = 0;
4597 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4598 STp->partition = STp->new_partition = 0;
4599 STp->door_locked = ST_UNLOCKED;
4600 return 0;
4601 }
4602
4603 osst_configure_onstream(STp, &SRpnt);
4604
4605 STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4606 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4607 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4608 STp->buffer->buffer_bytes =
4609 STp->buffer->read_pointer =
4610 STp->frame_in_buffer = 0;
4611
4612 #if DEBUG
4613 if (debugging)
4614 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4615 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4616 (STp->buffer)->buffer_blocks);
4617 #endif
4618
4619 if (STp->drv_write_prot) {
4620 STp->write_prot = 1;
4621 #if DEBUG
4622 if (debugging)
4623 printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4624 #endif
4625 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4626 retval = (-EROFS);
4627 goto err_out;
4628 }
4629 }
4630
4631 if (new_session) { /* Change the drive parameters for the new mode */
4632 #if DEBUG
4633 if (debugging)
4634 printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4635 #endif
4636 STp->density_changed = STp->blksize_changed = 0;
4637 STp->compression_changed = 0;
4638 }
4639
4640 /*
4641 * properly position the tape and check the ADR headers
4642 */
4643 if (STp->door_locked == ST_UNLOCKED) {
4644 if (do_door_lock(STp, 1))
4645 printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4646 else
4647 STp->door_locked = ST_LOCKED_AUTO;
4648 }
4649
4650 osst_analyze_headers(STp, &SRpnt);
4651
4652 scsi_release_request(SRpnt);
4653 SRpnt = NULL;
4654
4655 return 0;
4656
4657 err_out:
4658 if (SRpnt != NULL)
4659 scsi_release_request(SRpnt);
4660 normalize_buffer(STp->buffer);
4661 STp->header_ok = 0;
4662 STp->in_use = 0;
4663 scsi_device_put(STp->device);
4664
4665 return retval;
4666 }
4667
4668
4669 /* Flush the tape buffer before close */
4670 static int os_scsi_tape_flush(struct file * filp)
4671 {
4672 int result = 0, result2;
4673 struct osst_tape * STp = filp->private_data;
4674 struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4675 struct st_partstat * STps = &(STp->ps[STp->partition]);
4676 struct scsi_request * SRpnt = NULL;
4677 char * name = tape_name(STp);
4678
4679 if (file_count(filp) > 1)
4680 return 0;
4681
4682 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4683 STp->write_type = OS_WRITE_DATA;
4684 result = osst_flush_write_buffer(STp, &SRpnt);
4685 if (result != 0 && result != (-ENOSPC))
4686 goto out;
4687 }
4688 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4689
4690 #if DEBUG
4691 if (debugging) {
4692 printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4693 name, (long)(filp->f_pos));
4694 printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4695 name, STp->nbr_waits, STp->nbr_finished);
4696 }
4697 #endif
4698 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4699 #if DEBUG
4700 if (debugging)
4701 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4702 name, 1+STp->two_fm);
4703 #endif
4704 }
4705 else if (!STp->rew_at_close) {
4706 STps = &(STp->ps[STp->partition]);
4707 if (!STm->sysv || STps->rw != ST_READING) {
4708 if (STp->can_bsr)
4709 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4710 else if (STps->eof == ST_FM_HIT) {
4711 result = cross_eof(STp, &SRpnt, 0);
4712 if (result) {
4713 if (STps->drv_file >= 0)
4714 STps->drv_file++;
4715 STps->drv_block = 0;
4716 STps->eof = ST_FM;
4717 }
4718 else
4719 STps->eof = ST_NOEOF;
4720 }
4721 }
4722 else if ((STps->eof == ST_NOEOF &&
4723 !(result = cross_eof(STp, &SRpnt, 1))) ||
4724 STps->eof == ST_FM_HIT) {
4725 if (STps->drv_file >= 0)
4726 STps->drv_file++;
4727 STps->drv_block = 0;
4728 STps->eof = ST_FM;
4729 }
4730 }
4731
4732 out:
4733 if (STp->rew_at_close) {
4734 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4735 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4736 if (result == 0 && result2 < 0)
4737 result = result2;
4738 }
4739 if (SRpnt) scsi_release_request(SRpnt);
4740
4741 if (STp->abort_count || STp->recover_count) {
4742 printk(KERN_INFO "%s:I:", name);
4743 if (STp->abort_count)
4744 printk(" %d unrecovered errors", STp->abort_count);
4745 if (STp->recover_count)
4746 printk(" %d recovered errors", STp->recover_count);
4747 if (STp->write_count)
4748 printk(" in %d frames written", STp->write_count);
4749 if (STp->read_count)
4750 printk(" in %d frames read", STp->read_count);
4751 printk("\n");
4752 STp->recover_count = 0;
4753 STp->abort_count = 0;
4754 }
4755 STp->write_count = 0;
4756 STp->read_count = 0;
4757
4758 return result;
4759 }
4760
4761
4762 /* Close the device and release it */
4763 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4764 {
4765 int result = 0;
4766 struct osst_tape * STp = filp->private_data;
4767 struct scsi_request * SRpnt = NULL;
4768
4769 if (SRpnt) scsi_release_request(SRpnt);
4770
4771 if (STp->door_locked == ST_LOCKED_AUTO)
4772 do_door_lock(STp, 0);
4773
4774 if (STp->raw)
4775 STp->header_ok = 0;
4776
4777 normalize_buffer(STp->buffer);
4778 write_lock(&os_scsi_tapes_lock);
4779 STp->in_use = 0;
4780 write_unlock(&os_scsi_tapes_lock);
4781
4782 scsi_device_put(STp->device);
4783
4784 return result;
4785 }
4786
4787
4788 /* The ioctl command */
4789 static int osst_ioctl(struct inode * inode,struct file * file,
4790 unsigned int cmd_in, unsigned long arg)
4791 {
4792 int i, cmd_nr, cmd_type, retval = 0;
4793 unsigned int blk;
4794 struct st_modedef * STm;
4795 struct st_partstat * STps;
4796 struct scsi_request * SRpnt = NULL;
4797 struct osst_tape * STp = file->private_data;
4798 char * name = tape_name(STp);
4799 void __user * p = (void __user *)arg;
4800
4801 if (down_interruptible(&STp->lock))
4802 return -ERESTARTSYS;
4803
4804 #if DEBUG
4805 if (debugging && !STp->in_use) {
4806 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4807 retval = (-EIO);
4808 goto out;
4809 }
4810 #endif
4811 STm = &(STp->modes[STp->current_mode]);
4812 STps = &(STp->ps[STp->partition]);
4813
4814 /*
4815 * If we are in the middle of error recovery, don't let anyone
4816 * else try and use this device. Also, if error recovery fails, it
4817 * may try and take the device offline, in which case all further
4818 * access to the device is prohibited.
4819 */
4820 if( !scsi_block_when_processing_errors(STp->device) ) {
4821 retval = (-ENXIO);
4822 goto out;
4823 }
4824
4825 cmd_type = _IOC_TYPE(cmd_in);
4826 cmd_nr = _IOC_NR(cmd_in);
4827 #if DEBUG
4828 printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4829 cmd_type, cmd_nr, STp->raw?"raw":"normal");
4830 #endif
4831 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4832 struct mtop mtc;
4833 int auto_weof = 0;
4834
4835 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
4836 retval = (-EINVAL);
4837 goto out;
4838 }
4839
4840 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
4841 if (i) {
4842 retval = (-EFAULT);
4843 goto out;
4844 }
4845
4846 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
4847 printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
4848 retval = (-EPERM);
4849 goto out;
4850 }
4851
4852 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
4853 retval = (-ENXIO);
4854 goto out;
4855 }
4856
4857 if (!STp->pos_unknown) {
4858
4859 if (STps->eof == ST_FM_HIT) {
4860 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
4861 mtc.mt_count -= 1;
4862 if (STps->drv_file >= 0)
4863 STps->drv_file += 1;
4864 }
4865 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
4866 mtc.mt_count += 1;
4867 if (STps->drv_file >= 0)
4868 STps->drv_file += 1;
4869 }
4870 }
4871
4872 if (mtc.mt_op == MTSEEK) {
4873 /* Old position must be restored if partition will be changed */
4874 i = !STp->can_partitions || (STp->new_partition != STp->partition);
4875 }
4876 else {
4877 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
4878 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
4879 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
4880 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
4881 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
4882 mtc.mt_op == MTCOMPRESSION;
4883 }
4884 i = osst_flush_buffer(STp, &SRpnt, i);
4885 if (i < 0) {
4886 retval = i;
4887 goto out;
4888 }
4889 }
4890 else {
4891 /*
4892 * If there was a bus reset, block further access
4893 * to this device. If the user wants to rewind the tape,
4894 * then reset the flag and allow access again.
4895 */
4896 if(mtc.mt_op != MTREW &&
4897 mtc.mt_op != MTOFFL &&
4898 mtc.mt_op != MTRETEN &&
4899 mtc.mt_op != MTERASE &&
4900 mtc.mt_op != MTSEEK &&
4901 mtc.mt_op != MTEOM) {
4902 retval = (-EIO);
4903 goto out;
4904 }
4905 reset_state(STp);
4906 /* remove this when the midlevel properly clears was_reset */
4907 STp->device->was_reset = 0;
4908 }
4909
4910 if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK &&
4911 mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
4912 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER &&
4913 mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART &&
4914 mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) {
4915
4916 /*
4917 * The user tells us to move to another position on the tape.
4918 * If we were appending to the tape content, that would leave
4919 * the tape without proper end, in that case write EOD and
4920 * update the header to reflect its position.
4921 */
4922 #if DEBUG
4923 printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
4924 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
4925 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
4926 STp->logical_blk_num, STps->drv_file, STps->drv_block );
4927 #endif
4928 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
4929 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
4930 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4931 i = osst_write_trailer(STp, &SRpnt,
4932 !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
4933 #if DEBUG
4934 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
4935 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
4936 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
4937 #endif
4938 if (i < 0) {
4939 retval = i;
4940 goto out;
4941 }
4942 }
4943 STps->rw = ST_IDLE;
4944 }
4945
4946 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
4947 do_door_lock(STp, 0); /* Ignore result! */
4948
4949 if (mtc.mt_op == MTSETDRVBUFFER &&
4950 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
4951 retval = osst_set_options(STp, mtc.mt_count);
4952 goto out;
4953 }
4954
4955 if (mtc.mt_op == MTSETPART) {
4956 if (mtc.mt_count >= STp->nbr_partitions)
4957 retval = -EINVAL;
4958 else {
4959 STp->new_partition = mtc.mt_count;
4960 retval = 0;
4961 }
4962 goto out;
4963 }
4964
4965 if (mtc.mt_op == MTMKPART) {
4966 if (!STp->can_partitions) {
4967 retval = (-EINVAL);
4968 goto out;
4969 }
4970 if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
4971 (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
4972 retval = i;
4973 goto out;
4974 }
4975 for (i=0; i < ST_NBR_PARTITIONS; i++) {
4976 STp->ps[i].rw = ST_IDLE;
4977 STp->ps[i].at_sm = 0;
4978 STp->ps[i].last_block_valid = 0;
4979 }
4980 STp->partition = STp->new_partition = 0;
4981 STp->nbr_partitions = 1; /* Bad guess ?-) */
4982 STps->drv_block = STps->drv_file = 0;
4983 retval = 0;
4984 goto out;
4985 }
4986
4987 if (mtc.mt_op == MTSEEK) {
4988 if (STp->raw)
4989 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
4990 else
4991 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
4992 if (!STp->can_partitions)
4993 STp->ps[0].rw = ST_IDLE;
4994 retval = i;
4995 goto out;
4996 }
4997
4998 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
4999 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
5000 goto out;
5001 }
5002
5003 if (auto_weof)
5004 cross_eof(STp, &SRpnt, 0);
5005
5006 if (mtc.mt_op == MTCOMPRESSION)
5007 retval = -EINVAL; /* OnStream drives don't have compression hardware */
5008 else
5009 /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5010 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5011 retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5012 goto out;
5013 }
5014
5015 if (!STm->defined) {
5016 retval = (-ENXIO);
5017 goto out;
5018 }
5019
5020 if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5021 retval = i;
5022 goto out;
5023 }
5024
5025 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
5026 struct mtget mt_status;
5027
5028 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
5029 retval = (-EINVAL);
5030 goto out;
5031 }
5032
5033 mt_status.mt_type = MT_ISONSTREAM_SC;
5034 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
5035 mt_status.mt_dsreg =
5036 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
5037 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
5038 mt_status.mt_blkno = STps->drv_block;
5039 mt_status.mt_fileno = STps->drv_file;
5040 if (STp->block_size != 0) {
5041 if (STps->rw == ST_WRITING)
5042 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
5043 else if (STps->rw == ST_READING)
5044 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
5045 STp->block_size - 1) / STp->block_size;
5046 }
5047
5048 mt_status.mt_gstat = 0;
5049 if (STp->drv_write_prot)
5050 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
5051 if (mt_status.mt_blkno == 0) {
5052 if (mt_status.mt_fileno == 0)
5053 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
5054 else
5055 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
5056 }
5057 mt_status.mt_resid = STp->partition;
5058 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
5059 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
5060 else if (STps->eof >= ST_EOM_OK)
5061 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
5062 if (STp->density == 1)
5063 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
5064 else if (STp->density == 2)
5065 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
5066 else if (STp->density == 3)
5067 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
5068 if (STp->ready == ST_READY)
5069 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
5070 if (STp->ready == ST_NO_TAPE)
5071 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
5072 if (STps->at_sm)
5073 mt_status.mt_gstat |= GMT_SM(0xffffffff);
5074 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
5075 STp->drv_buffer != 0)
5076 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
5077
5078 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
5079 if (i) {
5080 retval = (-EFAULT);
5081 goto out;
5082 }
5083
5084 STp->recover_erreg = 0; /* Clear after read */
5085 retval = 0;
5086 goto out;
5087 } /* End of MTIOCGET */
5088
5089 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5090 struct mtpos mt_pos;
5091
5092 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5093 retval = (-EINVAL);
5094 goto out;
5095 }
5096 if (STp->raw)
5097 blk = osst_get_frame_position(STp, &SRpnt);
5098 else
5099 blk = osst_get_sector(STp, &SRpnt);
5100 if (blk < 0) {
5101 retval = blk;
5102 goto out;
5103 }
5104 mt_pos.mt_blkno = blk;
5105 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5106 if (i)
5107 retval = -EFAULT;
5108 goto out;
5109 }
5110 if (SRpnt) scsi_release_request(SRpnt);
5111
5112 up(&STp->lock);
5113
5114 return scsi_ioctl(STp->device, cmd_in, p);
5115
5116 out:
5117 if (SRpnt) scsi_release_request(SRpnt);
5118
5119 up(&STp->lock);
5120
5121 return retval;
5122 }
5123
5124
5125 /* Memory handling routines */
5126
5127 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5128 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5129 {
5130 int i, priority;
5131 struct osst_buffer *tb;
5132
5133 if (from_initialization)
5134 priority = GFP_ATOMIC;
5135 else
5136 priority = GFP_KERNEL;
5137
5138 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5139 tb = (struct osst_buffer *)kmalloc(i, priority);
5140 if (!tb) {
5141 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5142 return NULL;
5143 }
5144 memset(tb, 0, i);
5145 tb->sg_segs = tb->orig_sg_segs = 0;
5146 tb->use_sg = max_sg;
5147 tb->in_use = 1;
5148 tb->dma = need_dma;
5149 tb->buffer_size = 0;
5150 #if DEBUG
5151 if (debugging)
5152 printk(OSST_DEB_MSG
5153 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5154 i, max_sg, need_dma);
5155 #endif
5156 return tb;
5157 }
5158
5159 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5160 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5161 {
5162 int segs, nbr, max_segs, b_size, priority, order, got;
5163
5164 if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5165 return 1;
5166
5167 if (STbuffer->sg_segs) {
5168 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5169 normalize_buffer(STbuffer);
5170 }
5171 /* See how many segments we can use -- need at least two */
5172 nbr = max_segs = STbuffer->use_sg;
5173 if (nbr <= 2)
5174 return 0;
5175
5176 priority = GFP_KERNEL /* | __GFP_NOWARN */;
5177 if (need_dma)
5178 priority |= GFP_DMA;
5179
5180 /* Try to allocate the first segment up to OS_DATA_SIZE and the others
5181 big enough to reach the goal (code assumes no segments in place) */
5182 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5183 STbuffer->sg[0].page = alloc_pages(priority, order);
5184 STbuffer->sg[0].offset = 0;
5185 if (STbuffer->sg[0].page != NULL) {
5186 STbuffer->sg[0].length = b_size;
5187 STbuffer->b_data = page_address(STbuffer->sg[0].page);
5188 break;
5189 }
5190 }
5191 if (STbuffer->sg[0].page == NULL) {
5192 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5193 return 0;
5194 }
5195 /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5196 for (segs=STbuffer->sg_segs=1, got=b_size;
5197 segs < max_segs && got < OS_FRAME_SIZE; ) {
5198 STbuffer->sg[segs].page =
5199 alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5200 STbuffer->sg[segs].offset = 0;
5201 if (STbuffer->sg[segs].page == NULL) {
5202 if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
5203 b_size /= 2; /* Large enough for the rest of the buffers */
5204 order--;
5205 continue;
5206 }
5207 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5208 OS_FRAME_SIZE);
5209 #if DEBUG
5210 STbuffer->buffer_size = got;
5211 #endif
5212 normalize_buffer(STbuffer);
5213 return 0;
5214 }
5215 STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
5216 got += STbuffer->sg[segs].length;
5217 STbuffer->buffer_size = got;
5218 STbuffer->sg_segs = ++segs;
5219 }
5220 #if DEBUG
5221 if (debugging) {
5222 printk(OSST_DEB_MSG
5223 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5224 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5225 printk(OSST_DEB_MSG
5226 "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5227 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5228 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5229 }
5230 #endif
5231
5232 return 1;
5233 }
5234
5235
5236 /* Release the segments */
5237 static void normalize_buffer(struct osst_buffer *STbuffer)
5238 {
5239 int i, order, b_size;
5240
5241 for (i=0; i < STbuffer->sg_segs; i++) {
5242
5243 for (b_size = PAGE_SIZE, order = 0;
5244 b_size < STbuffer->sg[i].length;
5245 b_size *= 2, order++);
5246
5247 __free_pages(STbuffer->sg[i].page, order);
5248 STbuffer->buffer_size -= STbuffer->sg[i].length;
5249 }
5250 #if DEBUG
5251 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5252 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5253 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5254 #endif
5255 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5256 }
5257
5258
5259 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5260 negative error code. */
5261 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
5262 {
5263 int i, cnt, res, offset;
5264
5265 for (i=0, offset=st_bp->buffer_bytes;
5266 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5267 offset -= st_bp->sg[i].length;
5268 if (i == st_bp->sg_segs) { /* Should never happen */
5269 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5270 return (-EIO);
5271 }
5272 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5273 cnt = st_bp->sg[i].length - offset < do_count ?
5274 st_bp->sg[i].length - offset : do_count;
5275 res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
5276 if (res)
5277 return (-EFAULT);
5278 do_count -= cnt;
5279 st_bp->buffer_bytes += cnt;
5280 ubp += cnt;
5281 offset = 0;
5282 }
5283 if (do_count) { /* Should never happen */
5284 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5285 do_count);
5286 return (-EIO);
5287 }
5288 return 0;
5289 }
5290
5291
5292 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5293 negative error code. */
5294 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
5295 {
5296 int i, cnt, res, offset;
5297
5298 for (i=0, offset=st_bp->read_pointer;
5299 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5300 offset -= st_bp->sg[i].length;
5301 if (i == st_bp->sg_segs) { /* Should never happen */
5302 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5303 return (-EIO);
5304 }
5305 for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5306 cnt = st_bp->sg[i].length - offset < do_count ?
5307 st_bp->sg[i].length - offset : do_count;
5308 res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
5309 if (res)
5310 return (-EFAULT);
5311 do_count -= cnt;
5312 st_bp->buffer_bytes -= cnt;
5313 st_bp->read_pointer += cnt;
5314 ubp += cnt;
5315 offset = 0;
5316 }
5317 if (do_count) { /* Should never happen */
5318 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5319 return (-EIO);
5320 }
5321 return 0;
5322 }
5323
5324 /* Sets the tail of the buffer after fill point to zero.
5325 Returns zero (success) or negative error code. */
5326 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
5327 {
5328 int i, offset, do_count, cnt;
5329
5330 for (i = 0, offset = st_bp->buffer_bytes;
5331 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5332 offset -= st_bp->sg[i].length;
5333 if (i == st_bp->sg_segs) { /* Should never happen */
5334 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5335 return (-EIO);
5336 }
5337 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5338 i < st_bp->sg_segs && do_count > 0; i++) {
5339 cnt = st_bp->sg[i].length - offset < do_count ?
5340 st_bp->sg[i].length - offset : do_count ;
5341 memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
5342 do_count -= cnt;
5343 offset = 0;
5344 }
5345 if (do_count) { /* Should never happen */
5346 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5347 return (-EIO);
5348 }
5349 return 0;
5350 }
5351
5352 /* Copy a osst 32K chunk of memory into the buffer.
5353 Returns zero (success) or negative error code. */
5354 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5355 {
5356 int i, cnt, do_count = OS_DATA_SIZE;
5357
5358 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5359 cnt = st_bp->sg[i].length < do_count ?
5360 st_bp->sg[i].length : do_count ;
5361 memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
5362 do_count -= cnt;
5363 ptr += cnt;
5364 }
5365 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5366 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5367 do_count, i);
5368 return (-EIO);
5369 }
5370 return 0;
5371 }
5372
5373 /* Copy a osst 32K chunk of memory from the buffer.
5374 Returns zero (success) or negative error code. */
5375 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5376 {
5377 int i, cnt, do_count = OS_DATA_SIZE;
5378
5379 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5380 cnt = st_bp->sg[i].length < do_count ?
5381 st_bp->sg[i].length : do_count ;
5382 memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
5383 do_count -= cnt;
5384 ptr += cnt;
5385 }
5386 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */
5387 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5388 do_count, i);
5389 return (-EIO);
5390 }
5391 return 0;
5392 }
5393
5394
5395 /* Module housekeeping */
5396
5397 static void validate_options (void)
5398 {
5399 if (max_dev > 0)
5400 osst_max_dev = max_dev;
5401 if (write_threshold_kbs > 0)
5402 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5403 if (osst_write_threshold > osst_buffer_size)
5404 osst_write_threshold = osst_buffer_size;
5405 if (max_sg_segs >= OSST_FIRST_SG)
5406 osst_max_sg_segs = max_sg_segs;
5407 #if DEBUG
5408 printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5409 osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5410 #endif
5411 }
5412
5413 #ifndef MODULE
5414 /* Set the boot options. Syntax: osst=xxx,yyy,...
5415 where xxx is write threshold in 1024 byte blocks,
5416 and yyy is number of s/g segments to use. */
5417 static int __init osst_setup (char *str)
5418 {
5419 int i, ints[5];
5420 char *stp;
5421
5422 stp = get_options(str, ARRAY_SIZE(ints), ints);
5423
5424 if (ints[0] > 0) {
5425 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5426 *parms[i].val = ints[i + 1];
5427 } else {
5428 while (stp != NULL) {
5429 for (i = 0; i < ARRAY_SIZE(parms); i++) {
5430 int len = strlen(parms[i].name);
5431 if (!strncmp(stp, parms[i].name, len) &&
5432 (*(stp + len) == ':' || *(stp + len) == '=')) {
5433 *parms[i].val =
5434 simple_strtoul(stp + len + 1, NULL, 0);
5435 break;
5436 }
5437 }
5438 if (i >= sizeof(parms) / sizeof(struct osst_dev_parm))
5439 printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5440 stp);
5441 stp = strchr(stp, ',');
5442 if (stp)
5443 stp++;
5444 }
5445 }
5446
5447 return 1;
5448 }
5449
5450 __setup("osst=", osst_setup);
5451
5452 #endif
5453
5454 static struct file_operations osst_fops = {
5455 .owner = THIS_MODULE,
5456 .read = osst_read,
5457 .write = osst_write,
5458 .ioctl = osst_ioctl,
5459 .open = os_scsi_tape_open,
5460 .flush = os_scsi_tape_flush,
5461 .release = os_scsi_tape_close,
5462 };
5463
5464 static int osst_supports(struct scsi_device * SDp)
5465 {
5466 struct osst_support_data {
5467 char *vendor;
5468 char *model;
5469 char *rev;
5470 char *driver_hint; /* Name of the correct driver, NULL if unknown */
5471 };
5472
5473 static struct osst_support_data support_list[] = {
5474 /* {"XXX", "Yy-", "", NULL}, example */
5475 SIGS_FROM_OSST,
5476 {NULL, }};
5477
5478 struct osst_support_data *rp;
5479
5480 /* We are willing to drive OnStream SC-x0 as well as the
5481 * * IDE, ParPort, FireWire, USB variants, if accessible by
5482 * * emulation layer (ide-scsi, usb-storage, ...) */
5483
5484 for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5485 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5486 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5487 !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5488 return 1;
5489 return 0;
5490 }
5491
5492 /*
5493 * sysfs support for osst driver parameter information
5494 */
5495
5496 static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
5497 {
5498 return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
5499 }
5500
5501 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
5502
5503 static void osst_create_driverfs_files(struct device_driver *driverfs)
5504 {
5505 driver_create_file(driverfs, &driver_attr_version);
5506 }
5507
5508 static void osst_remove_driverfs_files(struct device_driver *driverfs)
5509 {
5510 driver_remove_file(driverfs, &driver_attr_version);
5511 }
5512
5513 /*
5514 * sysfs support for accessing ADR header information
5515 */
5516
5517 static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf)
5518 {
5519 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5520 ssize_t l = 0;
5521
5522 if (STp && STp->header_ok && STp->linux_media)
5523 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
5524 return l;
5525 }
5526
5527 CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
5528
5529 static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf)
5530 {
5531 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5532 ssize_t l = 0;
5533
5534 if (STp && STp->header_ok && STp->linux_media)
5535 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
5536 return l;
5537 }
5538
5539 CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
5540
5541 static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf)
5542 {
5543 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5544 ssize_t l = 0;
5545
5546 if (STp && STp->header_ok && STp->linux_media)
5547 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
5548 return l;
5549 }
5550
5551 CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
5552
5553 static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf)
5554 {
5555 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5556 ssize_t l = 0;
5557
5558 if (STp && STp->header_ok && STp->linux_media)
5559 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
5560 return l;
5561 }
5562
5563 CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
5564
5565 static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf)
5566 {
5567 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5568 ssize_t l = 0;
5569
5570 if (STp && STp->header_ok && STp->linux_media)
5571 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
5572 return l;
5573 }
5574
5575 CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
5576
5577 static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf)
5578 {
5579 struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
5580 ssize_t l = 0;
5581
5582 if (STp && STp->header_ok && STp->linux_media)
5583 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
5584 return l;
5585 }
5586
5587 CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5588
5589 static struct class_simple * osst_sysfs_class;
5590
5591 static int osst_sysfs_valid = 0;
5592
5593 static void osst_sysfs_init(void)
5594 {
5595 osst_sysfs_class = class_simple_create(THIS_MODULE, "onstream_tape");
5596 if ( IS_ERR(osst_sysfs_class) )
5597 printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
5598 else
5599 osst_sysfs_valid = 1;
5600 }
5601
5602 static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5603 {
5604 struct class_device *osst_class_member;
5605
5606 if (!osst_sysfs_valid) return;
5607
5608 osst_class_member = class_simple_device_add(osst_sysfs_class, dev, device, "%s", name);
5609 if (IS_ERR(osst_class_member)) {
5610 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5611 return;
5612 }
5613 class_set_devdata(osst_class_member, STp);
5614 class_device_create_file(osst_class_member, &class_device_attr_ADR_rev);
5615 class_device_create_file(osst_class_member, &class_device_attr_media_version);
5616 class_device_create_file(osst_class_member, &class_device_attr_capacity);
5617 class_device_create_file(osst_class_member, &class_device_attr_BOT_frame);
5618 class_device_create_file(osst_class_member, &class_device_attr_EOD_frame);
5619 class_device_create_file(osst_class_member, &class_device_attr_file_count);
5620 }
5621
5622 static void osst_sysfs_destroy(dev_t dev)
5623 {
5624 if (!osst_sysfs_valid) return;
5625
5626 class_simple_device_remove(dev);
5627 }
5628
5629 static void osst_sysfs_cleanup(void)
5630 {
5631 if (osst_sysfs_valid) {
5632 class_simple_destroy(osst_sysfs_class);
5633 osst_sysfs_valid = 0;
5634 }
5635 }
5636
5637 /*
5638 * osst startup / cleanup code
5639 */
5640
5641 static int osst_probe(struct device *dev)
5642 {
5643 struct scsi_device * SDp = to_scsi_device(dev);
5644 struct osst_tape * tpnt;
5645 struct st_modedef * STm;
5646 struct st_partstat * STps;
5647 struct osst_buffer * buffer;
5648 struct gendisk * drive;
5649 int i, mode, dev_num;
5650
5651 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5652 return -ENODEV;
5653
5654 drive = alloc_disk(1);
5655 if (!drive) {
5656 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5657 return -ENODEV;
5658 }
5659
5660 /* if this is the first attach, build the infrastructure */
5661 write_lock(&os_scsi_tapes_lock);
5662 if (os_scsi_tapes == NULL) {
5663 os_scsi_tapes =
5664 (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *),
5665 GFP_ATOMIC);
5666 if (os_scsi_tapes == NULL) {
5667 write_unlock(&os_scsi_tapes_lock);
5668 printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5669 goto out_put_disk;
5670 }
5671 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5672 }
5673
5674 if (osst_nr_dev >= osst_max_dev) {
5675 write_unlock(&os_scsi_tapes_lock);
5676 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5677 goto out_put_disk;
5678 }
5679
5680 /* find a free minor number */
5681 for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++);
5682 if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5683 dev_num = i;
5684
5685 /* allocate a struct osst_tape for this device */
5686 tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
5687 if (tpnt == NULL) {
5688 write_unlock(&os_scsi_tapes_lock);
5689 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5690 goto out_put_disk;
5691 }
5692 memset(tpnt, 0, sizeof(struct osst_tape));
5693
5694 /* allocate a buffer for this device */
5695 i = SDp->host->sg_tablesize;
5696 if (osst_max_sg_segs < i)
5697 i = osst_max_sg_segs;
5698 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
5699 if (buffer == NULL) {
5700 write_unlock(&os_scsi_tapes_lock);
5701 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5702 kfree(tpnt);
5703 goto out_put_disk;
5704 }
5705 os_scsi_tapes[dev_num] = tpnt;
5706 tpnt->buffer = buffer;
5707 tpnt->device = SDp;
5708 drive->private_data = &tpnt->driver;
5709 sprintf(drive->disk_name, "osst%d", dev_num);
5710 tpnt->driver = &osst_template;
5711 tpnt->drive = drive;
5712 tpnt->in_use = 0;
5713 tpnt->capacity = 0xfffff;
5714 tpnt->dirty = 0;
5715 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
5716 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5717 tpnt->density = 0;
5718 tpnt->do_auto_lock = OSST_AUTO_LOCK;
5719 tpnt->can_bsr = OSST_IN_FILE_POS;
5720 tpnt->can_partitions = 0;
5721 tpnt->two_fm = OSST_TWO_FM;
5722 tpnt->fast_mteom = OSST_FAST_MTEOM;
5723 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5724 tpnt->write_threshold = osst_write_threshold;
5725 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5726 tpnt->partition = 0;
5727 tpnt->new_partition = 0;
5728 tpnt->nbr_partitions = 0;
5729 tpnt->min_block = 512;
5730 tpnt->max_block = OS_DATA_SIZE;
5731 tpnt->timeout = OSST_TIMEOUT;
5732 tpnt->long_timeout = OSST_LONG_TIMEOUT;
5733
5734 /* Recognize OnStream tapes */
5735 /* We don't need to test for OnStream, as this has been done in detect () */
5736 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5737 tpnt->omit_blklims = 1;
5738
5739 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5740 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5741 tpnt->frame_in_buffer = 0;
5742 tpnt->header_ok = 0;
5743 tpnt->linux_media = 0;
5744 tpnt->header_cache = NULL;
5745
5746 for (i=0; i < ST_NBR_MODES; i++) {
5747 STm = &(tpnt->modes[i]);
5748 STm->defined = 0;
5749 STm->sysv = OSST_SYSV;
5750 STm->defaults_for_writes = 0;
5751 STm->do_async_writes = OSST_ASYNC_WRITES;
5752 STm->do_buffer_writes = OSST_BUFFER_WRITES;
5753 STm->do_read_ahead = OSST_READ_AHEAD;
5754 STm->default_compression = ST_DONT_TOUCH;
5755 STm->default_blksize = 512;
5756 STm->default_density = (-1); /* No forced density */
5757 }
5758
5759 for (i=0; i < ST_NBR_PARTITIONS; i++) {
5760 STps = &(tpnt->ps[i]);
5761 STps->rw = ST_IDLE;
5762 STps->eof = ST_NOEOF;
5763 STps->at_sm = 0;
5764 STps->last_block_valid = 0;
5765 STps->drv_block = (-1);
5766 STps->drv_file = (-1);
5767 }
5768
5769 tpnt->current_mode = 0;
5770 tpnt->modes[0].defined = 1;
5771 tpnt->modes[2].defined = 1;
5772 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
5773
5774 init_MUTEX(&tpnt->lock);
5775 osst_nr_dev++;
5776 write_unlock(&os_scsi_tapes_lock);
5777 {
5778 char name[8];
5779 /* Rewind entry */
5780 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5781 /* No-rewind entry */
5782 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5783 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5784 }
5785 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
5786 /* Rewind entry */
5787 devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)),
5788 S_IFCHR | S_IRUGO | S_IWUGO,
5789 "%s/ot%s", SDp->devfs_name, osst_formats[mode]);
5790
5791 /* No-rewind entry */
5792 devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5) + 128),
5793 S_IFCHR | S_IRUGO | S_IWUGO,
5794 "%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
5795 }
5796 drive->number = devfs_register_tape(SDp->devfs_name);
5797
5798 printk(KERN_INFO
5799 "osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as %s\n",
5800 SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, tape_name(tpnt));
5801
5802 return 0;
5803
5804 out_put_disk:
5805 put_disk(drive);
5806 return -ENODEV;
5807 };
5808
5809 static int osst_remove(struct device *dev)
5810 {
5811 struct scsi_device * SDp = to_scsi_device(dev);
5812 struct osst_tape * tpnt;
5813 int i, mode;
5814
5815 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
5816 return 0;
5817
5818 write_lock(&os_scsi_tapes_lock);
5819 for(i=0; i < osst_max_dev; i++) {
5820 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
5821 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
5822 osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
5823 tpnt->device = NULL;
5824 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
5825 devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]);
5826 devfs_remove("%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
5827 }
5828 devfs_unregister_tape(tpnt->drive->number);
5829 put_disk(tpnt->drive);
5830 os_scsi_tapes[i] = NULL;
5831 osst_nr_dev--;
5832 write_unlock(&os_scsi_tapes_lock);
5833 if (tpnt->header_cache != NULL) vfree(tpnt->header_cache);
5834 if (tpnt->buffer) {
5835 normalize_buffer(tpnt->buffer);
5836 kfree(tpnt->buffer);
5837 }
5838 kfree(tpnt);
5839 return 0;
5840 }
5841 }
5842 write_unlock(&os_scsi_tapes_lock);
5843 return 0;
5844 }
5845
5846 static int __init init_osst(void)
5847 {
5848 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
5849
5850 validate_options();
5851 osst_sysfs_init();
5852
5853 if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
5854 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
5855 osst_sysfs_cleanup();
5856 return 1;
5857 }
5858 osst_create_driverfs_files(&osst_template.gendrv);
5859
5860 return 0;
5861 }
5862
5863 static void __exit exit_osst (void)
5864 {
5865 int i;
5866 struct osst_tape * STp;
5867
5868 osst_remove_driverfs_files(&osst_template.gendrv);
5869 scsi_unregister_driver(&osst_template.gendrv);
5870 unregister_chrdev(OSST_MAJOR, "osst");
5871 osst_sysfs_cleanup();
5872
5873 if (os_scsi_tapes) {
5874 for (i=0; i < osst_max_dev; ++i) {
5875 if (!(STp = os_scsi_tapes[i])) continue;
5876 /* This is defensive, supposed to happen during detach */
5877 if (STp->header_cache)
5878 vfree(STp->header_cache);
5879 if (STp->buffer) {
5880 normalize_buffer(STp->buffer);
5881 kfree(STp->buffer);
5882 }
5883 put_disk(STp->drive);
5884 kfree(STp);
5885 }
5886 kfree(os_scsi_tapes);
5887 }
5888 printk(KERN_INFO "osst :I: Unloaded.\n");
5889 }
5890
5891 module_init(init_osst);
5892 module_exit(exit_osst);
5893
|
This page was automatically generated by the
LXR engine.
|