osst: update ppos instead of using file->f_pos
[pandora-kernel.git] / drivers / scsi / osst.c
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 - 2006 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 static const char * osst_version = "0.99.4";
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/slab.h>
42 #include <linux/init.h>
43 #include <linux/string.h>
44 #include <linux/errno.h>
45 #include <linux/mtio.h>
46 #include <linux/ioctl.h>
47 #include <linux/fcntl.h>
48 #include <linux/spinlock.h>
49 #include <linux/vmalloc.h>
50 #include <linux/blkdev.h>
51 #include <linux/moduleparam.h>
52 #include <linux/delay.h>
53 #include <linux/jiffies.h>
54 #include <linux/smp_lock.h>
55 #include <asm/uaccess.h>
56 #include <asm/dma.h>
57 #include <asm/system.h>
58
59 /* The driver prints some debugging information on the console if DEBUG
60    is defined and non-zero. */
61 #define DEBUG 0
62
63 /* The message level for the debug messages is currently set to KERN_NOTICE
64    so that people can easily see the messages. Later when the debugging messages
65    in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
66 #define OSST_DEB_MSG  KERN_NOTICE
67
68 #include <scsi/scsi.h>
69 #include <scsi/scsi_dbg.h>
70 #include <scsi/scsi_device.h>
71 #include <scsi/scsi_driver.h>
72 #include <scsi/scsi_eh.h>
73 #include <scsi/scsi_host.h>
74 #include <scsi/scsi_ioctl.h>
75
76 #define ST_KILOBYTE 1024
77
78 #include "st.h"
79 #include "osst.h"
80 #include "osst_options.h"
81 #include "osst_detect.h"
82
83 static int max_dev = 0;
84 static int write_threshold_kbs = 0;
85 static int max_sg_segs = 0;
86
87 #ifdef MODULE
88 MODULE_AUTHOR("Willem Riede");
89 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
90 MODULE_LICENSE("GPL");
91 MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR);
92 MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
93
94 module_param(max_dev, int, 0444);
95 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
96
97 module_param(write_threshold_kbs, int, 0644);
98 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
99
100 module_param(max_sg_segs, int, 0644);
101 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
102 #else
103 static struct osst_dev_parm {
104        char   *name;
105        int    *val;
106 } parms[] __initdata = {
107        { "max_dev",             &max_dev             },
108        { "write_threshold_kbs", &write_threshold_kbs },
109        { "max_sg_segs",         &max_sg_segs         }
110 };
111 #endif
112
113 /* Some default definitions have been moved to osst_options.h */
114 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
115 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
116
117 /* The buffer size should fit into the 24 bits for length in the
118    6-byte SCSI read and write commands. */
119 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
120 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
121 #endif
122
123 #if DEBUG
124 static int debugging = 1;
125 /* uncomment define below to test error recovery */
126 // #define OSST_INJECT_ERRORS 1 
127 #endif
128
129 /* Do not retry! The drive firmware already retries when appropriate,
130    and when it tries to tell us something, we had better listen... */
131 #define MAX_RETRIES 0
132
133 #define NO_TAPE  NOT_READY
134
135 #define OSST_WAIT_POSITION_COMPLETE   (HZ > 200 ? HZ / 200 : 1)
136 #define OSST_WAIT_WRITE_COMPLETE      (HZ / 12)
137 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
138         
139 #define OSST_TIMEOUT (200 * HZ)
140 #define OSST_LONG_TIMEOUT (1800 * HZ)
141
142 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
143 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
144 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
145 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
146
147 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
148    24 bits) */
149 #define SET_DENS_AND_BLK 0x10001
150
151 static int osst_buffer_size       = OSST_BUFFER_SIZE;
152 static int osst_write_threshold   = OSST_WRITE_THRESHOLD;
153 static int osst_max_sg_segs       = OSST_MAX_SG;
154 static int osst_max_dev           = OSST_MAX_TAPES;
155 static int osst_nr_dev;
156
157 static struct osst_tape **os_scsi_tapes = NULL;
158 static DEFINE_RWLOCK(os_scsi_tapes_lock);
159
160 static int modes_defined = 0;
161
162 static struct osst_buffer *new_tape_buffer(int, int, int);
163 static int enlarge_buffer(struct osst_buffer *, int);
164 static void normalize_buffer(struct osst_buffer *);
165 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
166 static int from_buffer(struct osst_buffer *, char __user *, int);
167 static int osst_zero_buffer_tail(struct osst_buffer *);
168 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
169 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
170
171 static int osst_probe(struct device *);
172 static int osst_remove(struct device *);
173
174 static struct scsi_driver osst_template = {
175         .owner                  = THIS_MODULE,
176         .gendrv = {
177                 .name           =  "osst",
178                 .probe          = osst_probe,
179                 .remove         = osst_remove,
180         }
181 };
182
183 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt,
184                             unsigned int cmd_in, unsigned long arg);
185
186 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip);
187
188 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt);
189
190 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt);
191
192 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending);
193
194 static inline char *tape_name(struct osst_tape *tape)
195 {
196         return tape->drive->disk_name;
197 }
198 \f
199 /* Routines that handle the interaction with mid-layer SCSI routines */
200
201
202 /* Normalize Sense */
203 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s)
204 {
205         const u8 *ucp;
206         const u8 *sense = SRpnt->sense;
207
208         s->have_sense = scsi_normalize_sense(SRpnt->sense,
209                                 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
210         s->flags = 0;
211
212         if (s->have_sense) {
213                 s->deferred = 0;
214                 s->remainder_valid =
215                         scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
216                 switch (sense[0] & 0x7f) {
217                 case 0x71:
218                         s->deferred = 1;
219                 case 0x70:
220                         s->fixed_format = 1;
221                         s->flags = sense[2] & 0xe0;
222                         break;
223                 case 0x73:
224                         s->deferred = 1;
225                 case 0x72:
226                         s->fixed_format = 0;
227                         ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
228                         s->flags = ucp ? (ucp[3] & 0xe0) : 0;
229                         break;
230                 }
231         }
232 }
233
234 /* Convert the result to success code */
235 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
236 {
237         char *name = tape_name(STp);
238         int result = SRpnt->result;
239         u8 * sense = SRpnt->sense, scode;
240 #if DEBUG
241         const char *stp;
242 #endif
243         struct st_cmdstatus *cmdstatp;
244
245         if (!result)
246                 return 0;
247
248         cmdstatp = &STp->buffer->cmdstat;
249         osst_analyze_sense(SRpnt, cmdstatp);
250
251         if (cmdstatp->have_sense)
252                 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
253         else
254                 scode = 0;
255 #if DEBUG
256         if (debugging) {
257                 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
258                    name, result,
259                    SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
260                    SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
261                 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
262                                 name, scode, sense[12], sense[13]);
263                 if (cmdstatp->have_sense)
264                         __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
265         }
266         else
267 #endif
268         if (cmdstatp->have_sense && (
269                  scode != NO_SENSE &&
270                  scode != RECOVERED_ERROR &&
271 /*               scode != UNIT_ATTENTION && */
272                  scode != BLANK_CHECK &&
273                  scode != VOLUME_OVERFLOW &&
274                  SRpnt->cmd[0] != MODE_SENSE &&
275                  SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
276                 if (cmdstatp->have_sense) {
277                         printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
278                         __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
279                 }
280                 else {
281                         static  int     notyetprinted = 1;
282
283                         printk(KERN_WARNING
284                              "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n",
285                              name, result, driver_byte(result),
286                              host_byte(result));
287                         if (notyetprinted) {
288                                 notyetprinted = 0;
289                                 printk(KERN_INFO
290                                         "%s:I: This warning may be caused by your scsi controller,\n", name);
291                                 printk(KERN_INFO
292                                         "%s:I: it has been reported with some Buslogic cards.\n", name);
293                         }
294                 }
295         }
296         STp->pos_unknown |= STp->device->was_reset;
297
298         if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
299                 STp->recover_count++;
300                 STp->recover_erreg++;
301 #if DEBUG
302                 if (debugging) {
303                         if (SRpnt->cmd[0] == READ_6)
304                                 stp = "read";
305                         else if (SRpnt->cmd[0] == WRITE_6)
306                                 stp = "write";
307                         else
308                                 stp = "ioctl";
309                         printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
310                                              STp->recover_count);
311                 }
312 #endif
313                 if ((sense[2] & 0xe0) == 0)
314                         return 0;
315         }
316         return (-EIO);
317 }
318
319
320 /* Wakeup from interrupt */
321 static void osst_end_async(struct request *req, int update)
322 {
323         struct osst_request *SRpnt = req->end_io_data;
324         struct osst_tape *STp = SRpnt->stp;
325         struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
326
327         STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
328 #if DEBUG
329         STp->write_pending = 0;
330 #endif
331         if (SRpnt->waiting)
332                 complete(SRpnt->waiting);
333
334         if (SRpnt->bio) {
335                 kfree(mdata->pages);
336                 blk_rq_unmap_user(SRpnt->bio);
337         }
338
339         __blk_put_request(req->q, req);
340 }
341
342 /* osst_request memory management */
343 static struct osst_request *osst_allocate_request(void)
344 {
345         return kzalloc(sizeof(struct osst_request), GFP_KERNEL);
346 }
347
348 static void osst_release_request(struct osst_request *streq)
349 {
350         kfree(streq);
351 }
352
353 static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
354                         int cmd_len, int data_direction, void *buffer, unsigned bufflen,
355                         int use_sg, int timeout, int retries)
356 {
357         struct request *req;
358         struct page **pages = NULL;
359         struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
360
361         int err = 0;
362         int write = (data_direction == DMA_TO_DEVICE);
363
364         req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL);
365         if (!req)
366                 return DRIVER_ERROR << 24;
367
368         req->cmd_type = REQ_TYPE_BLOCK_PC;
369         req->cmd_flags |= REQ_QUIET;
370
371         SRpnt->bio = NULL;
372
373         if (use_sg) {
374                 struct scatterlist *sg, *sgl = (struct scatterlist *)buffer;
375                 int i;
376
377                 pages = kzalloc(use_sg * sizeof(struct page *), GFP_KERNEL);
378                 if (!pages)
379                         goto free_req;
380
381                 for_each_sg(sgl, sg, use_sg, i)
382                         pages[i] = sg_page(sg);
383
384                 mdata->null_mapped = 1;
385
386                 mdata->page_order = get_order(sgl[0].length);
387                 mdata->nr_entries =
388                         DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order);
389                 mdata->offset = 0;
390
391                 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
392                 if (err) {
393                         kfree(pages);
394                         goto free_req;
395                 }
396                 SRpnt->bio = req->bio;
397                 mdata->pages = pages;
398
399         } else if (bufflen) {
400                 err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL);
401                 if (err)
402                         goto free_req;
403         }
404
405         req->cmd_len = cmd_len;
406         memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
407         memcpy(req->cmd, cmd, req->cmd_len);
408         req->sense = SRpnt->sense;
409         req->sense_len = 0;
410         req->timeout = timeout;
411         req->retries = retries;
412         req->end_io_data = SRpnt;
413
414         blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async);
415         return 0;
416 free_req:
417         blk_put_request(req);
418         return DRIVER_ERROR << 24;
419 }
420
421 /* Do the scsi command. Waits until command performed if do_wait is true.
422    Otherwise osst_write_behind_check() is used to check that the command
423    has finished. */
424 static  struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp, 
425         unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
426 {
427         unsigned char *bp;
428         unsigned short use_sg;
429 #ifdef OSST_INJECT_ERRORS
430         static   int   inject = 0;
431         static   int   repeat = 0;
432 #endif
433         struct completion *waiting;
434
435         /* if async, make sure there's no command outstanding */
436         if (!do_wait && ((STp->buffer)->last_SRpnt)) {
437                 printk(KERN_ERR "%s: Async command already active.\n",
438                        tape_name(STp));
439                 if (signal_pending(current))
440                         (STp->buffer)->syscall_result = (-EINTR);
441                 else
442                         (STp->buffer)->syscall_result = (-EBUSY);
443                 return NULL;
444         }
445
446         if (SRpnt == NULL) {
447                 SRpnt = osst_allocate_request();
448                 if (SRpnt == NULL) {
449                         printk(KERN_ERR "%s: Can't allocate SCSI request.\n",
450                                      tape_name(STp));
451                         if (signal_pending(current))
452                                 (STp->buffer)->syscall_result = (-EINTR);
453                         else
454                                 (STp->buffer)->syscall_result = (-EBUSY);
455                         return NULL;
456                 }
457                 SRpnt->stp = STp;
458         }
459
460         /* If async IO, set last_SRpnt. This ptr tells write_behind_check
461            which IO is outstanding. It's nulled out when the IO completes. */
462         if (!do_wait)
463                 (STp->buffer)->last_SRpnt = SRpnt;
464
465         waiting = &STp->wait;
466         init_completion(waiting);
467         SRpnt->waiting = waiting;
468
469         use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0;
470         if (use_sg) {
471                 bp = (char *)&(STp->buffer->sg[0]);
472                 if (STp->buffer->sg_segs < use_sg)
473                         use_sg = STp->buffer->sg_segs;
474         }
475         else
476                 bp = (STp->buffer)->b_data;
477
478         memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
479         STp->buffer->cmdstat.have_sense = 0;
480         STp->buffer->syscall_result = 0;
481
482         if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
483                          use_sg, timeout, retries))
484                 /* could not allocate the buffer or request was too large */
485                 (STp->buffer)->syscall_result = (-EBUSY);
486         else if (do_wait) {
487                 wait_for_completion(waiting);
488                 SRpnt->waiting = NULL;
489                 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
490 #ifdef OSST_INJECT_ERRORS
491                 if (STp->buffer->syscall_result == 0 &&
492                     cmd[0] == READ_6 &&
493                     cmd[4] && 
494                     ( (++ inject % 83) == 29  ||
495                       (STp->first_frame_position == 240 
496                                  /* or STp->read_error_frame to fail again on the block calculated above */ &&
497                                  ++repeat < 3))) {
498                         printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
499                         STp->buffer->last_result_fatal = 1;
500                 }
501 #endif
502         }
503         return SRpnt;
504 }
505
506
507 /* Handle the write-behind checking (downs the semaphore) */
508 static void osst_write_behind_check(struct osst_tape *STp)
509 {
510         struct osst_buffer * STbuffer;
511
512         STbuffer = STp->buffer;
513
514 #if DEBUG
515         if (STp->write_pending)
516                 STp->nbr_waits++;
517         else
518                 STp->nbr_finished++;
519 #endif
520         wait_for_completion(&(STp->wait));
521         STp->buffer->last_SRpnt->waiting = NULL;
522
523         STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
524
525         if (STp->buffer->syscall_result)
526                 STp->buffer->syscall_result =
527                         osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1);
528         else
529                 STp->first_frame_position++;
530
531         osst_release_request(STp->buffer->last_SRpnt);
532
533         if (STbuffer->writing < STbuffer->buffer_bytes)
534                 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
535
536         STbuffer->last_SRpnt = NULL;
537         STbuffer->buffer_bytes -= STbuffer->writing;
538         STbuffer->writing = 0;
539
540         return;
541 }
542
543
544 \f
545 /* Onstream specific Routines */
546 /*
547  * Initialize the OnStream AUX
548  */
549 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
550                                          int logical_blk_num, int blk_sz, int blk_cnt)
551 {
552         os_aux_t       *aux = STp->buffer->aux;
553         os_partition_t *par = &aux->partition;
554         os_dat_t       *dat = &aux->dat;
555
556         if (STp->raw) return;
557
558         memset(aux, 0, sizeof(*aux));
559         aux->format_id = htonl(0);
560         memcpy(aux->application_sig, "LIN4", 4);
561         aux->hdwr = htonl(0);
562         aux->frame_type = frame_type;
563
564         switch (frame_type) {
565           case  OS_FRAME_TYPE_HEADER:
566                 aux->update_frame_cntr    = htonl(STp->update_frame_cntr);
567                 par->partition_num        = OS_CONFIG_PARTITION;
568                 par->par_desc_ver         = OS_PARTITION_VERSION;
569                 par->wrt_pass_cntr        = htons(0xffff);
570                 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
571                 par->first_frame_ppos     = htonl(0);
572                 par->last_frame_ppos      = htonl(0xbb7);
573                 aux->frame_seq_num        = htonl(0);
574                 aux->logical_blk_num_high = htonl(0);
575                 aux->logical_blk_num      = htonl(0);
576                 aux->next_mark_ppos       = htonl(STp->first_mark_ppos);
577                 break;
578           case  OS_FRAME_TYPE_DATA:
579           case  OS_FRAME_TYPE_MARKER:
580                 dat->dat_sz = 8;
581                 dat->reserved1 = 0;
582                 dat->entry_cnt = 1;
583                 dat->reserved3 = 0;
584                 dat->dat_list[0].blk_sz   = htonl(blk_sz);
585                 dat->dat_list[0].blk_cnt  = htons(blk_cnt);
586                 dat->dat_list[0].flags    = frame_type==OS_FRAME_TYPE_MARKER?
587                                                         OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
588                 dat->dat_list[0].reserved = 0;
589           case  OS_FRAME_TYPE_EOD:
590                 aux->update_frame_cntr    = htonl(0);
591                 par->partition_num        = OS_DATA_PARTITION;
592                 par->par_desc_ver         = OS_PARTITION_VERSION;
593                 par->wrt_pass_cntr        = htons(STp->wrt_pass_cntr);
594                 par->first_frame_ppos     = htonl(STp->first_data_ppos);
595                 par->last_frame_ppos      = htonl(STp->capacity);
596                 aux->frame_seq_num        = htonl(frame_seq_number);
597                 aux->logical_blk_num_high = htonl(0);
598                 aux->logical_blk_num      = htonl(logical_blk_num);
599                 break;
600           default: ; /* probably FILL */
601         }
602         aux->filemark_cnt = htonl(STp->filemark_cnt);
603         aux->phys_fm = htonl(0xffffffff);
604         aux->last_mark_ppos = htonl(STp->last_mark_ppos);
605         aux->last_mark_lbn  = htonl(STp->last_mark_lbn);
606 }
607
608 /*
609  * Verify that we have the correct tape frame
610  */
611 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
612 {
613         char               * name = tape_name(STp);
614         os_aux_t           * aux  = STp->buffer->aux;
615         os_partition_t     * par  = &(aux->partition);
616         struct st_partstat * STps = &(STp->ps[STp->partition]);
617         int                  blk_cnt, blk_sz, i;
618
619         if (STp->raw) {
620                 if (STp->buffer->syscall_result) {
621                         for (i=0; i < STp->buffer->sg_segs; i++)
622                                 memset(page_address(sg_page(&STp->buffer->sg[i])),
623                                        0, STp->buffer->sg[i].length);
624                         strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
625                 } else
626                         STp->buffer->buffer_bytes = OS_FRAME_SIZE;
627                 return 1;
628         }
629         if (STp->buffer->syscall_result) {
630 #if DEBUG
631                 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
632 #endif
633                 return 0;
634         }
635         if (ntohl(aux->format_id) != 0) {
636 #if DEBUG
637                 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
638 #endif
639                 goto err_out;
640         }
641         if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
642             (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
643 #if DEBUG
644                 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
645 #endif
646                 goto err_out;
647         }
648         if (par->partition_num != OS_DATA_PARTITION) {
649                 if (!STp->linux_media || STp->linux_media_version != 2) {
650 #if DEBUG
651                         printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
652                                             name, par->partition_num);
653 #endif
654                         goto err_out;
655                 }
656         }
657         if (par->par_desc_ver != OS_PARTITION_VERSION) {
658 #if DEBUG
659                 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
660 #endif
661                 goto err_out;
662         }
663         if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
664 #if DEBUG
665                 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n", 
666                                     name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
667 #endif
668                 goto err_out;
669         }
670         if (aux->frame_type != OS_FRAME_TYPE_DATA &&
671             aux->frame_type != OS_FRAME_TYPE_EOD &&
672             aux->frame_type != OS_FRAME_TYPE_MARKER) {
673                 if (!quiet) {
674 #if DEBUG
675                         printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
676 #endif
677                 }
678                 goto err_out;
679         }
680         if (aux->frame_type == OS_FRAME_TYPE_EOD &&
681             STp->first_frame_position < STp->eod_frame_ppos) {
682                 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
683                                  STp->first_frame_position);
684                 goto err_out;
685         }
686         if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
687                 if (!quiet) {
688 #if DEBUG
689                         printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n", 
690                                             name, ntohl(aux->frame_seq_num), frame_seq_number);
691 #endif
692                 }
693                 goto err_out;
694         }
695         if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
696                 STps->eof = ST_FM_HIT;
697
698                 i = ntohl(aux->filemark_cnt);
699                 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
700                     STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
701 #if DEBUG
702                         printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
703                                   STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
704                                   i, STp->first_frame_position - 1);
705 #endif
706                         STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
707                         if (i >= STp->filemark_cnt)
708                                  STp->filemark_cnt = i+1;
709                 }
710         }
711         if (aux->frame_type == OS_FRAME_TYPE_EOD) {
712                 STps->eof = ST_EOD_1;
713                 STp->frame_in_buffer = 1;
714         }
715         if (aux->frame_type == OS_FRAME_TYPE_DATA) {
716                 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
717                 blk_sz  = ntohl(aux->dat.dat_list[0].blk_sz);
718                 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
719                 STp->buffer->read_pointer = 0;
720                 STp->frame_in_buffer = 1;
721
722                 /* See what block size was used to write file */
723                 if (STp->block_size != blk_sz && blk_sz > 0) {
724                         printk(KERN_INFO
725                 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
726                                 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
727                                 STp->block_size<1024?STp->block_size:STp->block_size/1024,
728                                 STp->block_size<1024?'b':'k');
729                         STp->block_size            = blk_sz;
730                         STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
731                 }
732                 STps->eof = ST_NOEOF;
733         }
734         STp->frame_seq_number = ntohl(aux->frame_seq_num);
735         STp->logical_blk_num  = ntohl(aux->logical_blk_num);
736         return 1;
737
738 err_out:
739         if (STp->read_error_frame == 0)
740                 STp->read_error_frame = STp->first_frame_position - 1;
741         return 0;
742 }
743
744 /*
745  * Wait for the unit to become Ready
746  */
747 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
748                                  unsigned timeout, int initial_delay)
749 {
750         unsigned char           cmd[MAX_COMMAND_SIZE];
751         struct osst_request   * SRpnt;
752         unsigned long           startwait = jiffies;
753 #if DEBUG
754         int                     dbg  = debugging;
755         char                  * name = tape_name(STp);
756
757         printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
758 #endif
759
760         if (initial_delay > 0)
761                 msleep(jiffies_to_msecs(initial_delay));
762
763         memset(cmd, 0, MAX_COMMAND_SIZE);
764         cmd[0] = TEST_UNIT_READY;
765
766         SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
767         *aSRpnt = SRpnt;
768         if (!SRpnt) return (-EBUSY);
769
770         while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
771                (( SRpnt->sense[2]  == 2 && SRpnt->sense[12] == 4    &&
772                  (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)    ) ||
773                 ( SRpnt->sense[2]  == 6 && SRpnt->sense[12] == 0x28 &&
774                   SRpnt->sense[13] == 0                                        )  )) {
775 #if DEBUG
776             if (debugging) {
777                 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
778                 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
779                 debugging = 0;
780             }
781 #endif
782             msleep(100);
783
784             memset(cmd, 0, MAX_COMMAND_SIZE);
785             cmd[0] = TEST_UNIT_READY;
786
787             SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
788         }
789         *aSRpnt = SRpnt;
790 #if DEBUG
791         debugging = dbg;
792 #endif
793         if ( STp->buffer->syscall_result &&
794              osst_write_error_recovery(STp, aSRpnt, 0) ) {
795 #if DEBUG
796             printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
797             printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
798                         STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
799                         SRpnt->sense[12], SRpnt->sense[13]);
800 #endif
801             return (-EIO);
802         }
803 #if DEBUG
804         printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
805 #endif
806         return 0;
807 }
808
809 /*
810  * Wait for a tape to be inserted in the unit
811  */
812 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
813 {
814         unsigned char           cmd[MAX_COMMAND_SIZE];
815         struct osst_request   * SRpnt;
816         unsigned long           startwait = jiffies;
817 #if DEBUG
818         int                     dbg = debugging;
819         char                  * name = tape_name(STp);
820
821         printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
822 #endif
823
824         memset(cmd, 0, MAX_COMMAND_SIZE);
825         cmd[0] = TEST_UNIT_READY;
826
827         SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
828         *aSRpnt = SRpnt;
829         if (!SRpnt) return (-EBUSY);
830
831         while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
832                 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0  ) {
833 #if DEBUG
834             if (debugging) {
835                 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
836                 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
837                 debugging = 0;
838             }
839 #endif
840             msleep(100);
841
842             memset(cmd, 0, MAX_COMMAND_SIZE);
843             cmd[0] = TEST_UNIT_READY;
844
845             SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
846         }
847         *aSRpnt = SRpnt;
848 #if DEBUG
849         debugging = dbg;
850 #endif
851         if ( STp->buffer->syscall_result     && SRpnt->sense[2]  != 2 &&
852              SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) {
853 #if DEBUG
854             printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
855             printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
856                         STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
857                         SRpnt->sense[12], SRpnt->sense[13]);
858 #endif
859             return 0;
860         }
861 #if DEBUG
862         printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
863 #endif
864         return 1;
865 }
866
867 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame)
868 {
869         int     retval;
870
871         osst_wait_ready(STp, aSRpnt, 15 * 60, 0);                       /* TODO - can this catch a write error? */
872         retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
873         if (retval) return (retval);
874         osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
875         return (osst_get_frame_position(STp, aSRpnt));
876 }
877
878 /*
879  * Wait for write(s) to complete
880  */
881 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
882 {
883         unsigned char           cmd[MAX_COMMAND_SIZE];
884         struct osst_request   * SRpnt;
885         int                     result = 0;
886         int                     delay  = OSST_WAIT_WRITE_COMPLETE;
887 #if DEBUG
888         char                  * name = tape_name(STp);
889
890         printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
891 #endif
892
893         memset(cmd, 0, MAX_COMMAND_SIZE);
894         cmd[0] = WRITE_FILEMARKS;
895         cmd[1] = 1;
896
897         SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
898         *aSRpnt = SRpnt;
899         if (!SRpnt) return (-EBUSY);
900         if (STp->buffer->syscall_result) {
901                 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) {
902                         if (SRpnt->sense[13] == 8) {
903                                 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
904                         }
905                 } else
906                         result = osst_write_error_recovery(STp, aSRpnt, 0);
907         }
908         result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
909         STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
910
911         return (result);
912 }
913
914 #define OSST_POLL_PER_SEC 10
915 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to)
916 {
917         unsigned long   startwait = jiffies;
918         char          * name      = tape_name(STp);
919 #if DEBUG
920         char       notyetprinted  = 1;
921 #endif
922         if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
923                 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
924
925         while (time_before (jiffies, startwait + to*HZ))
926         { 
927                 int result;
928                 result = osst_get_frame_position(STp, aSRpnt);
929                 if (result == -EIO)
930                         if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
931                                 return 0;       /* successful recovery leaves drive ready for frame */
932                 if (result < 0) break;
933                 if (STp->first_frame_position == curr &&
934                     ((minlast < 0 &&
935                       (signed)STp->last_frame_position > (signed)curr + minlast) ||
936                      (minlast >= 0 && STp->cur_frames > minlast)
937                     ) && result >= 0)
938                 {
939 #if DEBUG                       
940                         if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC))
941                                 printk (OSST_DEB_MSG
942                                         "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
943                                         name, curr, curr+minlast, STp->first_frame_position,
944                                         STp->last_frame_position, STp->cur_frames,
945                                         result, (jiffies-startwait)/HZ, 
946                                         (((jiffies-startwait)%HZ)*10)/HZ);
947 #endif
948                         return 0;
949                 }
950 #if DEBUG
951                 if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted)
952                 {
953                         printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
954                                 name, curr, curr+minlast, STp->first_frame_position,
955                                 STp->last_frame_position, STp->cur_frames, result);
956                         notyetprinted--;
957                 }
958 #endif
959                 msleep(1000 / OSST_POLL_PER_SEC);
960         }
961 #if DEBUG
962         printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
963                 name, curr, curr+minlast, STp->first_frame_position,
964                 STp->last_frame_position, STp->cur_frames,
965                 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
966 #endif  
967         return -EBUSY;
968 }
969
970 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
971 {
972         struct osst_request   * SRpnt;
973         unsigned char           cmd[MAX_COMMAND_SIZE];
974         unsigned long           startwait = jiffies;
975         int                     retval    = 1;
976         char                  * name      = tape_name(STp);
977                                                                                                                                 
978         if (writing) {
979                 char    mybuf[24];
980                 char  * olddata = STp->buffer->b_data;
981                 int     oldsize = STp->buffer->buffer_size;
982
983                 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
984
985                 memset(cmd, 0, MAX_COMMAND_SIZE);
986                 cmd[0] = WRITE_FILEMARKS;
987                 cmd[1] = 1;
988                 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
989                                                                 MAX_RETRIES, 1);
990
991                 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
992
993                         if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) {
994
995                                 /* some failure - not just not-ready */
996                                 retval = osst_write_error_recovery(STp, aSRpnt, 0);
997                                 break;
998                         }
999                         schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
1000
1001                         STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
1002                         memset(cmd, 0, MAX_COMMAND_SIZE);
1003                         cmd[0] = READ_POSITION;
1004
1005                         SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
1006                                                                                 MAX_RETRIES, 1);
1007
1008                         retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
1009                         STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
1010                 }
1011                 if (retval)
1012                         printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
1013         } else
1014                 /* TODO - figure out which error conditions can be handled */
1015                 if (STp->buffer->syscall_result)
1016                         printk(KERN_WARNING
1017                                 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
1018                                         (*aSRpnt)->sense[ 2] & 0x0f,
1019                                         (*aSRpnt)->sense[12],
1020                                         (*aSRpnt)->sense[13]);
1021
1022         return retval;
1023 }
1024
1025 /*
1026  * Read the next OnStream tape frame at the current location
1027  */
1028 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
1029 {
1030         unsigned char           cmd[MAX_COMMAND_SIZE];
1031         struct osst_request   * SRpnt;
1032         int                     retval = 0;
1033 #if DEBUG
1034         os_aux_t              * aux    = STp->buffer->aux;
1035         char                  * name   = tape_name(STp);
1036 #endif
1037
1038         if (STp->poll)
1039                 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
1040                         retval = osst_recover_wait_frame(STp, aSRpnt, 0);
1041
1042         memset(cmd, 0, MAX_COMMAND_SIZE);
1043         cmd[0] = READ_6;
1044         cmd[1] = 1;
1045         cmd[4] = 1;
1046
1047 #if DEBUG
1048         if (debugging)
1049                 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
1050 #endif
1051         SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1052                                       STp->timeout, MAX_RETRIES, 1);
1053         *aSRpnt = SRpnt;
1054         if (!SRpnt)
1055                 return (-EBUSY);
1056
1057         if ((STp->buffer)->syscall_result) {
1058             retval = 1;
1059             if (STp->read_error_frame == 0) {
1060                 STp->read_error_frame = STp->first_frame_position;
1061 #if DEBUG
1062                 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
1063 #endif
1064             }
1065 #if DEBUG
1066             if (debugging)
1067                 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1068                    name,
1069                    SRpnt->sense[0], SRpnt->sense[1],
1070                    SRpnt->sense[2], SRpnt->sense[3],
1071                    SRpnt->sense[4], SRpnt->sense[5],
1072                    SRpnt->sense[6], SRpnt->sense[7]);
1073 #endif
1074         }
1075         else
1076             STp->first_frame_position++;
1077 #if DEBUG
1078         if (debugging) {
1079            char sig[8]; int i;
1080            for (i=0;i<4;i++)
1081                    sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
1082            sig[4] = '\0';
1083            printk(OSST_DEB_MSG 
1084                 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
1085                         ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
1086                         aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
1087                         aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL", 
1088                         ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
1089                         ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
1090            if (aux->frame_type==2)
1091                 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
1092                         ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
1093            printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
1094         }
1095 #endif
1096         return (retval);
1097 }
1098
1099 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
1100 {
1101         struct st_partstat    * STps   = &(STp->ps[STp->partition]);
1102         struct osst_request   * SRpnt  ;
1103         unsigned char           cmd[MAX_COMMAND_SIZE];
1104         int                     retval = 0;
1105         char                  * name   = tape_name(STp);
1106
1107         if (STps->rw != ST_READING) {         /* Initialize read operation */
1108                 if (STps->rw == ST_WRITING || STp->dirty) {
1109                         STp->write_type = OS_WRITE_DATA;
1110                         osst_flush_write_buffer(STp, aSRpnt);
1111                         osst_flush_drive_buffer(STp, aSRpnt);
1112                 }
1113                 STps->rw = ST_READING;
1114                 STp->frame_in_buffer = 0;
1115
1116                 /*
1117                  *      Issue a read 0 command to get the OnStream drive
1118                  *      read frames into its buffer.
1119                  */
1120                 memset(cmd, 0, MAX_COMMAND_SIZE);
1121                 cmd[0] = READ_6;
1122                 cmd[1] = 1;
1123
1124 #if DEBUG
1125                 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
1126 #endif
1127                 SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
1128                 *aSRpnt = SRpnt;
1129                 if ((retval = STp->buffer->syscall_result))
1130                         printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
1131         }
1132
1133         return retval;
1134 }
1135
1136 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt,
1137                                                 int frame_seq_number, int quiet)
1138 {
1139         struct st_partstat * STps  = &(STp->ps[STp->partition]);
1140         char               * name  = tape_name(STp);
1141         int                  cnt   = 0,
1142                              bad   = 0,
1143                              past  = 0,
1144                              x,
1145                              position;
1146
1147         /*
1148          * If we want just any frame (-1) and there is a frame in the buffer, return it
1149          */
1150         if (frame_seq_number == -1 && STp->frame_in_buffer) {
1151 #if DEBUG
1152                 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1153 #endif
1154                 return (STps->eof);
1155         }
1156         /*
1157          * Search and wait for the next logical tape frame
1158          */
1159         while (1) {
1160                 if (cnt++ > 400) {
1161                         printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1162                                             name, frame_seq_number);
1163                         if (STp->read_error_frame) {
1164                                 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1165 #if DEBUG
1166                                 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1167                                                     name, STp->read_error_frame);
1168 #endif
1169                                 STp->read_error_frame = 0;
1170                                 STp->abort_count++;
1171                         }
1172                         return (-EIO);
1173                 }
1174 #if DEBUG
1175                 if (debugging)
1176                         printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1177                                           name, frame_seq_number, cnt);
1178 #endif
1179                 if ( osst_initiate_read(STp, aSRpnt)
1180                 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1181                         if (STp->raw)
1182                                 return (-EIO);
1183                         position = osst_get_frame_position(STp, aSRpnt);
1184                         if (position >= 0xbae && position < 0xbb8)
1185                                 position = 0xbb8;
1186                         else if (position > STp->eod_frame_ppos || ++bad == 10) {
1187                                 position = STp->read_error_frame - 1;
1188                                 bad = 0;
1189                         }
1190                         else {
1191                                 position += 29;
1192                                 cnt      += 19;
1193                         }
1194 #if DEBUG
1195                         printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1196                                          name, position);
1197 #endif
1198                         osst_set_frame_position(STp, aSRpnt, position, 0);
1199                         continue;
1200                 }
1201                 if (osst_verify_frame(STp, frame_seq_number, quiet))
1202                         break;
1203                 if (osst_verify_frame(STp, -1, quiet)) {
1204                         x = ntohl(STp->buffer->aux->frame_seq_num);
1205                         if (STp->fast_open) {
1206                                 printk(KERN_WARNING
1207                                        "%s:W: Found logical frame %d instead of %d after fast open\n",
1208                                        name, x, frame_seq_number);
1209                                 STp->header_ok = 0;
1210                                 STp->read_error_frame = 0;
1211                                 return (-EIO);
1212                         }
1213                         if (x > frame_seq_number) {
1214                                 if (++past > 3) {
1215                                         /* positioning backwards did not bring us to the desired frame */
1216                                         position = STp->read_error_frame - 1;
1217                                 }
1218                                 else {
1219                                         position = osst_get_frame_position(STp, aSRpnt)
1220                                                  + frame_seq_number - x - 1;
1221
1222                                         if (STp->first_frame_position >= 3000 && position < 3000)
1223                                                 position -= 10;
1224                                 }
1225 #if DEBUG
1226                                 printk(OSST_DEB_MSG
1227                                        "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1228                                                 name, x, frame_seq_number,
1229                                                 STp->first_frame_position - position);
1230 #endif
1231                                 osst_set_frame_position(STp, aSRpnt, position, 0);
1232                                 cnt += 10;
1233                         }
1234                         else
1235                                 past = 0;
1236                 }
1237                 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1238 #if DEBUG
1239                         printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1240 #endif
1241                         osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1242                         cnt--;
1243                 }
1244                 STp->frame_in_buffer = 0;
1245         }
1246         if (cnt > 1) {
1247                 STp->recover_count++;
1248                 STp->recover_erreg++;
1249                 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n", 
1250                                         name, STp->read_error_frame);
1251         }
1252         STp->read_count++;
1253
1254 #if DEBUG
1255         if (debugging || STps->eof)
1256                 printk(OSST_DEB_MSG
1257                         "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1258                         name, frame_seq_number, STp->frame_seq_number, STps->eof);
1259 #endif
1260         STp->fast_open = 0;
1261         STp->read_error_frame = 0;
1262         return (STps->eof);
1263 }
1264
1265 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num)
1266 {
1267         struct st_partstat * STps = &(STp->ps[STp->partition]);
1268         char               * name = tape_name(STp);
1269         int     retries    = 0;
1270         int     frame_seq_estimate, ppos_estimate, move;
1271         
1272         if (logical_blk_num < 0) logical_blk_num = 0;
1273 #if DEBUG
1274         printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1275                                 name, logical_blk_num, STp->logical_blk_num, 
1276                                 STp->block_size<1024?STp->block_size:STp->block_size/1024,
1277                                 STp->block_size<1024?'b':'k');
1278 #endif
1279         /* Do we know where we are? */
1280         if (STps->drv_block >= 0) {
1281                 move                = logical_blk_num - STp->logical_blk_num;
1282                 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1283                 move               /= (OS_DATA_SIZE / STp->block_size);
1284                 frame_seq_estimate  = STp->frame_seq_number + move;
1285         } else
1286                 frame_seq_estimate  = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1287
1288         if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1289         else                           ppos_estimate = frame_seq_estimate + 20;
1290         while (++retries < 10) {
1291            if (ppos_estimate > STp->eod_frame_ppos-2) {
1292                frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1293                ppos_estimate       = STp->eod_frame_ppos - 2;
1294            }
1295            if (frame_seq_estimate < 0) {
1296                frame_seq_estimate = 0;
1297                ppos_estimate      = 10;
1298            }
1299            osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1300            if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1301               /* we've located the estimated frame, now does it have our block? */
1302               if (logical_blk_num <  STp->logical_blk_num ||
1303                   logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1304                  if (STps->eof == ST_FM_HIT)
1305                     move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1306                  else {
1307                     move                = logical_blk_num - STp->logical_blk_num;
1308                     if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1309                     move               /= (OS_DATA_SIZE / STp->block_size);
1310                  }
1311                  if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1312 #if DEBUG
1313                  printk(OSST_DEB_MSG
1314                         "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1315                                 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
1316                                 STp->logical_blk_num, logical_blk_num, move);
1317 #endif
1318                  frame_seq_estimate += move;
1319                  ppos_estimate      += move;
1320                  continue;
1321               } else {
1322                  STp->buffer->read_pointer  = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1323                  STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1324                  STp->logical_blk_num       =  logical_blk_num;
1325 #if DEBUG
1326                  printk(OSST_DEB_MSG 
1327                         "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1328                                 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer, 
1329                                 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size, 
1330                                 STp->block_size);
1331 #endif
1332                  STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1333                  if (STps->eof == ST_FM_HIT) {
1334                      STps->drv_file++;
1335                      STps->drv_block = 0;
1336                  } else {
1337                      STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1338                                           STp->logical_blk_num -
1339                                              (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1340                                         -1;
1341                  }
1342                  STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1343                  return 0;
1344               }
1345            }
1346            if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1347               goto error;
1348            /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1349 #if DEBUG
1350            printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n", 
1351                            name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
1352                            STp->logical_blk_num, logical_blk_num);
1353 #endif
1354            if (frame_seq_estimate != STp->frame_seq_number)
1355               ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1356            else
1357               break;
1358         }
1359 error:
1360         printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n", 
1361                             name, logical_blk_num, STp->logical_blk_num, retries);
1362         return (-EIO);
1363 }
1364
1365 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1366  * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1367  * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1368  * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1369  */
1370 #define OSST_FRAME_SHIFT  6
1371 #define OSST_SECTOR_SHIFT 9
1372 #define OSST_SECTOR_MASK  0x03F
1373
1374 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt)
1375 {
1376         int     sector;
1377 #if DEBUG
1378         char  * name = tape_name(STp);
1379         
1380         printk(OSST_DEB_MSG 
1381                 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1382                 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1383                 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block, 
1384                 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1385                 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1386                 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1387 #endif
1388         /* do we know where we are inside a file? */
1389         if (STp->ps[STp->partition].drv_block >= 0) {
1390                 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1391                                 STp->first_frame_position) << OSST_FRAME_SHIFT;
1392                 if (STp->ps[STp->partition].rw == ST_WRITING)
1393                         sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1394                 else
1395                         sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1396         } else {
1397                 sector = osst_get_frame_position(STp, aSRpnt);
1398                 if (sector > 0)
1399                         sector <<= OSST_FRAME_SHIFT;
1400         }
1401         return sector;
1402 }
1403
1404 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector)
1405 {
1406         struct st_partstat * STps   = &(STp->ps[STp->partition]);
1407         int                  frame  = sector >> OSST_FRAME_SHIFT,
1408                              offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 
1409                              r;
1410 #if DEBUG
1411         char          * name = tape_name(STp);
1412
1413         printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1414                                 name, sector, frame, offset);
1415 #endif
1416         if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1417
1418         if (frame <= STp->first_data_ppos) {
1419                 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1420                 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1421         }
1422         r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1423         if (r < 0) return r;
1424
1425         r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1426         if (r < 0) return r;
1427
1428         if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1429
1430         if (offset) {
1431                 STp->logical_blk_num      += offset / STp->block_size;
1432                 STp->buffer->read_pointer  = offset;
1433                 STp->buffer->buffer_bytes -= offset;
1434         } else {
1435                 STp->frame_seq_number++;
1436                 STp->frame_in_buffer       = 0;
1437                 STp->logical_blk_num      += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1438                 STp->buffer->buffer_bytes  = STp->buffer->read_pointer = 0;
1439         }
1440         STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1441         if (STps->eof == ST_FM_HIT) {
1442                 STps->drv_file++;
1443                 STps->drv_block = 0;
1444         } else {
1445                 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1446                                     STp->logical_blk_num -
1447                                         (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1448                                   -1;
1449         }
1450         STps->eof       = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1451 #if DEBUG
1452         printk(OSST_DEB_MSG 
1453                 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1454                 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1455                 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1456 #endif
1457         return 0;
1458 }
1459
1460 /*
1461  * Read back the drive's internal buffer contents, as a part
1462  * of the write error recovery mechanism for old OnStream
1463  * firmware revisions.
1464  * Precondition for this function to work: all frames in the
1465  * drive's buffer must be of one type (DATA, MARK or EOD)!
1466  */
1467 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
1468                                                 unsigned int frame, unsigned int skip, int pending)
1469 {
1470         struct osst_request   * SRpnt = * aSRpnt;
1471         unsigned char         * buffer, * p;
1472         unsigned char           cmd[MAX_COMMAND_SIZE];
1473         int                     flag, new_frame, i;
1474         int                     nframes          = STp->cur_frames;
1475         int                     blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1476         int                     frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1477                                                 - (nframes + pending - 1);
1478         int                     logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
1479                                                 - (nframes + pending - 1) * blks_per_frame;
1480         char                  * name             = tape_name(STp);
1481         unsigned long           startwait        = jiffies;
1482 #if DEBUG
1483         int                     dbg              = debugging;
1484 #endif
1485
1486         if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
1487                 return (-EIO);
1488
1489         printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1490                          name, nframes, pending?" and one that was pending":"");
1491
1492         osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1493 #if DEBUG
1494         if (pending && debugging)
1495                 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1496                                 name, frame_seq_number + nframes,
1497                                 logical_blk_num + nframes * blks_per_frame,
1498                                 p[0], p[1], p[2], p[3]);
1499 #endif
1500         for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1501
1502                 memset(cmd, 0, MAX_COMMAND_SIZE);
1503                 cmd[0] = 0x3C;          /* Buffer Read           */
1504                 cmd[1] = 6;             /* Retrieve Faulty Block */
1505                 cmd[7] = 32768 >> 8;
1506                 cmd[8] = 32768 & 0xff;
1507
1508                 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1509                                             STp->timeout, MAX_RETRIES, 1);
1510         
1511                 if ((STp->buffer)->syscall_result || !SRpnt) {
1512                         printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1513                         vfree(buffer);
1514                         *aSRpnt = SRpnt;
1515                         return (-EIO);
1516                 }
1517                 osst_copy_from_buffer(STp->buffer, p);
1518 #if DEBUG
1519                 if (debugging)
1520                         printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1521                                           name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1522 #endif
1523         }
1524         *aSRpnt = SRpnt;
1525         osst_get_frame_position(STp, aSRpnt);
1526
1527 #if DEBUG
1528         printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1529 #endif
1530         /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1531         /* In the header we don't actually re-write the frames that fail, just the ones after them */
1532
1533         for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1534
1535                 if (flag) {
1536                         if (STp->write_type == OS_WRITE_HEADER) {
1537                                 i += skip;
1538                                 p += skip * OS_DATA_SIZE;
1539                         }
1540                         else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1541                                 new_frame = 3000-i;
1542                         else
1543                                 new_frame += skip;
1544 #if DEBUG
1545                         printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1546                                                 name, new_frame+i, frame_seq_number+i);
1547 #endif
1548                         osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1549                         osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1550                         osst_get_frame_position(STp, aSRpnt);
1551                         SRpnt = * aSRpnt;
1552
1553                         if (new_frame > frame + 1000) {
1554                                 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1555                                 vfree(buffer);
1556                                 return (-EIO);
1557                         }
1558                         if ( i >= nframes + pending ) break;
1559                         flag = 0;
1560                 }
1561                 osst_copy_to_buffer(STp->buffer, p);
1562                 /*
1563                  * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1564                  */
1565                 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1566                                 logical_blk_num + i*blks_per_frame,
1567                                 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1568                 memset(cmd, 0, MAX_COMMAND_SIZE);
1569                 cmd[0] = WRITE_6;
1570                 cmd[1] = 1;
1571                 cmd[4] = 1;
1572
1573 #if DEBUG
1574                 if (debugging)
1575                         printk(OSST_DEB_MSG
1576                                 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1577                                 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1578                                 p[0], p[1], p[2], p[3]);
1579 #endif
1580                 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1581                                             STp->timeout, MAX_RETRIES, 1);
1582
1583                 if (STp->buffer->syscall_result)
1584                         flag = 1;
1585                 else {
1586                         p += OS_DATA_SIZE; i++;
1587
1588                         /* if we just sent the last frame, wait till all successfully written */
1589                         if ( i == nframes + pending ) {
1590 #if DEBUG
1591                                 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1592 #endif
1593                                 memset(cmd, 0, MAX_COMMAND_SIZE);
1594                                 cmd[0] = WRITE_FILEMARKS;
1595                                 cmd[1] = 1;
1596                                 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1597                                                             STp->timeout, MAX_RETRIES, 1);
1598 #if DEBUG
1599                                 if (debugging) {
1600                                         printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1601                                         printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1602                                         debugging = 0;
1603                                 }
1604 #endif
1605                                 flag = STp->buffer->syscall_result;
1606                                 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1607
1608                                         memset(cmd, 0, MAX_COMMAND_SIZE);
1609                                         cmd[0] = TEST_UNIT_READY;
1610
1611                                         SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1612                                                                                                 MAX_RETRIES, 1);
1613
1614                                         if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
1615                                             (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
1616                                                 /* in the process of becoming ready */
1617                                                 msleep(100);
1618                                                 continue;
1619                                         }
1620                                         if (STp->buffer->syscall_result)
1621                                                 flag = 1;
1622                                         break;
1623                                 }
1624 #if DEBUG
1625                                 debugging = dbg;
1626                                 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1627 #endif
1628                         }
1629                 }
1630                 *aSRpnt = SRpnt;
1631                 if (flag) {
1632                         if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1633                              SRpnt->sense[12]         ==  0 &&
1634                              SRpnt->sense[13]         ==  2) {
1635                                 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1636                                 vfree(buffer);
1637                                 return (-EIO);                  /* hit end of tape = fail */
1638                         }
1639                         i = ((SRpnt->sense[3] << 24) |
1640                              (SRpnt->sense[4] << 16) |
1641                              (SRpnt->sense[5] <<  8) |
1642                               SRpnt->sense[6]        ) - new_frame;
1643                         p = &buffer[i * OS_DATA_SIZE];
1644 #if DEBUG
1645                         printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1646 #endif
1647                         osst_get_frame_position(STp, aSRpnt);
1648 #if DEBUG
1649                         printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1650                                           name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1651 #endif
1652                 }
1653         }
1654         if (flag) {
1655                 /* error recovery did not successfully complete */
1656                 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1657                                 STp->write_type == OS_WRITE_HEADER?"header":"body");
1658         }
1659         if (!pending)
1660                 osst_copy_to_buffer(STp->buffer, p);    /* so buffer content == at entry in all cases */
1661         vfree(buffer);
1662         return 0;
1663 }
1664
1665 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
1666                                         unsigned int frame, unsigned int skip, int pending)
1667 {
1668         unsigned char           cmd[MAX_COMMAND_SIZE];
1669         struct osst_request   * SRpnt;
1670         char                  * name      = tape_name(STp);
1671         int                     expected  = 0;
1672         int                     attempts  = 1000 / skip;
1673         int                     flag      = 1;
1674         unsigned long           startwait = jiffies;
1675 #if DEBUG
1676         int                     dbg       = debugging;
1677 #endif
1678
1679         while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1680                 if (flag) {
1681 #if DEBUG
1682                         debugging = dbg;
1683 #endif
1684                         if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1685                                 frame = 3000-skip;
1686                         expected = frame+skip+STp->cur_frames+pending;
1687 #if DEBUG
1688                         printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1689                                           name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1690 #endif
1691                         osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1692                         flag = 0;
1693                         attempts--;
1694                         schedule_timeout_interruptible(msecs_to_jiffies(100));
1695                 }
1696                 if (osst_get_frame_position(STp, aSRpnt) < 0) {         /* additional write error */
1697 #if DEBUG
1698                         printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1699                                           name, STp->first_frame_position,
1700                                           STp->last_frame_position, STp->cur_frames);
1701 #endif
1702                         frame = STp->last_frame_position;
1703                         flag = 1;
1704                         continue;
1705                 }
1706                 if (pending && STp->cur_frames < 50) {
1707
1708                         memset(cmd, 0, MAX_COMMAND_SIZE);
1709                         cmd[0] = WRITE_6;
1710                         cmd[1] = 1;
1711                         cmd[4] = 1;
1712 #if DEBUG
1713                         printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1714                                           name, STp->frame_seq_number-1, STp->first_frame_position);
1715 #endif
1716                         SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1717                                                       STp->timeout, MAX_RETRIES, 1);
1718                         *aSRpnt = SRpnt;
1719
1720                         if (STp->buffer->syscall_result) {              /* additional write error */
1721                                 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1722                                      SRpnt->sense[12]         ==  0 &&
1723                                      SRpnt->sense[13]         ==  2) {
1724                                         printk(KERN_ERR
1725                                                "%s:E: Volume overflow in write error recovery\n",
1726                                                name);
1727                                         break;                          /* hit end of tape = fail */
1728                                 }
1729                                 flag = 1;
1730                         }
1731                         else
1732                                 pending = 0;
1733
1734                         continue;
1735                 }
1736                 if (STp->cur_frames == 0) {
1737 #if DEBUG
1738                         debugging = dbg;
1739                         printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1740 #endif
1741                         if (STp->first_frame_position != expected) {
1742                                 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n", 
1743                                                 name, STp->first_frame_position, expected);
1744                                 return (-EIO);
1745                         }
1746                         return 0;
1747                 }
1748 #if DEBUG
1749                 if (debugging) {
1750                         printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1751                         printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1752                         debugging = 0;
1753                 }
1754 #endif
1755                 schedule_timeout_interruptible(msecs_to_jiffies(100));
1756         }
1757         printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1758 #if DEBUG
1759         debugging = dbg;
1760 #endif
1761         return (-EIO);
1762 }
1763
1764 /*
1765  * Error recovery algorithm for the OnStream tape.
1766  */
1767
1768 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending)
1769 {
1770         struct osst_request * SRpnt  = * aSRpnt;
1771         struct st_partstat  * STps   = & STp->ps[STp->partition];
1772         char                * name   = tape_name(STp);
1773         int                   retval = 0;
1774         int                   rw_state;
1775         unsigned int          frame, skip;
1776
1777         rw_state = STps->rw;
1778
1779         if ((SRpnt->sense[ 2] & 0x0f) != 3
1780           || SRpnt->sense[12]         != 12
1781           || SRpnt->sense[13]         != 0) {
1782 #if DEBUG
1783                 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1784                         SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]);
1785 #endif
1786                 return (-EIO);
1787         }
1788         frame = (SRpnt->sense[3] << 24) |
1789                 (SRpnt->sense[4] << 16) |
1790                 (SRpnt->sense[5] <<  8) |
1791                  SRpnt->sense[6];
1792         skip  =  SRpnt->sense[9];
1793  
1794 #if DEBUG
1795         printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1796 #endif
1797         osst_get_frame_position(STp, aSRpnt);
1798 #if DEBUG
1799         printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1800                         name, STp->first_frame_position, STp->last_frame_position);
1801 #endif
1802         switch (STp->write_type) {
1803            case OS_WRITE_DATA:
1804            case OS_WRITE_EOD:
1805            case OS_WRITE_NEW_MARK:
1806                 printk(KERN_WARNING 
1807                         "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1808                         name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1809                 if (STp->os_fw_rev >= 10600)
1810                         retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1811                 else
1812                         retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1813                 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1814                                 retval?"E"    :"I",
1815                                 retval?""     :"Don't worry, ",
1816                                 retval?" not ":" ");
1817                 break;
1818            case OS_WRITE_LAST_MARK:
1819                 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1820                 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1821                 retval = -EIO;
1822                 break;
1823            case OS_WRITE_HEADER:
1824                 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1825                 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1826                 break;
1827            default:
1828                 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1829                 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1830         }
1831         osst_get_frame_position(STp, aSRpnt);
1832 #if DEBUG
1833         printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n", 
1834                         name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1835         printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1836 #endif
1837         if (retval == 0) {
1838                 STp->recover_count++;
1839                 STp->recover_erreg++;
1840         } else
1841                 STp->abort_count++;
1842
1843         STps->rw = rw_state;
1844         return retval;
1845 }
1846
1847 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt,
1848                                                                  int mt_op, int mt_count)
1849 {
1850         char  * name = tape_name(STp);
1851         int     cnt;
1852         int     last_mark_ppos = -1;
1853
1854 #if DEBUG
1855         printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1856 #endif
1857         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1858 #if DEBUG
1859                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1860 #endif
1861                 return -EIO;
1862         }
1863         if (STp->linux_media_version >= 4) {
1864                 /*
1865                  * direct lookup in header filemark list
1866                  */
1867                 cnt = ntohl(STp->buffer->aux->filemark_cnt);
1868                 if (STp->header_ok                         && 
1869                     STp->header_cache != NULL              &&
1870                     (cnt - mt_count)  >= 0                 &&
1871                     (cnt - mt_count)   < OS_FM_TAB_MAX     &&
1872                     (cnt - mt_count)   < STp->filemark_cnt &&
1873                     STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1874
1875                         last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1876 #if DEBUG
1877                 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1878                         printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1879                                STp->header_cache == NULL?"lack of header cache":"count out of range");
1880                 else
1881                         printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1882                                 name, cnt,
1883                                 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1884                                  (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1885                                          STp->buffer->aux->last_mark_ppos))?"match":"error",
1886                                mt_count, last_mark_ppos);
1887 #endif
1888                 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1889                         osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1890                         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1891 #if DEBUG
1892                                 printk(OSST_DEB_MSG 
1893                                         "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1894 #endif
1895                                 return (-EIO);
1896                         }
1897                         if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1898                                 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1899                                                  name, last_mark_ppos);
1900                                 return (-EIO);
1901                         }
1902                         goto found;
1903                 }
1904 #if DEBUG
1905                 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1906 #endif
1907         }
1908         cnt = 0;
1909         while (cnt != mt_count) {
1910                 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1911                 if (last_mark_ppos == -1)
1912                         return (-EIO);
1913 #if DEBUG
1914                 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1915 #endif
1916                 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1917                 cnt++;
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", name);
1921 #endif
1922                         return (-EIO);
1923                 }
1924                 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1925                         printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1926                                          name, last_mark_ppos);
1927                         return (-EIO);
1928                 }
1929         }
1930 found:
1931         if (mt_op == MTBSFM) {
1932                 STp->frame_seq_number++;
1933                 STp->frame_in_buffer      = 0;
1934                 STp->buffer->buffer_bytes = 0;
1935                 STp->buffer->read_pointer = 0;
1936                 STp->logical_blk_num     += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1937         }
1938         return 0;
1939 }
1940
1941 /*
1942  * ADRL 1.1 compatible "slow" space filemarks fwd version
1943  *
1944  * Just scans for the filemark sequentially.
1945  */
1946 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt,
1947                                                                      int mt_op, int mt_count)
1948 {
1949         int     cnt = 0;
1950 #if DEBUG
1951         char  * name = tape_name(STp);
1952
1953         printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1954 #endif
1955         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1956 #if DEBUG
1957                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1958 #endif
1959                 return (-EIO);
1960         }
1961         while (1) {
1962                 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1963 #if DEBUG
1964                         printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1965 #endif
1966                         return (-EIO);
1967                 }
1968                 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1969                         cnt++;
1970                 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1971 #if DEBUG
1972                         printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1973 #endif
1974                         if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1975 #if DEBUG
1976                                 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1977                                                 name, STp->eod_frame_ppos, STp->first_frame_position-1);
1978 #endif
1979                                 STp->eod_frame_ppos = STp->first_frame_position-1;
1980                         }
1981                         return (-EIO);
1982                 }
1983                 if (cnt == mt_count)
1984                         break;
1985                 STp->frame_in_buffer = 0;
1986         }
1987         if (mt_op == MTFSF) {
1988                 STp->frame_seq_number++;
1989                 STp->frame_in_buffer      = 0;
1990                 STp->buffer->buffer_bytes = 0;
1991                 STp->buffer->read_pointer = 0;
1992                 STp->logical_blk_num     += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1993         }
1994         return 0;
1995 }
1996
1997 /*
1998  * Fast linux specific version of OnStream FSF
1999  */
2000 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt,
2001                                                                      int mt_op, int mt_count)
2002 {
2003         char  * name = tape_name(STp);
2004         int     cnt  = 0,
2005                 next_mark_ppos = -1;
2006
2007 #if DEBUG
2008         printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
2009 #endif
2010         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2011 #if DEBUG
2012                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
2013 #endif
2014                 return (-EIO);
2015         }
2016
2017         if (STp->linux_media_version >= 4) {
2018                 /*
2019                  * direct lookup in header filemark list
2020                  */
2021                 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
2022                 if (STp->header_ok                         && 
2023                     STp->header_cache != NULL              &&
2024                     (cnt + mt_count)   < OS_FM_TAB_MAX     &&
2025                     (cnt + mt_count)   < STp->filemark_cnt &&
2026                     ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2027                      (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
2028
2029                         next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
2030 #if DEBUG
2031                 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
2032                         printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
2033                                STp->header_cache == NULL?"lack of header cache":"count out of range");
2034                 else
2035                         printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
2036                                name, cnt,
2037                                ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2038                                 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
2039                                          STp->buffer->aux->last_mark_ppos))?"match":"error",
2040                                mt_count, next_mark_ppos);
2041 #endif
2042                 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
2043 #if DEBUG
2044                         printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2045 #endif
2046                         return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2047                 } else {
2048                         osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2049                         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2050 #if DEBUG
2051                                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2052                                                  name);
2053 #endif
2054                                 return (-EIO);
2055                         }
2056                         if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2057                                 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2058                                                  name, next_mark_ppos);
2059                                 return (-EIO);
2060                         }
2061                         if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
2062                                 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
2063                                                  name, cnt+mt_count, next_mark_ppos,
2064                                                  ntohl(STp->buffer->aux->filemark_cnt));
2065                                 return (-EIO);
2066                         }
2067                 }
2068         } else {
2069                 /*
2070                  * Find nearest (usually previous) marker, then jump from marker to marker
2071                  */
2072                 while (1) {
2073                         if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
2074                                 break;
2075                         if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
2076 #if DEBUG
2077                                 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
2078 #endif
2079                                 return (-EIO);
2080                         }
2081                         if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
2082                                 if (STp->first_mark_ppos == -1) {
2083 #if DEBUG
2084                                         printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2085 #endif
2086                                         return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2087                                 }
2088                                 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
2089                                 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2090 #if DEBUG
2091                                         printk(OSST_DEB_MSG
2092                                                "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2093                                                name);
2094 #endif
2095                                         return (-EIO);
2096                                 }
2097                                 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2098                                         printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
2099                                                          name, STp->first_mark_ppos);
2100                                         return (-EIO);
2101                                 }
2102                         } else {
2103                                 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
2104                                         return (-EIO);
2105                                 mt_count++;
2106                         }
2107                 }
2108                 cnt++;
2109                 while (cnt != mt_count) {
2110                         next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
2111                         if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
2112 #if DEBUG
2113                                 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2114 #endif
2115                                 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
2116                         }
2117 #if DEBUG
2118                         else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
2119 #endif
2120                         osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2121                         cnt++;
2122                         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2123 #if DEBUG
2124                                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2125                                                  name);
2126 #endif
2127                                 return (-EIO);
2128                         }
2129                         if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2130                                 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2131                                                  name, next_mark_ppos);
2132                                 return (-EIO);
2133                         }
2134                 }
2135         }
2136         if (mt_op == MTFSF) {
2137                 STp->frame_seq_number++;
2138                 STp->frame_in_buffer      = 0;
2139                 STp->buffer->buffer_bytes = 0;
2140                 STp->buffer->read_pointer = 0;
2141                 STp->logical_blk_num     += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2142         }
2143         return 0;
2144 }
2145
2146 /*
2147  * In debug mode, we want to see as many errors as possible
2148  * to test the error recovery mechanism.
2149  */
2150 #if DEBUG
2151 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries)
2152 {
2153         unsigned char           cmd[MAX_COMMAND_SIZE];
2154         struct osst_request   * SRpnt  = * aSRpnt;
2155         char                  * name   = tape_name(STp);
2156
2157         memset(cmd, 0, MAX_COMMAND_SIZE);
2158         cmd[0] = MODE_SELECT;
2159         cmd[1] = 0x10;
2160         cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2161
2162         (STp->buffer)->b_data[0] = cmd[4] - 1;
2163         (STp->buffer)->b_data[1] = 0;                   /* Medium Type - ignoring */
2164         (STp->buffer)->b_data[2] = 0;                   /* Reserved */
2165         (STp->buffer)->b_data[3] = 0;                   /* Block Descriptor Length */
2166         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2167         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2168         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2169         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2170
2171         if (debugging)
2172             printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2173
2174         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2175         *aSRpnt = SRpnt;
2176
2177         if ((STp->buffer)->syscall_result)
2178             printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2179 }
2180 #endif
2181
2182
2183 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt)
2184 {
2185         int     result;
2186         int     this_mark_ppos = STp->first_frame_position;
2187         int     this_mark_lbn  = STp->logical_blk_num;
2188 #if DEBUG
2189         char  * name = tape_name(STp);
2190 #endif
2191
2192         if (STp->raw) return 0;
2193
2194         STp->write_type = OS_WRITE_NEW_MARK;
2195 #if DEBUG
2196         printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n", 
2197                name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2198 #endif
2199         STp->dirty = 1;
2200         result  = osst_flush_write_buffer(STp, aSRpnt);
2201         result |= osst_flush_drive_buffer(STp, aSRpnt);
2202         STp->last_mark_ppos = this_mark_ppos;
2203         STp->last_mark_lbn  = this_mark_lbn;
2204         if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2205                 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2206         if (STp->filemark_cnt++ == 0)
2207                 STp->first_mark_ppos = this_mark_ppos;
2208         return result;
2209 }
2210
2211 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt)
2212 {
2213         int     result;
2214 #if DEBUG
2215         char  * name = tape_name(STp);
2216 #endif
2217
2218         if (STp->raw) return 0;
2219
2220         STp->write_type = OS_WRITE_EOD;
2221         STp->eod_frame_ppos = STp->first_frame_position;
2222 #if DEBUG
2223         printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2224                         STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2225 #endif
2226         STp->dirty = 1;
2227
2228         result  = osst_flush_write_buffer(STp, aSRpnt); 
2229         result |= osst_flush_drive_buffer(STp, aSRpnt);
2230         STp->eod_frame_lfa = --(STp->frame_seq_number);
2231         return result;
2232 }
2233
2234 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2235 {
2236         char * name = tape_name(STp);
2237
2238 #if DEBUG
2239         printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2240 #endif
2241         osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2242         osst_set_frame_position(STp, aSRpnt, where, 0);
2243         STp->write_type = OS_WRITE_FILLER;
2244         while (count--) {
2245                 memcpy(STp->buffer->b_data, "Filler", 6);
2246                 STp->buffer->buffer_bytes = 6;
2247                 STp->dirty = 1;
2248                 if (osst_flush_write_buffer(STp, aSRpnt)) {
2249                         printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2250                         return (-EIO);
2251                 }
2252         }
2253 #if DEBUG
2254         printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2255 #endif
2256         return osst_flush_drive_buffer(STp, aSRpnt);
2257 }
2258
2259 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2260 {
2261         char * name = tape_name(STp);
2262         int     result;
2263
2264 #if DEBUG
2265         printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2266 #endif
2267         osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2268         osst_set_frame_position(STp, aSRpnt, where, 0);
2269         STp->write_type = OS_WRITE_HEADER;
2270         while (count--) {
2271                 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2272                 STp->buffer->buffer_bytes = sizeof(os_header_t);
2273                 STp->dirty = 1;
2274                 if (osst_flush_write_buffer(STp, aSRpnt)) {
2275                         printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2276                         return (-EIO);
2277                 }
2278         }
2279         result = osst_flush_drive_buffer(STp, aSRpnt);
2280 #if DEBUG
2281         printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2282 #endif
2283         return result;
2284 }
2285
2286 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod)
2287 {
2288         os_header_t * header;
2289         int           result;
2290         char        * name = tape_name(STp);
2291
2292 #if DEBUG
2293         printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2294 #endif
2295         if (STp->raw) return 0;
2296
2297         if (STp->header_cache == NULL) {
2298                 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2299                         printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2300                         return (-ENOMEM);
2301                 }
2302                 memset(STp->header_cache, 0, sizeof(os_header_t));
2303 #if DEBUG
2304                 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2305 #endif
2306         }
2307         if (STp->header_ok) STp->update_frame_cntr++;
2308         else                STp->update_frame_cntr = 0;
2309
2310         header = STp->header_cache;
2311         strcpy(header->ident_str, "ADR_SEQ");
2312         header->major_rev      = 1;
2313         header->minor_rev      = 4;
2314         header->ext_trk_tb_off = htons(17192);
2315         header->pt_par_num     = 1;
2316         header->partition[0].partition_num              = OS_DATA_PARTITION;
2317         header->partition[0].par_desc_ver               = OS_PARTITION_VERSION;
2318         header->partition[0].wrt_pass_cntr              = htons(STp->wrt_pass_cntr);
2319         header->partition[0].first_frame_ppos           = htonl(STp->first_data_ppos);
2320         header->partition[0].last_frame_ppos            = htonl(STp->capacity);
2321         header->partition[0].eod_frame_ppos             = htonl(STp->eod_frame_ppos);
2322         header->cfg_col_width                           = htonl(20);
2323         header->dat_col_width                           = htonl(1500);
2324         header->qfa_col_width                           = htonl(0);
2325         header->ext_track_tb.nr_stream_part             = 1;
2326         header->ext_track_tb.et_ent_sz                  = 32;
2327         header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2328         header->ext_track_tb.dat_ext_trk_ey.fmt         = 1;
2329         header->ext_track_tb.dat_ext_trk_ey.fm_tab_off  = htons(17736);
2330         header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2331         header->ext_track_tb.dat_ext_trk_ey.last_hlb    = htonl(STp->eod_frame_lfa);
2332         header->ext_track_tb.dat_ext_trk_ey.last_pp     = htonl(STp->eod_frame_ppos);
2333         header->dat_fm_tab.fm_part_num                  = 0;
2334         header->dat_fm_tab.fm_tab_ent_sz                = 4;
2335         header->dat_fm_tab.fm_tab_ent_cnt               = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2336                                                                 STp->filemark_cnt:OS_FM_TAB_MAX);
2337
2338         result  = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2339         if (STp->update_frame_cntr == 0)
2340                     osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2341         result &= __osst_write_header(STp, aSRpnt,     5, 5);
2342
2343         if (locate_eod) {
2344 #if DEBUG
2345                 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2346 #endif
2347                 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2348         }
2349         if (result)
2350                 printk(KERN_ERR "%s:E: Write header failed\n", name);
2351         else {
2352                 memcpy(STp->application_sig, "LIN4", 4);
2353                 STp->linux_media         = 1;
2354                 STp->linux_media_version = 4;
2355                 STp->header_ok           = 1;
2356         }
2357         return result;
2358 }
2359
2360 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt)
2361 {
2362         if (STp->header_cache != NULL)
2363                 memset(STp->header_cache, 0, sizeof(os_header_t));
2364
2365         STp->logical_blk_num = STp->frame_seq_number = 0;
2366         STp->frame_in_buffer = 0;
2367         STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2368         STp->filemark_cnt = 0;
2369         STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2370         return osst_write_header(STp, aSRpnt, 1);
2371 }
2372
2373 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos)
2374 {
2375         char        * name = tape_name(STp);
2376         os_header_t * header;
2377         os_aux_t    * aux;
2378         char          id_string[8];
2379         int           linux_media_version,
2380                       update_frame_cntr;
2381
2382         if (STp->raw)
2383                 return 1;
2384
2385         if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2386                 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2387                         printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2388                 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2389                 if (osst_initiate_read (STp, aSRpnt)) {
2390                         printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2391                         return 0;
2392                 }
2393         }
2394         if (osst_read_frame(STp, aSRpnt, 180)) {
2395 #if DEBUG
2396                 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2397 #endif
2398                 return 0;
2399         }
2400         header = (os_header_t *) STp->buffer->b_data;   /* warning: only first segment addressable */
2401         aux = STp->buffer->aux;
2402         if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2403 #if DEBUG
2404                 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2405 #endif
2406                 return 0;
2407         }
2408         if (ntohl(aux->frame_seq_num)              != 0                   ||
2409             ntohl(aux->logical_blk_num)            != 0                   ||
2410                   aux->partition.partition_num     != OS_CONFIG_PARTITION ||
2411             ntohl(aux->partition.first_frame_ppos) != 0                   ||
2412             ntohl(aux->partition.last_frame_ppos)  != 0xbb7               ) {
2413 #if DEBUG
2414                 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2415                                 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2416                                 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2417                                 ntohl(aux->partition.last_frame_ppos));
2418 #endif
2419                 return 0;
2420         }
2421         if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2422             strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2423                 strlcpy(id_string, header->ident_str, 8);
2424 #if DEBUG
2425                 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2426 #endif
2427                 return 0;
2428         }
2429         update_frame_cntr = ntohl(aux->update_frame_cntr);
2430         if (update_frame_cntr < STp->update_frame_cntr) {
2431 #if DEBUG
2432                 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2433                                    name, ppos, update_frame_cntr, STp->update_frame_cntr);
2434 #endif
2435                 return 0;
2436         }
2437         if (header->major_rev != 1 || header->minor_rev != 4 ) {
2438 #if DEBUG
2439                 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n", 
2440                                  name, (header->major_rev != 1 || header->minor_rev < 2 || 
2441                                        header->minor_rev  > 4 )? "Invalid" : "Warning:",
2442                                  header->major_rev, header->minor_rev);
2443 #endif
2444                 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2445                         return 0;
2446         }
2447 #if DEBUG
2448         if (header->pt_par_num != 1)
2449                 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n", 
2450                                  name, header->pt_par_num);
2451 #endif
2452         memcpy(id_string, aux->application_sig, 4);
2453         id_string[4] = 0;
2454         if (memcmp(id_string, "LIN", 3) == 0) {
2455                 STp->linux_media = 1;
2456                 linux_media_version = id_string[3] - '0';
2457                 if (linux_media_version != 4)
2458                         printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2459                                          name, linux_media_version);
2460         } else {
2461                 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2462                 return 0;
2463         }
2464         if (linux_media_version < STp->linux_media_version) {
2465 #if DEBUG
2466                 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2467                                   name, ppos, linux_media_version);
2468 #endif
2469                 return 0;
2470         }
2471         if (linux_media_version > STp->linux_media_version) {
2472 #if DEBUG
2473                 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2474                                    name, ppos, linux_media_version);
2475 #endif
2476                 memcpy(STp->application_sig, id_string, 5);
2477                 STp->linux_media_version = linux_media_version;
2478                 STp->update_frame_cntr = -1;
2479         }
2480         if (update_frame_cntr > STp->update_frame_cntr) {
2481 #if DEBUG
2482                 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2483                                    name, ppos, update_frame_cntr);
2484 #endif
2485                 if (STp->header_cache == NULL) {
2486                         if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
2487                                 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2488                                 return 0;
2489                         }
2490 #if DEBUG
2491                         printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2492 #endif
2493                 }
2494                 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2495                 header = STp->header_cache;     /* further accesses from cached (full) copy */
2496
2497                 STp->wrt_pass_cntr     = ntohs(header->partition[0].wrt_pass_cntr);
2498                 STp->first_data_ppos   = ntohl(header->partition[0].first_frame_ppos);
2499                 STp->eod_frame_ppos    = ntohl(header->partition[0].eod_frame_ppos);
2500                 STp->eod_frame_lfa     = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2501                 STp->filemark_cnt      = ntohl(aux->filemark_cnt);
2502                 STp->first_mark_ppos   = ntohl(aux->next_mark_ppos);
2503                 STp->last_mark_ppos    = ntohl(aux->last_mark_ppos);
2504                 STp->last_mark_lbn     = ntohl(aux->last_mark_lbn);
2505                 STp->update_frame_cntr = update_frame_cntr;
2506 #if DEBUG
2507         printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2508                           name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2509         printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2510                           STp->first_data_ppos,
2511                           ntohl(header->partition[0].last_frame_ppos),
2512                           ntohl(header->partition[0].eod_frame_ppos));
2513         printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n", 
2514                           name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2515 #endif
2516                 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2517 #if DEBUG
2518                         printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2519 #endif
2520                         memcpy((void *)header->dat_fm_tab.fm_tab_ent, 
2521                                (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2522                         memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2523                 }
2524                 if (header->minor_rev == 4   &&
2525                     (header->ext_trk_tb_off                          != htons(17192)               ||
2526                      header->partition[0].partition_num              != OS_DATA_PARTITION          ||
2527                      header->partition[0].par_desc_ver               != OS_PARTITION_VERSION       ||
2528                      header->partition[0].last_frame_ppos            != htonl(STp->capacity)       ||
2529                      header->cfg_col_width                           != htonl(20)                  ||
2530                      header->dat_col_width                           != htonl(1500)                ||
2531                      header->qfa_col_width                           != htonl(0)                   ||
2532                      header->ext_track_tb.nr_stream_part             != 1                          ||
2533                      header->ext_track_tb.et_ent_sz                  != 32                         ||
2534                      header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION          ||
2535                      header->ext_track_tb.dat_ext_trk_ey.fmt         != 1                          ||
2536                      header->ext_track_tb.dat_ext_trk_ey.fm_tab_off  != htons(17736)               ||
2537                      header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0                          ||
2538                      header->ext_track_tb.dat_ext_trk_ey.last_pp     != htonl(STp->eod_frame_ppos) ||
2539                      header->dat_fm_tab.fm_part_num                  != OS_DATA_PARTITION          ||
2540                      header->dat_fm_tab.fm_tab_ent_sz                != 4                          ||
2541                      header->dat_fm_tab.fm_tab_ent_cnt               !=
2542                              htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2543                         printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2544
2545         }
2546
2547         return 1;
2548 }
2549
2550 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt)
2551 {
2552         int     position, ppos;
2553         int     first, last;
2554         int     valid = 0;
2555         char  * name  = tape_name(STp);
2556
2557         position = osst_get_frame_position(STp, aSRpnt);
2558
2559         if (STp->raw) {
2560                 STp->header_ok = STp->linux_media = 1;
2561                 STp->linux_media_version = 0;
2562                 return 1;
2563         }
2564         STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2565         STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2566         STp->eod_frame_ppos = STp->first_data_ppos = -1;
2567         STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2568 #if DEBUG
2569         printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2570 #endif
2571
2572         /* optimization for speed - if we are positioned at ppos 10, read second group first  */        
2573         /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2574
2575         first = position==10?0xbae: 5;
2576         last  = position==10?0xbb3:10;
2577
2578         for (ppos = first; ppos < last; ppos++)
2579                 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2580                         valid = 1;
2581
2582         first = position==10? 5:0xbae;
2583         last  = position==10?10:0xbb3;
2584
2585         for (ppos = first; ppos < last; ppos++)
2586                 if (__osst_analyze_headers(STp, aSRpnt, ppos))
2587                         valid = 1;
2588
2589         if (!valid) {
2590                 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2591                 STp->eod_frame_ppos = STp->first_data_ppos = 0;
2592                 osst_set_frame_position(STp, aSRpnt, 10, 0);
2593                 return 0;
2594         }
2595         if (position <= STp->first_data_ppos) {
2596                 position = STp->first_data_ppos;
2597                 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2598         }
2599         osst_set_frame_position(STp, aSRpnt, position, 0);
2600         STp->header_ok = 1;
2601
2602         return 1;
2603 }
2604
2605 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt)
2606 {
2607         int     frame_position  = STp->first_frame_position;
2608         int     frame_seq_numbr = STp->frame_seq_number;
2609         int     logical_blk_num = STp->logical_blk_num;
2610         int     halfway_frame   = STp->frame_in_buffer;
2611         int     read_pointer    = STp->buffer->read_pointer;
2612         int     prev_mark_ppos  = -1;
2613         int     actual_mark_ppos, i, n;
2614 #if DEBUG
2615         char  * name = tape_name(STp);
2616
2617         printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2618 #endif
2619         osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2620         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2621 #if DEBUG
2622                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2623 #endif
2624                 return (-EIO);
2625         }
2626         if (STp->linux_media_version >= 4) {
2627                 for (i=0; i<STp->filemark_cnt; i++)
2628                         if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2629                                 prev_mark_ppos = n;
2630         } else
2631                 prev_mark_ppos = frame_position - 1;  /* usually - we don't really know */
2632         actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2633                                 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2634         if (frame_position  != STp->first_frame_position                   ||
2635             frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2636             prev_mark_ppos  != actual_mark_ppos                            ) {
2637 #if DEBUG
2638                 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2639                                   STp->first_frame_position, frame_position, 
2640                                   STp->frame_seq_number + (halfway_frame?0:1),
2641                                   frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2642 #endif
2643                 return (-EIO);
2644         }
2645         if (halfway_frame) {
2646                 /* prepare buffer for append and rewrite on top of original */
2647                 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2648                 STp->buffer->buffer_bytes  = read_pointer;
2649                 STp->ps[STp->partition].rw = ST_WRITING;
2650                 STp->dirty                 = 1;
2651         }
2652         STp->frame_in_buffer  = halfway_frame;
2653         STp->frame_seq_number = frame_seq_numbr;
2654         STp->logical_blk_num  = logical_blk_num;
2655         return 0;
2656 }
2657
2658 /* Acc. to OnStream, the vers. numbering is the following:
2659  * X.XX for released versions (X=digit), 
2660  * XXXY for unreleased versions (Y=letter)
2661  * Ordering 1.05 < 106A < 106B < ...  < 106a < ... < 1.06
2662  * This fn makes monoton numbers out of this scheme ...
2663  */
2664 static unsigned int osst_parse_firmware_rev (const char * str)
2665 {
2666         if (str[1] == '.') {
2667                 return (str[0]-'0')*10000
2668                         +(str[2]-'0')*1000
2669                         +(str[3]-'0')*100;
2670         } else {
2671                 return (str[0]-'0')*10000
2672                         +(str[1]-'0')*1000
2673                         +(str[2]-'0')*100 - 100
2674                         +(str[3]-'@');
2675         }
2676 }
2677
2678 /*
2679  * Configure the OnStream SCII tape drive for default operation
2680  */
2681 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
2682 {
2683         unsigned char                  cmd[MAX_COMMAND_SIZE];
2684         char                         * name = tape_name(STp);
2685         struct osst_request          * SRpnt = * aSRpnt;
2686         osst_mode_parameter_header_t * header;
2687         osst_block_size_page_t       * bs;
2688         osst_capabilities_page_t     * cp;
2689         osst_tape_paramtr_page_t     * prm;
2690         int                            drive_buffer_size;
2691
2692         if (STp->ready != ST_READY) {
2693 #if DEBUG
2694             printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2695 #endif
2696             return (-EIO);
2697         }
2698         
2699         if (STp->os_fw_rev < 10600) {
2700             printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2701             printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2702         }
2703
2704         /*
2705          * Configure 32.5KB (data+aux) frame size.
2706          * Get the current frame size from the block size mode page
2707          */
2708         memset(cmd, 0, MAX_COMMAND_SIZE);
2709         cmd[0] = MODE_SENSE;
2710         cmd[1] = 8;
2711         cmd[2] = BLOCK_SIZE_PAGE;
2712         cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2713
2714         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2715         if (SRpnt == NULL) {
2716 #if DEBUG
2717             printk(OSST_DEB_MSG "osst :D: Busy\n");
2718 #endif
2719             return (-EBUSY);
2720         }
2721         *aSRpnt = SRpnt;
2722         if ((STp->buffer)->syscall_result != 0) {
2723             printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2724             return (-EIO);
2725         }
2726
2727         header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2728         bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2729
2730 #if DEBUG
2731         printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n",   name, bs->play32     ? "Yes" : "No");
2732         printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5   ? "Yes" : "No");
2733         printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n",      name, bs->record32   ? "Yes" : "No");
2734         printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n",    name, bs->record32_5 ? "Yes" : "No");
2735 #endif
2736
2737         /*
2738          * Configure default auto columns mode, 32.5KB transfer mode
2739          */ 
2740         bs->one = 1;
2741         bs->play32 = 0;
2742         bs->play32_5 = 1;
2743         bs->record32 = 0;
2744         bs->record32_5 = 1;
2745
2746         memset(cmd, 0, MAX_COMMAND_SIZE);
2747         cmd[0] = MODE_SELECT;
2748         cmd[1] = 0x10;
2749         cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2750
2751         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2752         *aSRpnt = SRpnt;
2753         if ((STp->buffer)->syscall_result != 0) {
2754             printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2755             return (-EIO);
2756         }
2757
2758 #if DEBUG
2759         printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2760          /*
2761          * In debug mode, we want to see as many errors as possible
2762          * to test the error recovery mechanism.
2763          */
2764         osst_set_retries(STp, aSRpnt, 0);
2765         SRpnt = * aSRpnt;
2766 #endif
2767
2768         /*
2769          * Set vendor name to 'LIN4' for "Linux support version 4".
2770          */
2771
2772         memset(cmd, 0, MAX_COMMAND_SIZE);
2773         cmd[0] = MODE_SELECT;
2774         cmd[1] = 0x10;
2775         cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2776
2777         header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2778         header->medium_type      = 0;   /* Medium Type - ignoring */
2779         header->dsp              = 0;   /* Reserved */
2780         header->bdl              = 0;   /* Block Descriptor Length */
2781         
2782         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2783         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2784         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2785         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2786         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2787         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2788         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2789         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2790
2791         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2792         *aSRpnt = SRpnt;
2793
2794         if ((STp->buffer)->syscall_result != 0) {
2795             printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name, 
2796                         (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2797             return (-EIO);
2798         }
2799
2800         memset(cmd, 0, MAX_COMMAND_SIZE);
2801         cmd[0] = MODE_SENSE;
2802         cmd[1] = 8;
2803         cmd[2] = CAPABILITIES_PAGE;
2804         cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2805
2806         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2807         *aSRpnt = SRpnt;
2808
2809         if ((STp->buffer)->syscall_result != 0) {
2810             printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2811             return (-EIO);
2812         }
2813
2814         header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2815         cp     = (osst_capabilities_page_t    *) ((STp->buffer)->b_data +
2816                  sizeof(osst_mode_parameter_header_t) + header->bdl);
2817
2818         drive_buffer_size = ntohs(cp->buffer_size) / 2;
2819
2820         memset(cmd, 0, MAX_COMMAND_SIZE);
2821         cmd[0] = MODE_SENSE;
2822         cmd[1] = 8;
2823         cmd[2] = TAPE_PARAMTR_PAGE;
2824         cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2825
2826         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2827         *aSRpnt = SRpnt;
2828
2829         if ((STp->buffer)->syscall_result != 0) {
2830             printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2831             return (-EIO);
2832         }
2833
2834         header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2835         prm    = (osst_tape_paramtr_page_t    *) ((STp->buffer)->b_data +
2836                  sizeof(osst_mode_parameter_header_t) + header->bdl);
2837
2838         STp->density  = prm->density;
2839         STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2840 #if DEBUG
2841         printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2842                           name, STp->density, STp->capacity / 32, drive_buffer_size);
2843 #endif
2844
2845         return 0;
2846         
2847 }
2848
2849
2850 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2851    it messes up the block number). */
2852 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward)
2853 {
2854         int     result;
2855         char  * name = tape_name(STp);
2856
2857 #if DEBUG
2858         if (debugging)
2859                 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2860                                   name, forward ? "forward" : "backward");
2861 #endif
2862
2863         if (forward) {
2864            /* assumes that the filemark is already read by the drive, so this is low cost */
2865            result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2866         }
2867         else
2868            /* assumes this is only called if we just read the filemark! */
2869            result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2870
2871         if (result < 0)
2872            printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2873                                 name, forward ? "forward" : "backward");
2874
2875         return result;
2876 }
2877
2878
2879 /* Get the tape position. */
2880
2881 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
2882 {
2883         unsigned char           scmd[MAX_COMMAND_SIZE];
2884         struct osst_request   * SRpnt;
2885         int                     result = 0;
2886         char                  * name   = tape_name(STp);
2887
2888         /* KG: We want to be able to use it for checking Write Buffer availability
2889          *  and thus don't want to risk to overwrite anything. Exchange buffers ... */
2890         char            mybuf[24];
2891         char          * olddata = STp->buffer->b_data;
2892         int             oldsize = STp->buffer->buffer_size;
2893
2894         if (STp->ready != ST_READY) return (-EIO);
2895
2896         memset (scmd, 0, MAX_COMMAND_SIZE);
2897         scmd[0] = READ_POSITION;
2898
2899         STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2900         SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2901                                       STp->timeout, MAX_RETRIES, 1);
2902         if (!SRpnt) {
2903                 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2904                 return (-EBUSY);
2905         }
2906         *aSRpnt = SRpnt;
2907
2908         if (STp->buffer->syscall_result)
2909                 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL;      /* 3: Write Error */
2910
2911         if (result == -EINVAL)
2912                 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2913         else {
2914                 if (result == -EIO) {   /* re-read position - this needs to preserve media errors */
2915                         unsigned char mysense[16];
2916                         memcpy (mysense, SRpnt->sense, 16);
2917                         memset (scmd, 0, MAX_COMMAND_SIZE);
2918                         scmd[0] = READ_POSITION;
2919                         STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2920                         SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2921                                                     STp->timeout, MAX_RETRIES, 1);
2922 #if DEBUG
2923                         printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2924                                         name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2925                                         SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]);
2926 #endif
2927                         if (!STp->buffer->syscall_result)
2928                                 memcpy (SRpnt->sense, mysense, 16);
2929                         else
2930                                 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2931                 }
2932                 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2933                                           + ((STp->buffer)->b_data[5] << 16)
2934                                           + ((STp->buffer)->b_data[6] << 8)