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