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