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