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