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