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