2   SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
 
   3   file Documentation/scsi/st.txt for more information.
 
   7   OnStream SCSI Tape support (osst) cloned from st.c by
 
   8   Willem Riede (osst@riede.org) Feb 2000
 
   9   Fixes ... Kurt Garloff <garloff@suse.de> Mar 2000
 
  11   Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
 
  12   Contribution and ideas from several people including (in alphabetical
 
  13   order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
 
  14   Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
 
  16   Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede
 
  19   $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
 
  21   Microscopic alterations - Rik Ling, 2000/12/21
 
  22   Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
 
  23   Some small formal changes - aeb, 950809
 
  26 static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $";
 
  27 static const char * osst_version = "0.99.4";
 
  29 /* The "failure to reconnect" firmware bug */
 
  30 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
 
  31 #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/
 
  32 #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
 
  34 #include <linux/module.h>
 
  37 #include <linux/kernel.h>
 
  38 #include <linux/sched.h>
 
  39 #include <linux/proc_fs.h>
 
  41 #include <linux/init.h>
 
  42 #include <linux/string.h>
 
  43 #include <linux/errno.h>
 
  44 #include <linux/mtio.h>
 
  45 #include <linux/ioctl.h>
 
  46 #include <linux/fcntl.h>
 
  47 #include <linux/spinlock.h>
 
  48 #include <linux/vmalloc.h>
 
  49 #include <linux/blkdev.h>
 
  50 #include <linux/moduleparam.h>
 
  51 #include <linux/delay.h>
 
  52 #include <linux/jiffies.h>
 
  53 #include <asm/uaccess.h>
 
  55 #include <asm/system.h>
 
  57 /* The driver prints some debugging information on the console if DEBUG
 
  58    is defined and non-zero. */
 
  61 /* The message level for the debug messages is currently set to KERN_NOTICE
 
  62    so that people can easily see the messages. Later when the debugging messages
 
  63    in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
 
  64 #define OSST_DEB_MSG  KERN_NOTICE
 
  66 #include <scsi/scsi.h>
 
  67 #include <scsi/scsi_dbg.h>
 
  68 #include <scsi/scsi_device.h>
 
  69 #include <scsi/scsi_driver.h>
 
  70 #include <scsi/scsi_eh.h>
 
  71 #include <scsi/scsi_host.h>
 
  72 #include <scsi/scsi_ioctl.h>
 
  74 #define ST_KILOBYTE 1024
 
  78 #include "osst_options.h"
 
  79 #include "osst_detect.h"
 
  81 static int max_dev = 0;
 
  82 static int write_threshold_kbs = 0;
 
  83 static int max_sg_segs = 0;
 
  86 MODULE_AUTHOR("Willem Riede");
 
  87 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
 
  88 MODULE_LICENSE("GPL");
 
  89 MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR);
 
  90 MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
 
  92 module_param(max_dev, int, 0444);
 
  93 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
 
  95 module_param(write_threshold_kbs, int, 0644);
 
  96 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
 
  98 module_param(max_sg_segs, int, 0644);
 
  99 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
 
 101 static struct osst_dev_parm {
 
 104 } parms[] __initdata = {
 
 105        { "max_dev",             &max_dev             },
 
 106        { "write_threshold_kbs", &write_threshold_kbs },
 
 107        { "max_sg_segs",         &max_sg_segs         }
 
 111 /* Some default definitions have been moved to osst_options.h */
 
 112 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
 
 113 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
 
 115 /* The buffer size should fit into the 24 bits for length in the
 
 116    6-byte SCSI read and write commands. */
 
 117 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
 
 118 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
 
 122 static int debugging = 1;
 
 123 /* uncomment define below to test error recovery */
 
 124 // #define OSST_INJECT_ERRORS 1 
 
 127 /* Do not retry! The drive firmware already retries when appropriate,
 
 128    and when it tries to tell us something, we had better listen... */
 
 129 #define MAX_RETRIES 0
 
 131 #define NO_TAPE  NOT_READY
 
 133 #define OSST_WAIT_POSITION_COMPLETE   (HZ > 200 ? HZ / 200 : 1)
 
 134 #define OSST_WAIT_WRITE_COMPLETE      (HZ / 12)
 
 135 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
 
 137 #define OSST_TIMEOUT (200 * HZ)
 
 138 #define OSST_LONG_TIMEOUT (1800 * HZ)
 
 140 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
 
 141 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
 
 142 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
 
 143 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
 
 145 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
 
 147 #define SET_DENS_AND_BLK 0x10001
 
 149 static int osst_buffer_size       = OSST_BUFFER_SIZE;
 
 150 static int osst_write_threshold   = OSST_WRITE_THRESHOLD;
 
 151 static int osst_max_sg_segs       = OSST_MAX_SG;
 
 152 static int osst_max_dev           = OSST_MAX_TAPES;
 
 153 static int osst_nr_dev;
 
 155 static struct osst_tape **os_scsi_tapes = NULL;
 
 156 static DEFINE_RWLOCK(os_scsi_tapes_lock);
 
 158 static int modes_defined = 0;
 
 160 static struct osst_buffer *new_tape_buffer(int, int, int);
 
 161 static int enlarge_buffer(struct osst_buffer *, int);
 
 162 static void normalize_buffer(struct osst_buffer *);
 
 163 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
 
 164 static int from_buffer(struct osst_buffer *, char __user *, int);
 
 165 static int osst_zero_buffer_tail(struct osst_buffer *);
 
 166 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
 
 167 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
 
 169 static int osst_probe(struct device *);
 
 170 static int osst_remove(struct device *);
 
 172 static struct scsi_driver osst_template = {
 
 173         .owner                  = THIS_MODULE,
 
 177                 .remove         = osst_remove,
 
 181 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt,
 
 182                             unsigned int cmd_in, unsigned long arg);
 
 184 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip);
 
 186 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt);
 
 188 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt);
 
 190 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending);
 
 192 static inline char *tape_name(struct osst_tape *tape)
 
 194         return tape->drive->disk_name;
 
 197 /* Routines that handle the interaction with mid-layer SCSI routines */
 
 200 /* Normalize Sense */
 
 201 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s)
 
 204         const u8 *sense = SRpnt->sense;
 
 206         s->have_sense = scsi_normalize_sense(SRpnt->sense,
 
 207                                 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
 
 213                         scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
 
 214                 switch (sense[0] & 0x7f) {
 
 219                         s->flags = sense[2] & 0xe0;
 
 225                         ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
 
 226                         s->flags = ucp ? (ucp[3] & 0xe0) : 0;
 
 232 /* Convert the result to success code */
 
 233 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
 
 235         char *name = tape_name(STp);
 
 236         int result = SRpnt->result;
 
 237         u8 * sense = SRpnt->sense, scode;
 
 241         struct st_cmdstatus *cmdstatp;
 
 246         cmdstatp = &STp->buffer->cmdstat;
 
 247         osst_analyze_sense(SRpnt, cmdstatp);
 
 249         if (cmdstatp->have_sense)
 
 250                 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
 
 255                 printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
 
 257                    SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
 
 258                    SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
 
 259                 if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
 
 260                                 name, scode, sense[12], sense[13]);
 
 261                 if (cmdstatp->have_sense)
 
 262                         __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
 
 266         if (cmdstatp->have_sense && (
 
 268                  scode != RECOVERED_ERROR &&
 
 269 /*               scode != UNIT_ATTENTION && */
 
 270                  scode != BLANK_CHECK &&
 
 271                  scode != VOLUME_OVERFLOW &&
 
 272                  SRpnt->cmd[0] != MODE_SENSE &&
 
 273                  SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
 
 274                 if (cmdstatp->have_sense) {
 
 275                         printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
 
 276                         __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
 
 279                         static  int     notyetprinted = 1;
 
 282                              "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
 
 283                              name, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
 
 288                                         "%s:I: This warning may be caused by your scsi controller,\n", name);
 
 290                                         "%s:I: it has been reported with some Buslogic cards.\n", name);
 
 294         STp->pos_unknown |= STp->device->was_reset;
 
 296         if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
 
 297                 STp->recover_count++;
 
 298                 STp->recover_erreg++;
 
 301                         if (SRpnt->cmd[0] == READ_6)
 
 303                         else if (SRpnt->cmd[0] == WRITE_6)
 
 307                         printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
 
 311                 if ((sense[2] & 0xe0) == 0)
 
 318 /* Wakeup from interrupt */
 
 319 static void osst_sleep_done(void *data, char *sense, int result, int resid)
 
 321         struct osst_request *SRpnt = data;
 
 322         struct osst_tape *STp = SRpnt->stp;
 
 324         memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
 
 325         STp->buffer->cmdstat.midlevel_result = SRpnt->result = result;
 
 327         STp->write_pending = 0;
 
 330                 complete(SRpnt->waiting);
 
 333 /* osst_request memory management */
 
 334 static struct osst_request *osst_allocate_request(void)
 
 336         return kzalloc(sizeof(struct osst_request), GFP_KERNEL);
 
 339 static void osst_release_request(struct osst_request *streq)
 
 344 /* Do the scsi command. Waits until command performed if do_wait is true.
 
 345    Otherwise osst_write_behind_check() is used to check that the command
 
 347 static  struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp, 
 
 348         unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
 
 351         unsigned short use_sg;
 
 352 #ifdef OSST_INJECT_ERRORS
 
 353         static   int   inject = 0;
 
 354         static   int   repeat = 0;
 
 356         struct completion *waiting;
 
 358         /* if async, make sure there's no command outstanding */
 
 359         if (!do_wait && ((STp->buffer)->last_SRpnt)) {
 
 360                 printk(KERN_ERR "%s: Async command already active.\n",
 
 362                 if (signal_pending(current))
 
 363                         (STp->buffer)->syscall_result = (-EINTR);
 
 365                         (STp->buffer)->syscall_result = (-EBUSY);
 
 370                 SRpnt = osst_allocate_request();
 
 372                         printk(KERN_ERR "%s: Can't allocate SCSI request.\n",
 
 374                         if (signal_pending(current))
 
 375                                 (STp->buffer)->syscall_result = (-EINTR);
 
 377                                 (STp->buffer)->syscall_result = (-EBUSY);
 
 383         /* If async IO, set last_SRpnt. This ptr tells write_behind_check
 
 384            which IO is outstanding. It's nulled out when the IO completes. */
 
 386                 (STp->buffer)->last_SRpnt = SRpnt;
 
 388         waiting = &STp->wait;
 
 389         init_completion(waiting);
 
 390         SRpnt->waiting = waiting;
 
 392         use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0;
 
 394                 bp = (char *)&(STp->buffer->sg[0]);
 
 395                 if (STp->buffer->sg_segs < use_sg)
 
 396                         use_sg = STp->buffer->sg_segs;
 
 399                 bp = (STp->buffer)->b_data;
 
 401         memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
 
 402         STp->buffer->cmdstat.have_sense = 0;
 
 403         STp->buffer->syscall_result = 0;
 
 405         if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
 
 406                         use_sg, timeout, retries, SRpnt, osst_sleep_done, GFP_KERNEL))
 
 407                 /* could not allocate the buffer or request was too large */
 
 408                 (STp->buffer)->syscall_result = (-EBUSY);
 
 410                 wait_for_completion(waiting);
 
 411                 SRpnt->waiting = NULL;
 
 412                 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
 
 413 #ifdef OSST_INJECT_ERRORS
 
 414                 if (STp->buffer->syscall_result == 0 &&
 
 417                     ( (++ inject % 83) == 29  ||
 
 418                       (STp->first_frame_position == 240 
 
 419                                  /* or STp->read_error_frame to fail again on the block calculated above */ &&
 
 421                         printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
 
 422                         STp->buffer->last_result_fatal = 1;
 
 430 /* Handle the write-behind checking (downs the semaphore) */
 
 431 static void osst_write_behind_check(struct osst_tape *STp)
 
 433         struct osst_buffer * STbuffer;
 
 435         STbuffer = STp->buffer;
 
 438         if (STp->write_pending)
 
 443         wait_for_completion(&(STp->wait));
 
 444         STp->buffer->last_SRpnt->waiting = NULL;
 
 446         STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
 
 448         if (STp->buffer->syscall_result)
 
 449                 STp->buffer->syscall_result =
 
 450                         osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1);
 
 452                 STp->first_frame_position++;
 
 454         osst_release_request(STp->buffer->last_SRpnt);
 
 456         if (STbuffer->writing < STbuffer->buffer_bytes)
 
 457                 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
 
 459         STbuffer->last_SRpnt = NULL;
 
 460         STbuffer->buffer_bytes -= STbuffer->writing;
 
 461         STbuffer->writing = 0;
 
 468 /* Onstream specific Routines */
 
 470  * Initialize the OnStream AUX
 
 472 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
 
 473                                          int logical_blk_num, int blk_sz, int blk_cnt)
 
 475         os_aux_t       *aux = STp->buffer->aux;
 
 476         os_partition_t *par = &aux->partition;
 
 477         os_dat_t       *dat = &aux->dat;
 
 479         if (STp->raw) return;
 
 481         memset(aux, 0, sizeof(*aux));
 
 482         aux->format_id = htonl(0);
 
 483         memcpy(aux->application_sig, "LIN4", 4);
 
 484         aux->hdwr = htonl(0);
 
 485         aux->frame_type = frame_type;
 
 487         switch (frame_type) {
 
 488           case  OS_FRAME_TYPE_HEADER:
 
 489                 aux->update_frame_cntr    = htonl(STp->update_frame_cntr);
 
 490                 par->partition_num        = OS_CONFIG_PARTITION;
 
 491                 par->par_desc_ver         = OS_PARTITION_VERSION;
 
 492                 par->wrt_pass_cntr        = htons(0xffff);
 
 493                 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
 
 494                 par->first_frame_ppos     = htonl(0);
 
 495                 par->last_frame_ppos      = htonl(0xbb7);
 
 496                 aux->frame_seq_num        = htonl(0);
 
 497                 aux->logical_blk_num_high = htonl(0);
 
 498                 aux->logical_blk_num      = htonl(0);
 
 499                 aux->next_mark_ppos       = htonl(STp->first_mark_ppos);
 
 501           case  OS_FRAME_TYPE_DATA:
 
 502           case  OS_FRAME_TYPE_MARKER:
 
 507                 dat->dat_list[0].blk_sz   = htonl(blk_sz);
 
 508                 dat->dat_list[0].blk_cnt  = htons(blk_cnt);
 
 509                 dat->dat_list[0].flags    = frame_type==OS_FRAME_TYPE_MARKER?
 
 510                                                         OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
 
 511                 dat->dat_list[0].reserved = 0;
 
 512           case  OS_FRAME_TYPE_EOD:
 
 513                 aux->update_frame_cntr    = htonl(0);
 
 514                 par->partition_num        = OS_DATA_PARTITION;
 
 515                 par->par_desc_ver         = OS_PARTITION_VERSION;
 
 516                 par->wrt_pass_cntr        = htons(STp->wrt_pass_cntr);
 
 517                 par->first_frame_ppos     = htonl(STp->first_data_ppos);
 
 518                 par->last_frame_ppos      = htonl(STp->capacity);
 
 519                 aux->frame_seq_num        = htonl(frame_seq_number);
 
 520                 aux->logical_blk_num_high = htonl(0);
 
 521                 aux->logical_blk_num      = htonl(logical_blk_num);
 
 523           default: ; /* probably FILL */
 
 525         aux->filemark_cnt = htonl(STp->filemark_cnt);
 
 526         aux->phys_fm = htonl(0xffffffff);
 
 527         aux->last_mark_ppos = htonl(STp->last_mark_ppos);
 
 528         aux->last_mark_lbn  = htonl(STp->last_mark_lbn);
 
 532  * Verify that we have the correct tape frame
 
 534 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
 
 536         char               * name = tape_name(STp);
 
 537         os_aux_t           * aux  = STp->buffer->aux;
 
 538         os_partition_t     * par  = &(aux->partition);
 
 539         struct st_partstat * STps = &(STp->ps[STp->partition]);
 
 540         int                  blk_cnt, blk_sz, i;
 
 543                 if (STp->buffer->syscall_result) {
 
 544                         for (i=0; i < STp->buffer->sg_segs; i++)
 
 545                                 memset(page_address(sg_page(&STp->buffer->sg[i])),
 
 546                                        0, STp->buffer->sg[i].length);
 
 547                         strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
 
 549                         STp->buffer->buffer_bytes = OS_FRAME_SIZE;
 
 552         if (STp->buffer->syscall_result) {
 
 554                 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
 
 558         if (ntohl(aux->format_id) != 0) {
 
 560                 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
 
 564         if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
 
 565             (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
 
 567                 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
 
 571         if (par->partition_num != OS_DATA_PARTITION) {
 
 572                 if (!STp->linux_media || STp->linux_media_version != 2) {
 
 574                         printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
 
 575                                             name, par->partition_num);
 
 580         if (par->par_desc_ver != OS_PARTITION_VERSION) {
 
 582                 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
 
 586         if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
 
 588                 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n", 
 
 589                                     name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
 
 593         if (aux->frame_type != OS_FRAME_TYPE_DATA &&
 
 594             aux->frame_type != OS_FRAME_TYPE_EOD &&
 
 595             aux->frame_type != OS_FRAME_TYPE_MARKER) {
 
 598                         printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
 
 603         if (aux->frame_type == OS_FRAME_TYPE_EOD &&
 
 604             STp->first_frame_position < STp->eod_frame_ppos) {
 
 605                 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
 
 606                                  STp->first_frame_position);
 
 609         if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
 
 612                         printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n", 
 
 613                                             name, ntohl(aux->frame_seq_num), frame_seq_number);
 
 618         if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
 
 619                 STps->eof = ST_FM_HIT;
 
 621                 i = ntohl(aux->filemark_cnt);
 
 622                 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
 
 623                     STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
 
 625                         printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
 
 626                                   STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
 
 627                                   i, STp->first_frame_position - 1);
 
 629                         STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
 
 630                         if (i >= STp->filemark_cnt)
 
 631                                  STp->filemark_cnt = i+1;
 
 634         if (aux->frame_type == OS_FRAME_TYPE_EOD) {
 
 635                 STps->eof = ST_EOD_1;
 
 636                 STp->frame_in_buffer = 1;
 
 638         if (aux->frame_type == OS_FRAME_TYPE_DATA) {
 
 639                 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
 
 640                 blk_sz  = ntohl(aux->dat.dat_list[0].blk_sz);
 
 641                 STp->buffer->buffer_bytes = blk_cnt * blk_sz;
 
 642                 STp->buffer->read_pointer = 0;
 
 643                 STp->frame_in_buffer = 1;
 
 645                 /* See what block size was used to write file */
 
 646                 if (STp->block_size != blk_sz && blk_sz > 0) {
 
 648                 "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
 
 649                                 name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
 
 650                                 STp->block_size<1024?STp->block_size:STp->block_size/1024,
 
 651                                 STp->block_size<1024?'b':'k');
 
 652                         STp->block_size            = blk_sz;
 
 653                         STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
 
 655                 STps->eof = ST_NOEOF;
 
 657         STp->frame_seq_number = ntohl(aux->frame_seq_num);
 
 658         STp->logical_blk_num  = ntohl(aux->logical_blk_num);
 
 662         if (STp->read_error_frame == 0)
 
 663                 STp->read_error_frame = STp->first_frame_position - 1;
 
 668  * Wait for the unit to become Ready
 
 670 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
 
 671                                  unsigned timeout, int initial_delay)
 
 673         unsigned char           cmd[MAX_COMMAND_SIZE];
 
 674         struct osst_request   * SRpnt;
 
 675         unsigned long           startwait = jiffies;
 
 678         char                  * name = tape_name(STp);
 
 680         printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
 
 683         if (initial_delay > 0)
 
 684                 msleep(jiffies_to_msecs(initial_delay));
 
 686         memset(cmd, 0, MAX_COMMAND_SIZE);
 
 687         cmd[0] = TEST_UNIT_READY;
 
 689         SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 
 691         if (!SRpnt) return (-EBUSY);
 
 693         while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
 
 694                (( SRpnt->sense[2]  == 2 && SRpnt->sense[12] == 4    &&
 
 695                  (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)    ) ||
 
 696                 ( SRpnt->sense[2]  == 6 && SRpnt->sense[12] == 0x28 &&
 
 697                   SRpnt->sense[13] == 0                                        )  )) {
 
 700                 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
 
 701                 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
 
 707             memset(cmd, 0, MAX_COMMAND_SIZE);
 
 708             cmd[0] = TEST_UNIT_READY;
 
 710             SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 
 716         if ( STp->buffer->syscall_result &&
 
 717              osst_write_error_recovery(STp, aSRpnt, 0) ) {
 
 719             printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
 
 720             printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
 
 721                         STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
 
 722                         SRpnt->sense[12], SRpnt->sense[13]);
 
 727         printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
 
 733  * Wait for a tape to be inserted in the unit
 
 735 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
 
 737         unsigned char           cmd[MAX_COMMAND_SIZE];
 
 738         struct osst_request   * SRpnt;
 
 739         unsigned long           startwait = jiffies;
 
 742         char                  * name = tape_name(STp);
 
 744         printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
 
 747         memset(cmd, 0, MAX_COMMAND_SIZE);
 
 748         cmd[0] = TEST_UNIT_READY;
 
 750         SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 
 752         if (!SRpnt) return (-EBUSY);
 
 754         while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
 
 755                 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0  ) {
 
 758                 printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
 
 759                 printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
 
 765             memset(cmd, 0, MAX_COMMAND_SIZE);
 
 766             cmd[0] = TEST_UNIT_READY;
 
 768             SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 
 774         if ( STp->buffer->syscall_result     && SRpnt->sense[2]  != 2 &&
 
 775              SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) {
 
 777             printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
 
 778             printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
 
 779                         STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
 
 780                         SRpnt->sense[12], SRpnt->sense[13]);
 
 785         printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
 
 790 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame)
 
 794         osst_wait_ready(STp, aSRpnt, 15 * 60, 0);                       /* TODO - can this catch a write error? */
 
 795         retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
 
 796         if (retval) return (retval);
 
 797         osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
 
 798         return (osst_get_frame_position(STp, aSRpnt));
 
 802  * Wait for write(s) to complete
 
 804 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
 
 806         unsigned char           cmd[MAX_COMMAND_SIZE];
 
 807         struct osst_request   * SRpnt;
 
 809         int                     delay  = OSST_WAIT_WRITE_COMPLETE;
 
 811         char                  * name = tape_name(STp);
 
 813         printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
 
 816         memset(cmd, 0, MAX_COMMAND_SIZE);
 
 817         cmd[0] = WRITE_FILEMARKS;
 
 820         SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 
 822         if (!SRpnt) return (-EBUSY);
 
 823         if (STp->buffer->syscall_result) {
 
 824                 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) {
 
 825                         if (SRpnt->sense[13] == 8) {
 
 826                                 delay = OSST_WAIT_LONG_WRITE_COMPLETE;
 
 829                         result = osst_write_error_recovery(STp, aSRpnt, 0);
 
 831         result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
 
 832         STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
 
 837 #define OSST_POLL_PER_SEC 10
 
 838 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to)
 
 840         unsigned long   startwait = jiffies;
 
 841         char          * name      = tape_name(STp);
 
 843         char       notyetprinted  = 1;
 
 845         if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
 
 846                 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
 
 848         while (time_before (jiffies, startwait + to*HZ))
 
 851                 result = osst_get_frame_position(STp, aSRpnt);
 
 853                         if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
 
 854                                 return 0;       /* successful recovery leaves drive ready for frame */
 
 855                 if (result < 0) break;
 
 856                 if (STp->first_frame_position == curr &&
 
 858                       (signed)STp->last_frame_position > (signed)curr + minlast) ||
 
 859                      (minlast >= 0 && STp->cur_frames > minlast)
 
 863                         if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC))
 
 865                                         "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
 
 866                                         name, curr, curr+minlast, STp->first_frame_position,
 
 867                                         STp->last_frame_position, STp->cur_frames,
 
 868                                         result, (jiffies-startwait)/HZ, 
 
 869                                         (((jiffies-startwait)%HZ)*10)/HZ);
 
 874                 if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted)
 
 876                         printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
 
 877                                 name, curr, curr+minlast, STp->first_frame_position,
 
 878                                 STp->last_frame_position, STp->cur_frames, result);
 
 882                 msleep(1000 / OSST_POLL_PER_SEC);
 
 885         printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
 
 886                 name, curr, curr+minlast, STp->first_frame_position,
 
 887                 STp->last_frame_position, STp->cur_frames,
 
 888                 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
 
 893 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
 
 895         struct osst_request   * SRpnt;
 
 896         unsigned char           cmd[MAX_COMMAND_SIZE];
 
 897         unsigned long           startwait = jiffies;
 
 899         char                  * name      = tape_name(STp);
 
 903                 char  * olddata = STp->buffer->b_data;
 
 904                 int     oldsize = STp->buffer->buffer_size;
 
 906                 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
 
 908                 memset(cmd, 0, MAX_COMMAND_SIZE);
 
 909                 cmd[0] = WRITE_FILEMARKS;
 
 911                 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
 
 914                 while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
 
 916                         if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) {
 
 918                                 /* some failure - not just not-ready */
 
 919                                 retval = osst_write_error_recovery(STp, aSRpnt, 0);
 
 922                         schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
 
 924                         STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
 
 925                         memset(cmd, 0, MAX_COMMAND_SIZE);
 
 926                         cmd[0] = READ_POSITION;
 
 928                         SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
 
 931                         retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
 
 932                         STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
 
 935                         printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
 
 937                 /* TODO - figure out which error conditions can be handled */
 
 938                 if (STp->buffer->syscall_result)
 
 940                                 "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
 
 941                                         (*aSRpnt)->sense[ 2] & 0x0f,
 
 942                                         (*aSRpnt)->sense[12],
 
 943                                         (*aSRpnt)->sense[13]);
 
 949  * Read the next OnStream tape frame at the current location
 
 951 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
 
 953         unsigned char           cmd[MAX_COMMAND_SIZE];
 
 954         struct osst_request   * SRpnt;
 
 957         os_aux_t              * aux    = STp->buffer->aux;
 
 958         char                  * name   = tape_name(STp);
 
 962                 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
 
 963                         retval = osst_recover_wait_frame(STp, aSRpnt, 0);
 
 965         memset(cmd, 0, MAX_COMMAND_SIZE);
 
 972                 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
 
 974         SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
 
 975                                       STp->timeout, MAX_RETRIES, 1);
 
 980         if ((STp->buffer)->syscall_result) {
 
 982             if (STp->read_error_frame == 0) {
 
 983                 STp->read_error_frame = STp->first_frame_position;
 
 985                 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
 
 990                 printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
 
 992                    SRpnt->sense[0], SRpnt->sense[1],
 
 993                    SRpnt->sense[2], SRpnt->sense[3],
 
 994                    SRpnt->sense[4], SRpnt->sense[5],
 
 995                    SRpnt->sense[6], SRpnt->sense[7]);
 
 999             STp->first_frame_position++;
 
1004                    sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
 
1007                 "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
 
1008                         ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
 
1009                         aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
 
1010                         aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL", 
 
1011                         ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
 
1012                         ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
 
1013            if (aux->frame_type==2)
 
1014                 printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
 
1015                         ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
 
1016            printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
 
1022 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
 
1024         struct st_partstat    * STps   = &(STp->ps[STp->partition]);
 
1025         struct osst_request   * SRpnt  ;
 
1026         unsigned char           cmd[MAX_COMMAND_SIZE];
 
1028         char                  * name   = tape_name(STp);
 
1030         if (STps->rw != ST_READING) {         /* Initialize read operation */
 
1031                 if (STps->rw == ST_WRITING || STp->dirty) {
 
1032                         STp->write_type = OS_WRITE_DATA;
 
1033                         osst_flush_write_buffer(STp, aSRpnt);
 
1034                         osst_flush_drive_buffer(STp, aSRpnt);
 
1036                 STps->rw = ST_READING;
 
1037                 STp->frame_in_buffer = 0;
 
1040                  *      Issue a read 0 command to get the OnStream drive
 
1041                  *      read frames into its buffer.
 
1043                 memset(cmd, 0, MAX_COMMAND_SIZE);
 
1048                 printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
 
1050                 SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 
1052                 if ((retval = STp->buffer->syscall_result))
 
1053                         printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
 
1059 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt,
 
1060                                                 int frame_seq_number, int quiet)
 
1062         struct st_partstat * STps  = &(STp->ps[STp->partition]);
 
1063         char               * name  = tape_name(STp);
 
1071          * If we want just any frame (-1) and there is a frame in the buffer, return it
 
1073         if (frame_seq_number == -1 && STp->frame_in_buffer) {
 
1075                 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
 
1080          * Search and wait for the next logical tape frame
 
1084                         printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
 
1085                                             name, frame_seq_number);
 
1086                         if (STp->read_error_frame) {
 
1087                                 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
 
1089                                 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
 
1090                                                     name, STp->read_error_frame);
 
1092                                 STp->read_error_frame = 0;
 
1099                         printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
 
1100                                           name, frame_seq_number, cnt);
 
1102                 if ( osst_initiate_read(STp, aSRpnt)
 
1103                 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
 
1106                         position = osst_get_frame_position(STp, aSRpnt);
 
1107                         if (position >= 0xbae && position < 0xbb8)
 
1109                         else if (position > STp->eod_frame_ppos || ++bad == 10) {
 
1110                                 position = STp->read_error_frame - 1;
 
1118                         printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
 
1121                         osst_set_frame_position(STp, aSRpnt, position, 0);
 
1124                 if (osst_verify_frame(STp, frame_seq_number, quiet))
 
1126                 if (osst_verify_frame(STp, -1, quiet)) {
 
1127                         x = ntohl(STp->buffer->aux->frame_seq_num);
 
1128                         if (STp->fast_open) {
 
1130                                        "%s:W: Found logical frame %d instead of %d after fast open\n",
 
1131                                        name, x, frame_seq_number);
 
1133                                 STp->read_error_frame = 0;
 
1136                         if (x > frame_seq_number) {
 
1138                                         /* positioning backwards did not bring us to the desired frame */
 
1139                                         position = STp->read_error_frame - 1;
 
1142                                         position = osst_get_frame_position(STp, aSRpnt)
 
1143                                                  + frame_seq_number - x - 1;
 
1145                                         if (STp->first_frame_position >= 3000 && position < 3000)
 
1150                                        "%s:D: Found logical frame %d while looking for %d: back up %d\n",
 
1151                                                 name, x, frame_seq_number,
 
1152                                                 STp->first_frame_position - position);
 
1154                                 osst_set_frame_position(STp, aSRpnt, position, 0);
 
1160                 if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
 
1162                         printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
 
1164                         osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
 
1167                 STp->frame_in_buffer = 0;
 
1170                 STp->recover_count++;
 
1171                 STp->recover_erreg++;
 
1172                 printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n", 
 
1173                                         name, STp->read_error_frame);
 
1178         if (debugging || STps->eof)
 
1180                         "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
 
1181                         name, frame_seq_number, STp->frame_seq_number, STps->eof);
 
1184         STp->read_error_frame = 0;
 
1188 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num)
 
1190         struct st_partstat * STps = &(STp->ps[STp->partition]);
 
1191         char               * name = tape_name(STp);
 
1193         int     frame_seq_estimate, ppos_estimate, move;
 
1195         if (logical_blk_num < 0) logical_blk_num = 0;
 
1197         printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
 
1198                                 name, logical_blk_num, STp->logical_blk_num, 
 
1199                                 STp->block_size<1024?STp->block_size:STp->block_size/1024,
 
1200                                 STp->block_size<1024?'b':'k');
 
1202         /* Do we know where we are? */
 
1203         if (STps->drv_block >= 0) {
 
1204                 move                = logical_blk_num - STp->logical_blk_num;
 
1205                 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
 
1206                 move               /= (OS_DATA_SIZE / STp->block_size);
 
1207                 frame_seq_estimate  = STp->frame_seq_number + move;
 
1209                 frame_seq_estimate  = logical_blk_num * STp->block_size / OS_DATA_SIZE;
 
1211         if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
 
1212         else                           ppos_estimate = frame_seq_estimate + 20;
 
1213         while (++retries < 10) {
 
1214            if (ppos_estimate > STp->eod_frame_ppos-2) {
 
1215                frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
 
1216                ppos_estimate       = STp->eod_frame_ppos - 2;
 
1218            if (frame_seq_estimate < 0) {
 
1219                frame_seq_estimate = 0;
 
1222            osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
 
1223            if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
 
1224               /* we've located the estimated frame, now does it have our block? */
 
1225               if (logical_blk_num <  STp->logical_blk_num ||
 
1226                   logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
 
1227                  if (STps->eof == ST_FM_HIT)
 
1228                     move = logical_blk_num < STp->logical_blk_num? -2 : 1;
 
1230                     move                = logical_blk_num - STp->logical_blk_num;
 
1231                     if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
 
1232                     move               /= (OS_DATA_SIZE / STp->block_size);
 
1234                  if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
 
1237                         "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
 
1238                                 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
 
1239                                 STp->logical_blk_num, logical_blk_num, move);
 
1241                  frame_seq_estimate += move;
 
1242                  ppos_estimate      += move;
 
1245                  STp->buffer->read_pointer  = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
 
1246                  STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
 
1247                  STp->logical_blk_num       =  logical_blk_num;
 
1250                         "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
 
1251                                 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer, 
 
1252                                 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size, 
 
1255                  STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
 
1256                  if (STps->eof == ST_FM_HIT) {
 
1258                      STps->drv_block = 0;
 
1260                      STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
 
1261                                           STp->logical_blk_num -
 
1262                                              (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
 
1265                  STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
 
1269            if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
 
1271            /* we are not yet at the estimated frame, adjust our estimate of its physical position */
 
1273            printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n", 
 
1274                            name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
 
1275                            STp->logical_blk_num, logical_blk_num);
 
1277            if (frame_seq_estimate != STp->frame_seq_number)
 
1278               ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
 
1283         printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n", 
 
1284                             name, logical_blk_num, STp->logical_blk_num, retries);
 
1288 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
 
1289  * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
 
1290  * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
 
1291  * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
 
1293 #define OSST_FRAME_SHIFT  6
 
1294 #define OSST_SECTOR_SHIFT 9
 
1295 #define OSST_SECTOR_MASK  0x03F
 
1297 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt)
 
1301         char  * name = tape_name(STp);
 
1304                 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
 
1305                 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
 
1306                 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block, 
 
1307                 STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
 
1308                 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
 
1309                 STp->buffer->read_pointer, STp->ps[STp->partition].eof);
 
1311         /* do we know where we are inside a file? */
 
1312         if (STp->ps[STp->partition].drv_block >= 0) {
 
1313                 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
 
1314                                 STp->first_frame_position) << OSST_FRAME_SHIFT;
 
1315                 if (STp->ps[STp->partition].rw == ST_WRITING)
 
1316                         sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
 
1318                         sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
 
1320                 sector = osst_get_frame_position(STp, aSRpnt);
 
1322                         sector <<= OSST_FRAME_SHIFT;
 
1327 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector)
 
1329         struct st_partstat * STps   = &(STp->ps[STp->partition]);
 
1330         int                  frame  = sector >> OSST_FRAME_SHIFT,
 
1331                              offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 
 
1334         char          * name = tape_name(STp);
 
1336         printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
 
1337                                 name, sector, frame, offset);
 
1339         if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
 
1341         if (frame <= STp->first_data_ppos) {
 
1342                 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
 
1343                 return (osst_set_frame_position(STp, aSRpnt, frame, 0));
 
1345         r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
 
1346         if (r < 0) return r;
 
1348         r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
 
1349         if (r < 0) return r;
 
1351         if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
 
1354                 STp->logical_blk_num      += offset / STp->block_size;
 
1355                 STp->buffer->read_pointer  = offset;
 
1356                 STp->buffer->buffer_bytes -= offset;
 
1358                 STp->frame_seq_number++;
 
1359                 STp->frame_in_buffer       = 0;
 
1360                 STp->logical_blk_num      += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
 
1361                 STp->buffer->buffer_bytes  = STp->buffer->read_pointer = 0;
 
1363         STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
 
1364         if (STps->eof == ST_FM_HIT) {
 
1366                 STps->drv_block = 0;
 
1368                 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
 
1369                                     STp->logical_blk_num -
 
1370                                         (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
 
1373         STps->eof       = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
 
1376                 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
 
1377                 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
 
1378                 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
 
1384  * Read back the drive's internal buffer contents, as a part
 
1385  * of the write error recovery mechanism for old OnStream
 
1386  * firmware revisions.
 
1387  * Precondition for this function to work: all frames in the
 
1388  * drive's buffer must be of one type (DATA, MARK or EOD)!
 
1390 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
 
1391                                                 unsigned int frame, unsigned int skip, int pending)
 
1393         struct osst_request   * SRpnt = * aSRpnt;
 
1394         unsigned char         * buffer, * p;
 
1395         unsigned char           cmd[MAX_COMMAND_SIZE];
 
1396         int                     flag, new_frame, i;
 
1397         int                     nframes          = STp->cur_frames;
 
1398         int                     blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
 
1399         int                     frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
 
1400                                                 - (nframes + pending - 1);
 
1401         int                     logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
 
1402                                                 - (nframes + pending - 1) * blks_per_frame;
 
1403         char                  * name             = tape_name(STp);
 
1404         unsigned long           startwait        = jiffies;
 
1406         int                     dbg              = debugging;
 
1409         if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
 
1412         printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
 
1413                          name, nframes, pending?" and one that was pending":"");
 
1415         osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
 
1417         if (pending && debugging)
 
1418                 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
 
1419                                 name, frame_seq_number + nframes,
 
1420                                 logical_blk_num + nframes * blks_per_frame,
 
1421                                 p[0], p[1], p[2], p[3]);
 
1423         for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
 
1425                 memset(cmd, 0, MAX_COMMAND_SIZE);
 
1426                 cmd[0] = 0x3C;          /* Buffer Read           */
 
1427                 cmd[1] = 6;             /* Retrieve Faulty Block */
 
1428                 cmd[7] = 32768 >> 8;
 
1429                 cmd[8] = 32768 & 0xff;
 
1431                 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
 
1432                                             STp->timeout, MAX_RETRIES, 1);
 
1434                 if ((STp->buffer)->syscall_result || !SRpnt) {
 
1435                         printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
 
1440                 osst_copy_from_buffer(STp->buffer, p);
 
1443                         printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
 
1444                                           name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
 
1448         osst_get_frame_position(STp, aSRpnt);
 
1451         printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
 
1453         /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
 
1454         /* In the header we don't actually re-write the frames that fail, just the ones after them */
 
1456         for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
 
1459                         if (STp->write_type == OS_WRITE_HEADER) {
 
1461                                 p += skip * OS_DATA_SIZE;
 
1463                         else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
 
1468                         printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
 
1469                                                 name, new_frame+i, frame_seq_number+i);
 
1471                         osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
 
1472                         osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
 
1473                         osst_get_frame_position(STp, aSRpnt);
 
1476                         if (new_frame > frame + 1000) {
 
1477                                 printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
 
1481                         if ( i >= nframes + pending ) break;
 
1484                 osst_copy_to_buffer(STp->buffer, p);
 
1486                  * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
 
1488                 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
 
1489                                 logical_blk_num + i*blks_per_frame,
 
1490                                 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
 
1491                 memset(cmd, 0, MAX_COMMAND_SIZE);
 
1499                                 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
 
1500                                 name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
 
1501                                 p[0], p[1], p[2], p[3]);
 
1503                 SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
 
1504                                             STp->timeout, MAX_RETRIES, 1);
 
1506                 if (STp->buffer->syscall_result)
 
1509                         p += OS_DATA_SIZE; i++;
 
1511                         /* if we just sent the last frame, wait till all successfully written */
 
1512                         if ( i == nframes + pending ) {
 
1514                                 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
 
1516                                 memset(cmd, 0, MAX_COMMAND_SIZE);
 
1517                                 cmd[0] = WRITE_FILEMARKS;
 
1519                                 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
 
1520                                                             STp->timeout, MAX_RETRIES, 1);
 
1523                                         printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
 
1524                                         printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
 
1528                                 flag = STp->buffer->syscall_result;
 
1529                                 while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
 
1531                                         memset(cmd, 0, MAX_COMMAND_SIZE);
 
1532                                         cmd[0] = TEST_UNIT_READY;
 
1534                                         SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
 
1537                                         if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
 
1538                                             (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
 
1539                                                 /* in the process of becoming ready */
 
1543                                         if (STp->buffer->syscall_result)
 
1549                                 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
 
1555                         if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
 
1556                              SRpnt->sense[12]         ==  0 &&
 
1557                              SRpnt->sense[13]         ==  2) {
 
1558                                 printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
 
1560                                 return (-EIO);                  /* hit end of tape = fail */
 
1562                         i = ((SRpnt->sense[3] << 24) |
 
1563                              (SRpnt->sense[4] << 16) |
 
1564                              (SRpnt->sense[5] <<  8) |
 
1565                               SRpnt->sense[6]        ) - new_frame;
 
1566                         p = &buffer[i * OS_DATA_SIZE];
 
1568                         printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
 
1570                         osst_get_frame_position(STp, aSRpnt);
 
1572                         printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
 
1573                                           name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
 
1578                 /* error recovery did not successfully complete */
 
1579                 printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
 
1580                                 STp->write_type == OS_WRITE_HEADER?"header":"body");
 
1583                 osst_copy_to_buffer(STp->buffer, p);    /* so buffer content == at entry in all cases */
 
1588 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
 
1589                                         unsigned int frame, unsigned int skip, int pending)
 
1591         unsigned char           cmd[MAX_COMMAND_SIZE];
 
1592         struct osst_request   * SRpnt;
 
1593         char                  * name      = tape_name(STp);
 
1595         int                     attempts  = 1000 / skip;
 
1597         unsigned long           startwait = jiffies;
 
1599         int                     dbg       = debugging;
 
1602         while (attempts && time_before(jiffies, startwait + 60*HZ)) {
 
1607                         if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
 
1609                         expected = frame+skip+STp->cur_frames+pending;
 
1611                         printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
 
1612                                           name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
 
1614                         osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
 
1617                         schedule_timeout_interruptible(msecs_to_jiffies(100));
 
1619                 if (osst_get_frame_position(STp, aSRpnt) < 0) {         /* additional write error */
 
1621                         printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
 
1622                                           name, STp->first_frame_position,
 
1623                                           STp->last_frame_position, STp->cur_frames);
 
1625                         frame = STp->last_frame_position;
 
1629                 if (pending && STp->cur_frames < 50) {
 
1631                         memset(cmd, 0, MAX_COMMAND_SIZE);
 
1636                         printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
 
1637                                           name, STp->frame_seq_number-1, STp->first_frame_position);
 
1639                         SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
 
1640                                                       STp->timeout, MAX_RETRIES, 1);
 
1643                         if (STp->buffer->syscall_result) {              /* additional write error */
 
1644                                 if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
 
1645                                      SRpnt->sense[12]         ==  0 &&
 
1646                                      SRpnt->sense[13]         ==  2) {
 
1648                                                "%s:E: Volume overflow in write error recovery\n",
 
1650                                         break;                          /* hit end of tape = fail */
 
1659                 if (STp->cur_frames == 0) {
 
1662                         printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
 
1664                         if (STp->first_frame_position != expected) {
 
1665                                 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n", 
 
1666                                                 name, STp->first_frame_position, expected);
 
1673                         printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
 
1674                         printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
 
1678                 schedule_timeout_interruptible(msecs_to_jiffies(100));
 
1680         printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
 
1688  * Error recovery algorithm for the OnStream tape.
 
1691 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending)
 
1693         struct osst_request * SRpnt  = * aSRpnt;
 
1694         struct st_partstat  * STps   = & STp->ps[STp->partition];
 
1695         char                * name   = tape_name(STp);
 
1698         unsigned int          frame, skip;
 
1700         rw_state = STps->rw;
 
1702         if ((SRpnt->sense[ 2] & 0x0f) != 3
 
1703           || SRpnt->sense[12]         != 12
 
1704           || SRpnt->sense[13]         != 0) {
 
1706                 printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
 
1707                         SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]);
 
1711         frame = (SRpnt->sense[3] << 24) |
 
1712                 (SRpnt->sense[4] << 16) |
 
1713                 (SRpnt->sense[5] <<  8) |
 
1715         skip  =  SRpnt->sense[9];
 
1718         printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
 
1720         osst_get_frame_position(STp, aSRpnt);
 
1722         printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
 
1723                         name, STp->first_frame_position, STp->last_frame_position);
 
1725         switch (STp->write_type) {
 
1728            case OS_WRITE_NEW_MARK:
 
1730                         "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
 
1731                         name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
 
1732                 if (STp->os_fw_rev >= 10600)
 
1733                         retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
 
1735                         retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
 
1736                 printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
 
1738                                 retval?""     :"Don't worry, ",
 
1739                                 retval?" not ":" ");
 
1741            case OS_WRITE_LAST_MARK:
 
1742                 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
 
1743                 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
 
1746            case OS_WRITE_HEADER:
 
1747                 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
 
1748                 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
 
1751                 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
 
1752                 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
 
1754         osst_get_frame_position(STp, aSRpnt);
 
1756         printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n", 
 
1757                         name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
 
1758         printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
 
1761                 STp->recover_count++;
 
1762                 STp->recover_erreg++;
 
1766         STps->rw = rw_state;
 
1770 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt,
 
1771                                                                  int mt_op, int mt_count)
 
1773         char  * name = tape_name(STp);
 
1775         int     last_mark_ppos = -1;
 
1778         printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
 
1780         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 
1782                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
 
1786         if (STp->linux_media_version >= 4) {
 
1788                  * direct lookup in header filemark list
 
1790                 cnt = ntohl(STp->buffer->aux->filemark_cnt);
 
1791                 if (STp->header_ok                         && 
 
1792                     STp->header_cache != NULL              &&
 
1793                     (cnt - mt_count)  >= 0                 &&
 
1794                     (cnt - mt_count)   < OS_FM_TAB_MAX     &&
 
1795                     (cnt - mt_count)   < STp->filemark_cnt &&
 
1796                     STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
 
1798                         last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
 
1800                 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
 
1801                         printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
 
1802                                STp->header_cache == NULL?"lack of header cache":"count out of range");
 
1804                         printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
 
1806                                 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
 
1807                                  (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
 
1808                                          STp->buffer->aux->last_mark_ppos))?"match":"error",
 
1809                                mt_count, last_mark_ppos);
 
1811                 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
 
1812                         osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
 
1813                         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 
1816                                         "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
 
1820                         if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
 
1821                                 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
 
1822                                                  name, last_mark_ppos);
 
1828                 printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
 
1832         while (cnt != mt_count) {
 
1833                 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
 
1834                 if (last_mark_ppos == -1)
 
1837                 printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
 
1839                 osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
 
1841                 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 
1843                         printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
 
1847                 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
 
1848                         printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
 
1849                                          name, last_mark_ppos);
 
1854         if (mt_op == MTBSFM) {
 
1855                 STp->frame_seq_number++;
 
1856                 STp->frame_in_buffer      = 0;
 
1857                 STp->buffer->buffer_bytes = 0;
 
1858                 STp->buffer->read_pointer = 0;
 
1859                 STp->logical_blk_num     += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
 
1865  * ADRL 1.1 compatible "slow" space filemarks fwd version
 
1867  * Just scans for the filemark sequentially.
 
1869 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt,
 
1870                                                                      int mt_op, int mt_count)
 
1874         char  * name = tape_name(STp);
 
1876         printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
 
1878         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 
1880                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
 
1885                 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 
1887                         printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
 
1891                 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
 
1893                 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
 
1895                         printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
 
1897                         if (STp->first_frame_position > STp->eod_frame_ppos+1) {
 
1899                                 printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
 
1900                                                 name, STp->eod_frame_ppos, STp->first_frame_position-1);
 
1902                                 STp->eod_frame_ppos = STp->first_frame_position-1;
 
1906                 if (cnt == mt_count)
 
1908                 STp->frame_in_buffer = 0;
 
1910         if (mt_op == MTFSF) {
 
1911                 STp->frame_seq_number++;
 
1912                 STp->frame_in_buffer      = 0;
 
1913                 STp->buffer->buffer_bytes = 0;
 
1914                 STp->buffer->read_pointer = 0;
 
1915                 STp->logical_blk_num     += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
 
1921  * Fast linux specific version of OnStream FSF
 
1923 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt,
 
1924                                                                      int mt_op, int mt_count)
 
1926         char  * name = tape_name(STp);
 
1928                 next_mark_ppos = -1;
 
1931         printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
 
1933         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 
1935                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
 
1940         if (STp->linux_media_version >= 4) {
 
1942                  * direct lookup in header filemark list
 
1944                 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
 
1945                 if (STp->header_ok                         && 
 
1946                     STp->header_cache != NULL              &&
 
1947                     (cnt + mt_count)   < OS_FM_TAB_MAX     &&
 
1948                     (cnt + mt_count)   < STp->filemark_cnt &&
 
1949                     ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
 
1950                      (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
 
1952                         next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
 
1954                 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
 
1955                         printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
 
1956                                STp->header_cache == NULL?"lack of header cache":"count out of range");
 
1958                         printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
 
1960                                ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
 
1961                                 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
 
1962                                          STp->buffer->aux->last_mark_ppos))?"match":"error",
 
1963                                mt_count, next_mark_ppos);
 
1965                 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
 
1967                         printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
 
1969                         return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
 
1971                         osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
 
1972                         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 
1974                                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
 
1979                         if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
 
1980                                 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
 
1981                                                  name, next_mark_ppos);
 
1984                         if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
 
1985                                 printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
 
1986                                                  name, cnt+mt_count, next_mark_ppos,
 
1987                                                  ntohl(STp->buffer->aux->filemark_cnt));
 
1993                  * Find nearest (usually previous) marker, then jump from marker to marker
 
1996                         if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
 
1998                         if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
 
2000                                 printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
 
2004                         if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
 
2005                                 if (STp->first_mark_ppos == -1) {
 
2007                                         printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
 
2009                                         return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
 
2011                                 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
 
2012                                 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 
2015                                                "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
 
2020                                 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
 
2021                                         printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
 
2022                                                          name, STp->first_mark_ppos);
 
2026                                 if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
 
2032                 while (cnt != mt_count) {
 
2033                         next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
 
2034                         if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
 
2036                                 printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
 
2038                                 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
 
2041                         else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
 
2043                         osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
 
2045                         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 
2047                                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
 
2052                         if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
 
2053                                 printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
 
2054                                                  name, next_mark_ppos);
 
2059         if (mt_op == MTFSF) {
 
2060                 STp->frame_seq_number++;
 
2061                 STp->frame_in_buffer      = 0;
 
2062                 STp->buffer->buffer_bytes = 0;
 
2063                 STp->buffer->read_pointer = 0;
 
2064                 STp->logical_blk_num     += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
 
2070  * In debug mode, we want to see as many errors as possible
 
2071  * to test the error recovery mechanism.
 
2074 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries)
 
2076         unsigned char           cmd[MAX_COMMAND_SIZE];
 
2077         struct osst_request   * SRpnt  = * aSRpnt;
 
2078         char                  * name   = tape_name(STp);
 
2080         memset(cmd, 0, MAX_COMMAND_SIZE);
 
2081         cmd[0] = MODE_SELECT;
 
2083         cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
2085         (STp->buffer)->b_data[0] = cmd[4] - 1;
 
2086         (STp->buffer)->b_data[1] = 0;                   /* Medium Type - ignoring */
 
2087         (STp->buffer)->b_data[2] = 0;                   /* Reserved */
 
2088         (STp->buffer)->b_data[3] = 0;                   /* Block Descriptor Length */
 
2089         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
 
2090         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
 
2091         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
 
2092         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
 
2095             printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
 
2097         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
 
2100         if ((STp->buffer)->syscall_result)
 
2101             printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
 
2106 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt)
 
2109         int     this_mark_ppos = STp->first_frame_position;
 
2110         int     this_mark_lbn  = STp->logical_blk_num;
 
2112         char  * name = tape_name(STp);
 
2115         if (STp->raw) return 0;
 
2117         STp->write_type = OS_WRITE_NEW_MARK;
 
2119         printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n", 
 
2120                name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
 
2123         result  = osst_flush_write_buffer(STp, aSRpnt);
 
2124         result |= osst_flush_drive_buffer(STp, aSRpnt);
 
2125         STp->last_mark_ppos = this_mark_ppos;
 
2126         STp->last_mark_lbn  = this_mark_lbn;
 
2127         if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
 
2128                 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
 
2129         if (STp->filemark_cnt++ == 0)
 
2130                 STp->first_mark_ppos = this_mark_ppos;
 
2134 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt)
 
2138         char  * name = tape_name(STp);
 
2141         if (STp->raw) return 0;
 
2143         STp->write_type = OS_WRITE_EOD;
 
2144         STp->eod_frame_ppos = STp->first_frame_position;
 
2146         printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
 
2147                         STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
 
2151         result  = osst_flush_write_buffer(STp, aSRpnt); 
 
2152         result |= osst_flush_drive_buffer(STp, aSRpnt);
 
2153         STp->eod_frame_lfa = --(STp->frame_seq_number);
 
2157 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
 
2159         char * name = tape_name(STp);
 
2162         printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
 
2164         osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
 
2165         osst_set_frame_position(STp, aSRpnt, where, 0);
 
2166         STp->write_type = OS_WRITE_FILLER;
 
2168                 memcpy(STp->buffer->b_data, "Filler", 6);
 
2169                 STp->buffer->buffer_bytes = 6;
 
2171                 if (osst_flush_write_buffer(STp, aSRpnt)) {
 
2172                         printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
 
2177         printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
 
2179         return osst_flush_drive_buffer(STp, aSRpnt);
 
2182 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
 
2184         char * name = tape_name(STp);
 
2188         printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
 
2190         osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
 
2191         osst_set_frame_position(STp, aSRpnt, where, 0);
 
2192         STp->write_type = OS_WRITE_HEADER;
 
2194                 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
 
2195                 STp->buffer->buffer_bytes = sizeof(os_header_t);
 
2197                 if (osst_flush_write_buffer(STp, aSRpnt)) {
 
2198                         printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
 
2202         result = osst_flush_drive_buffer(STp, aSRpnt);
 
2204         printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
 
2209 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod)
 
2211         os_header_t * header;
 
2213         char        * name = tape_name(STp);
 
2216         printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
 
2218         if (STp->raw) return 0;
 
2220         if (STp->header_cache == NULL) {
 
2221                 if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
 
2222                         printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
 
2225                 memset(STp->header_cache, 0, sizeof(os_header_t));
 
2227                 printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
 
2230         if (STp->header_ok) STp->update_frame_cntr++;
 
2231         else                STp->update_frame_cntr = 0;
 
2233         header = STp->header_cache;
 
2234         strcpy(header->ident_str, "ADR_SEQ");
 
2235         header->major_rev      = 1;
 
2236         header->minor_rev      = 4;
 
2237         header->ext_trk_tb_off = htons(17192);
 
2238         header->pt_par_num     = 1;
 
2239         header->partition[0].partition_num              = OS_DATA_PARTITION;
 
2240         header->partition[0].par_desc_ver               = OS_PARTITION_VERSION;
 
2241         header->partition[0].wrt_pass_cntr              = htons(STp->wrt_pass_cntr);
 
2242         header->partition[0].first_frame_ppos           = htonl(STp->first_data_ppos);
 
2243         header->partition[0].last_frame_ppos            = htonl(STp->capacity);
 
2244         header->partition[0].eod_frame_ppos             = htonl(STp->eod_frame_ppos);
 
2245         header->cfg_col_width                           = htonl(20);
 
2246         header->dat_col_width                           = htonl(1500);
 
2247         header->qfa_col_width                           = htonl(0);
 
2248         header->ext_track_tb.nr_stream_part             = 1;
 
2249         header->ext_track_tb.et_ent_sz                  = 32;
 
2250         header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
 
2251         header->ext_track_tb.dat_ext_trk_ey.fmt         = 1;
 
2252         header->ext_track_tb.dat_ext_trk_ey.fm_tab_off  = htons(17736);
 
2253         header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
 
2254         header->ext_track_tb.dat_ext_trk_ey.last_hlb    = htonl(STp->eod_frame_lfa);
 
2255         header->ext_track_tb.dat_ext_trk_ey.last_pp     = htonl(STp->eod_frame_ppos);
 
2256         header->dat_fm_tab.fm_part_num                  = 0;
 
2257         header->dat_fm_tab.fm_tab_ent_sz                = 4;
 
2258         header->dat_fm_tab.fm_tab_ent_cnt               = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
 
2259                                                                 STp->filemark_cnt:OS_FM_TAB_MAX);
 
2261         result  = __osst_write_header(STp, aSRpnt, 0xbae, 5);
 
2262         if (STp->update_frame_cntr == 0)
 
2263                     osst_write_filler(STp, aSRpnt, 0xbb3, 5);
 
2264         result &= __osst_write_header(STp, aSRpnt,     5, 5);
 
2268                 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
 
2270                 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
 
2273                 printk(KERN_ERR "%s:E: Write header failed\n", name);
 
2275                 memcpy(STp->application_sig, "LIN4", 4);
 
2276                 STp->linux_media         = 1;
 
2277                 STp->linux_media_version = 4;
 
2283 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt)
 
2285         if (STp->header_cache != NULL)
 
2286                 memset(STp->header_cache, 0, sizeof(os_header_t));
 
2288         STp->logical_blk_num = STp->frame_seq_number = 0;
 
2289         STp->frame_in_buffer = 0;
 
2290         STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
 
2291         STp->filemark_cnt = 0;
 
2292         STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
 
2293         return osst_write_header(STp, aSRpnt, 1);
 
2296 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos)
 
2298         char        * name = tape_name(STp);
 
2299         os_header_t * header;
 
2302         int           linux_media_version,
 
2308         if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
 
2309                 if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
 
2310                         printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
 
2311                 osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
 
2312                 if (osst_initiate_read (STp, aSRpnt)) {
 
2313                         printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
 
2317         if (osst_read_frame(STp, aSRpnt, 180)) {
 
2319                 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
 
2323         header = (os_header_t *) STp->buffer->b_data;   /* warning: only first segment addressable */
 
2324         aux = STp->buffer->aux;
 
2325         if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
 
2327                 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
 
2331         if (ntohl(aux->frame_seq_num)              != 0                   ||
 
2332             ntohl(aux->logical_blk_num)            != 0                   ||
 
2333                   aux->partition.partition_num     != OS_CONFIG_PARTITION ||
 
2334             ntohl(aux->partition.first_frame_ppos) != 0                   ||
 
2335             ntohl(aux->partition.last_frame_ppos)  != 0xbb7               ) {
 
2337                 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
 
2338                                 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
 
2339                                 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
 
2340                                 ntohl(aux->partition.last_frame_ppos));
 
2344         if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
 
2345             strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
 
2346                 strlcpy(id_string, header->ident_str, 8);
 
2348                 printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
 
2352         update_frame_cntr = ntohl(aux->update_frame_cntr);
 
2353         if (update_frame_cntr < STp->update_frame_cntr) {
 
2355                 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
 
2356                                    name, ppos, update_frame_cntr, STp->update_frame_cntr);
 
2360         if (header->major_rev != 1 || header->minor_rev != 4 ) {
 
2362                 printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n", 
 
2363                                  name, (header->major_rev != 1 || header->minor_rev < 2 || 
 
2364                                        header->minor_rev  > 4 )? "Invalid" : "Warning:",
 
2365                                  header->major_rev, header->minor_rev);
 
2367                 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
 
2371         if (header->pt_par_num != 1)
 
2372                 printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n", 
 
2373                                  name, header->pt_par_num);
 
2375         memcpy(id_string, aux->application_sig, 4);
 
2377         if (memcmp(id_string, "LIN", 3) == 0) {
 
2378                 STp->linux_media = 1;
 
2379                 linux_media_version = id_string[3] - '0';
 
2380                 if (linux_media_version != 4)
 
2381                         printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
 
2382                                          name, linux_media_version);
 
2384                 printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
 
2387         if (linux_media_version < STp->linux_media_version) {
 
2389                 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
 
2390                                   name, ppos, linux_media_version);
 
2394         if (linux_media_version > STp->linux_media_version) {
 
2396                 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
 
2397                                    name, ppos, linux_media_version);
 
2399                 memcpy(STp->application_sig, id_string, 5);
 
2400                 STp->linux_media_version = linux_media_version;
 
2401                 STp->update_frame_cntr = -1;
 
2403         if (update_frame_cntr > STp->update_frame_cntr) {
 
2405                 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
 
2406                                    name, ppos, update_frame_cntr);
 
2408                 if (STp->header_cache == NULL) {
 
2409                         if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
 
2410                                 printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
 
2414                         printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
 
2417                 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
 
2418                 header = STp->header_cache;     /* further accesses from cached (full) copy */
 
2420                 STp->wrt_pass_cntr     = ntohs(header->partition[0].wrt_pass_cntr);
 
2421                 STp->first_data_ppos   = ntohl(header->partition[0].first_frame_ppos);
 
2422                 STp->eod_frame_ppos    = ntohl(header->partition[0].eod_frame_ppos);
 
2423                 STp->eod_frame_lfa     = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
 
2424                 STp->filemark_cnt      = ntohl(aux->filemark_cnt);
 
2425                 STp->first_mark_ppos   = ntohl(aux->next_mark_ppos);
 
2426                 STp->last_mark_ppos    = ntohl(aux->last_mark_ppos);
 
2427                 STp->last_mark_lbn     = ntohl(aux->last_mark_lbn);
 
2428                 STp->update_frame_cntr = update_frame_cntr;
 
2430         printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
 
2431                           name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
 
2432         printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
 
2433                           STp->first_data_ppos,
 
2434                           ntohl(header->partition[0].last_frame_ppos),
 
2435                           ntohl(header->partition[0].eod_frame_ppos));
 
2436         printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n", 
 
2437                           name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
 
2439                 if (header->minor_rev < 4 && STp->linux_media_version == 4) {
 
2441                         printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
 
2443                         memcpy((void *)header->dat_fm_tab.fm_tab_ent, 
 
2444                                (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
 
2445                         memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
 
2447                 if (header->minor_rev == 4   &&
 
2448                     (header->ext_trk_tb_off                          != htons(17192)               ||
 
2449                      header->partition[0].partition_num              != OS_DATA_PARTITION          ||
 
2450                      header->partition[0].par_desc_ver               != OS_PARTITION_VERSION       ||
 
2451                      header->partition[0].last_frame_ppos            != htonl(STp->capacity)       ||
 
2452                      header->cfg_col_width                           != htonl(20)                  ||
 
2453                      header->dat_col_width                           != htonl(1500)                ||
 
2454                      header->qfa_col_width                           != htonl(0)                   ||
 
2455                      header->ext_track_tb.nr_stream_part             != 1                          ||
 
2456                      header->ext_track_tb.et_ent_sz                  != 32                         ||
 
2457                      header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION          ||
 
2458                      header->ext_track_tb.dat_ext_trk_ey.fmt         != 1                          ||
 
2459                      header->ext_track_tb.dat_ext_trk_ey.fm_tab_off  != htons(17736)               ||
 
2460                      header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0                          ||
 
2461                      header->ext_track_tb.dat_ext_trk_ey.last_pp     != htonl(STp->eod_frame_ppos) ||
 
2462                      header->dat_fm_tab.fm_part_num                  != OS_DATA_PARTITION          ||
 
2463                      header->dat_fm_tab.fm_tab_ent_sz                != 4                          ||
 
2464                      header->dat_fm_tab.fm_tab_ent_cnt               !=
 
2465                              htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
 
2466                         printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
 
2473 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt)
 
2478         char  * name  = tape_name(STp);
 
2480         position = osst_get_frame_position(STp, aSRpnt);
 
2483                 STp->header_ok = STp->linux_media = 1;
 
2484                 STp->linux_media_version = 0;
 
2487         STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
 
2488         STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
 
2489         STp->eod_frame_ppos = STp->first_data_ppos = -1;
 
2490         STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
 
2492         printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
 
2495         /* optimization for speed - if we are positioned at ppos 10, read second group first  */        
 
2496         /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
 
2498         first = position==10?0xbae: 5;
 
2499         last  = position==10?0xbb3:10;
 
2501         for (ppos = first; ppos < last; ppos++)
 
2502                 if (__osst_analyze_headers(STp, aSRpnt, ppos))
 
2505         first = position==10? 5:0xbae;
 
2506         last  = position==10?10:0xbb3;
 
2508         for (ppos = first; ppos < last; ppos++)
 
2509                 if (__osst_analyze_headers(STp, aSRpnt, ppos))
 
2513                 printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
 
2514                 STp->eod_frame_ppos = STp->first_data_ppos = 0;
 
2515                 osst_set_frame_position(STp, aSRpnt, 10, 0);
 
2518         if (position <= STp->first_data_ppos) {
 
2519                 position = STp->first_data_ppos;
 
2520                 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
 
2522         osst_set_frame_position(STp, aSRpnt, position, 0);
 
2528 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt)
 
2530         int     frame_position  = STp->first_frame_position;
 
2531         int     frame_seq_numbr = STp->frame_seq_number;
 
2532         int     logical_blk_num = STp->logical_blk_num;
 
2533         int     halfway_frame   = STp->frame_in_buffer;
 
2534         int     read_pointer    = STp->buffer->read_pointer;
 
2535         int     prev_mark_ppos  = -1;
 
2536         int     actual_mark_ppos, i, n;
 
2538         char  * name = tape_name(STp);
 
2540         printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
 
2542         osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
 
2543         if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 
2545                 printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
 
2549         if (STp->linux_media_version >= 4) {
 
2550                 for (i=0; i<STp->filemark_cnt; i++)
 
2551                         if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
 
2554                 prev_mark_ppos = frame_position - 1;  /* usually - we don't really know */
 
2555         actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
 
2556                                 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
 
2557         if (frame_position  != STp->first_frame_position                   ||
 
2558             frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
 
2559             prev_mark_ppos  != actual_mark_ppos                            ) {
 
2561                 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
 
2562                                   STp->first_frame_position, frame_position, 
 
2563                                   STp->frame_seq_number + (halfway_frame?0:1),
 
2564                                   frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
 
2568         if (halfway_frame) {
 
2569                 /* prepare buffer for append and rewrite on top of original */
 
2570                 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
 
2571                 STp->buffer->buffer_bytes  = read_pointer;
 
2572                 STp->ps[STp->partition].rw = ST_WRITING;
 
2575         STp->frame_in_buffer  = halfway_frame;
 
2576         STp->frame_seq_number = frame_seq_numbr;
 
2577         STp->logical_blk_num  = logical_blk_num;
 
2581 /* Acc. to OnStream, the vers. numbering is the following:
 
2582  * X.XX for released versions (X=digit), 
 
2583  * XXXY for unreleased versions (Y=letter)
 
2584  * Ordering 1.05 < 106A < 106B < ...  < 106a < ... < 1.06
 
2585  * This fn makes monoton numbers out of this scheme ...
 
2587 static unsigned int osst_parse_firmware_rev (const char * str)
 
2589         if (str[1] == '.') {
 
2590                 return (str[0]-'0')*10000
 
2594                 return (str[0]-'0')*10000
 
2596                         +(str[2]-'0')*100 - 100
 
2602  * Configure the OnStream SCII tape drive for default operation
 
2604 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
 
2606         unsigned char                  cmd[MAX_COMMAND_SIZE];
 
2607         char                         * name = tape_name(STp);
 
2608         struct osst_request          * SRpnt = * aSRpnt;
 
2609         osst_mode_parameter_header_t * header;
 
2610         osst_block_size_page_t       * bs;
 
2611         osst_capabilities_page_t     * cp;
 
2612         osst_tape_paramtr_page_t     * prm;
 
2613         int                            drive_buffer_size;
 
2615         if (STp->ready != ST_READY) {
 
2617             printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
 
2622         if (STp->os_fw_rev < 10600) {
 
2623             printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
 
2624             printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
 
2628          * Configure 32.5KB (data+aux) frame size.
 
2629          * Get the current frame size from the block size mode page
 
2631         memset(cmd, 0, MAX_COMMAND_SIZE);
 
2632         cmd[0] = MODE_SENSE;
 
2634         cmd[2] = BLOCK_SIZE_PAGE;
 
2635         cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
2637         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
 
2638         if (SRpnt == NULL) {
 
2640             printk(OSST_DEB_MSG "osst :D: Busy\n");
 
2645         if ((STp->buffer)->syscall_result != 0) {
 
2646             printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
 
2650         header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
 
2651         bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
 
2654         printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n",   name, bs->play32     ? "Yes" : "No");
 
2655         printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5   ? "Yes" : "No");
 
2656         printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n",      name, bs->record32   ? "Yes" : "No");
 
2657         printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n",    name, bs->record32_5 ? "Yes" : "No");
 
2661          * Configure default auto columns mode, 32.5KB transfer mode
 
2669         memset(cmd, 0, MAX_COMMAND_SIZE);
 
2670         cmd[0] = MODE_SELECT;
 
2672         cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
2674         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
 
2676         if ((STp->buffer)->syscall_result != 0) {
 
2677             printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
 
2682         printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
 
2684          * In debug mode, we want to see as many errors as possible
 
2685          * to test the error recovery mechanism.
 
2687         osst_set_retries(STp, aSRpnt, 0);
 
2692          * Set vendor name to 'LIN4' for "Linux support version 4".
 
2695         memset(cmd, 0, MAX_COMMAND_SIZE);
 
2696         cmd[0] = MODE_SELECT;
 
2698         cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
2700         header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
 
2701         header->medium_type      = 0;   /* Medium Type - ignoring */
 
2702         header->dsp              = 0;   /* Reserved */
 
2703         header->bdl              = 0;   /* Block Descriptor Length */
 
2705         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
 
2706         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
 
2707         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
 
2708         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
 
2709         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
 
2710         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
 
2711         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
 
2712         (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
 
2714         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
 
2717         if ((STp->buffer)->syscall_result != 0) {
 
2718             printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name, 
 
2719                         (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
 
2723         memset(cmd, 0, MAX_COMMAND_SIZE);
 
2724         cmd[0] = MODE_SENSE;
 
2726         cmd[2] = CAPABILITIES_PAGE;
 
2727         cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
2729         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
 
2732         if ((STp->buffer)->syscall_result != 0) {
 
2733             printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
 
2737         header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
 
2738         cp     = (osst_capabilities_page_t    *) ((STp->buffer)->b_data +
 
2739                  sizeof(osst_mode_parameter_header_t) + header->bdl);
 
2741         drive_buffer_size = ntohs(cp->buffer_size) / 2;
 
2743         memset(cmd, 0, MAX_COMMAND_SIZE);
 
2744         cmd[0] = MODE_SENSE;
 
2746         cmd[2] = TAPE_PARAMTR_PAGE;
 
2747         cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
2749         SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
 
2752         if ((STp->buffer)->syscall_result != 0) {
 
2753             printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
 
2757         header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
 
2758         prm    = (osst_tape_paramtr_page_t    *) ((STp->buffer)->b_data +
 
2759                  sizeof(osst_mode_parameter_header_t) + header->bdl);
 
2761         STp->density  = prm->density;
 
2762         STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
 
2764         printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
 
2765                           name, STp->density, STp->capacity / 32, drive_buffer_size);
 
2773 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
 
2774    it messes up the block number). */
 
2775 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward)
 
2778         char  * name = tape_name(STp);
 
2782                 printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
 
2783                                   name, forward ? "forward" : "backward");
 
2787            /* assumes that the filemark is already read by the drive, so this is low cost */
 
2788            result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
 
2791            /* assumes this is only called if we just read the filemark! */
 
2792            result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
 
2795            printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
 
2796                                 name, forward ? "forward" : "backward");
 
2802 /* Get the tape position. */
 
2804 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
 
2806         unsigned char           scmd[MAX_COMMAND_SIZE];
 
2807         struct osst_request   * SRpnt;
 
2809         char                  * name   = tape_name(STp);
 
2811         /* KG: We want to be able to use it for checking Write Buffer availability
 
2812          *  and thus don't want to risk to overwrite anything. Exchange buffers ... */
 
2814         char          * olddata = STp->buffer->b_data;
 
2815         int             oldsize = STp->buffer->buffer_size;
 
2817         if (STp->ready != ST_READY) return (-EIO);
 
2819         memset (scmd, 0, MAX_COMMAND_SIZE);
 
2820         scmd[0] = READ_POSITION;
 
2822         STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
 
2823         SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
 
2824                                       STp->timeout, MAX_RETRIES, 1);
 
2826                 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
 
2831         if (STp->buffer->syscall_result)
 
2832                 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL;      /* 3: Write Error */
 
2834         if (result == -EINVAL)
 
2835                 printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
 
2837                 if (result == -EIO) {   /* re-read position - this needs to preserve media errors */
 
2838                         unsigned char mysense[16];
 
2839                         memcpy (mysense, SRpnt->sense, 16);
 
2840                         memset (scmd, 0, MAX_COMMAND_SIZE);
 
2841                         scmd[0] = READ_POSITION;
 
2842                         STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
 
2843                         SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
 
2844                                                     STp->timeout, MAX_RETRIES, 1);
 
2846                         printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
 
2847                                         name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
 
2848                                         SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]);
 
2850                         if (!STp->buffer->syscall_result)
 
2851                                 memcpy (SRpnt->sense, mysense, 16);
 
2853                                 printk(KERN_WARNING "%s:W: Double error in get position\n", name);
 
2855                 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
 
2856                                           + ((STp->buffer)->b_data[5] << 16)
 
2857                                           + ((STp->buffer)->b_data[6] << 8)
 
2858                                           +  (STp->buffer)->b_data[7];
 
2859                 STp->last_frame_position  = ((STp->buffer)->b_data[ 8] << 24)
 
2860                                           + ((STp->buffer)->b_data[ 9] << 16)
 
2861                                           + ((STp->buffer)->b_data[10] <<  8)
 
2862                                           +  (STp->buffer)->b_data[11];
 
2863                 STp->cur_frames           =  (STp->buffer)->b_data[15];
 
2866                         printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
 
2867                                             STp->first_frame_position, STp->last_frame_position,
 
2868                                             ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
 
2869                                             ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
 
2873                 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
 
2875                         printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
 
2876                                         STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
 
2878                         STp->first_frame_position = STp->last_frame_position;
 
2881         STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
 
2883         return (result == 0 ? STp->first_frame_position : result);
 
2887 /* Set the tape block */
 
2888 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip)
 
2890         unsigned char           scmd[MAX_COMMAND_SIZE];
 
2891         struct osst_request   * SRpnt;
 
2892         struct st_partstat    * STps;
 
2894         int                     pp     = (ppos == 3000 && !skip)? 0 : ppos;
 
2895         char                  * name   = tape_name(STp);
 
2897         if (STp->ready != ST_READY) return (-EIO);
 
2899         STps = &(STp->ps[STp->partition]);
 
2901         if (ppos < 0 || ppos > STp->capacity) {
 
2902                 printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
 
2903                 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
 
2910                         printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
 
2912                 memset (scmd, 0, MAX_COMMAND_SIZE);
 
2915                 scmd[3] = (pp >> 24);
 
2916                 scmd[4] = (pp >> 16);
 
2917                 scmd[5] = (pp >> 8);
 
2922                 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
 
2928                 if ((STp->buffer)->syscall_result != 0) {
 
2930                         printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
 
2931                                         name, STp->first_frame_position, pp);
 
2936                         osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
 
2937         } while ((pp != ppos) && (pp = ppos));
 
2938         STp->first_frame_position = STp->last_frame_position = ppos;
 
2939         STps->eof = ST_NOEOF;
 
2942         STp->frame_in_buffer = 0;
 
2946 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT)
 
2948         struct st_partstat * STps = &(STp->ps[STp->partition]);
 
2951         if (STp->write_type != OS_WRITE_NEW_MARK) {
 
2952                 /* true unless the user wrote the filemark for us */
 
2953                 result = osst_flush_drive_buffer(STp, aSRpnt);
 
2954                 if (result < 0) goto out;
 
2955                 result = osst_write_filemark(STp, aSRpnt);
 
2956                 if (result < 0) goto out;
 
2958                 if (STps->drv_file >= 0)
 
2960                 STps->drv_block = 0;
 
2962         result = osst_write_eod(STp, aSRpnt);
 
2963         osst_write_header(STp, aSRpnt, leave_at_EOT);
 
2970 /* osst versions of st functions - augmented and stripped to suit OnStream only */
 
2972 /* Flush the write buffer (never need to write if variable blocksize). */
 
2973 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt)
 
2975         int                     offset, transfer, blks = 0;
 
2977         unsigned char           cmd[MAX_COMMAND_SIZE];
 
2978         struct osst_request   * SRpnt = *aSRpnt;
 
2979         struct st_partstat    * STps;
 
2980         char                  * name = tape_name(STp);
 
2982         if ((STp->buffer)->writing) {
 
2983                 if (SRpnt == (STp->buffer)->last_SRpnt)
 
2985                         { printk(OSST_DEB_MSG
 
2986          "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name);
 
2988                         *aSRpnt = SRpnt = NULL;
 
2992          "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name);
 
2994                 osst_write_behind_check(STp);
 
2995                 if ((STp->buffer)->syscall_result) {
 
2998                                 printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
 
2999                                        name, (STp->buffer)->midlevel_result);
 
3001                         if ((STp->buffer)->midlevel_result == INT_MAX)
 
3008         if (STp->dirty == 1) {
 
3011                 STps     = &(STp->ps[STp->partition]);
 
3012                 STps->rw = ST_WRITING;
 
3013                 offset   = STp->buffer->buffer_bytes;
 
3014                 blks     = (offset + STp->block_size - 1) / STp->block_size;
 
3015                 transfer = OS_FRAME_SIZE;
 
3017                 if (offset < OS_DATA_SIZE)
 
3018                         osst_zero_buffer_tail(STp->buffer);
 
3021                         if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
 
3022                                 result = osst_recover_wait_frame(STp, aSRpnt, 1);
 
3024                 memset(cmd, 0, MAX_COMMAND_SIZE);
 
3029                 switch  (STp->write_type) {
 
3033                                 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
 
3034                                         name, blks, STp->frame_seq_number, 
 
3035                                         STp->logical_blk_num - blks, STp->logical_blk_num - 1);
 
3037                         osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
 
3038                                       STp->logical_blk_num - blks, STp->block_size, blks);
 
3041                         osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
 
3042                                       STp->logical_blk_num, 0, 0);
 
3044                    case OS_WRITE_NEW_MARK:
 
3045                         osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
 
3046                                       STp->logical_blk_num++, 0, blks=1);
 
3048                    case OS_WRITE_HEADER:
 
3049                         osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
 
3051                 default: /* probably FILLER */
 
3052                         osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
 
3056                         printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
 
3057                                                  name, offset, transfer, blks);
 
3060                 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
 
3061                                               STp->timeout, MAX_RETRIES, 1);
 
3066                 if ((STp->buffer)->syscall_result != 0) {
 
3069                                 "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
 
3070                                 name, SRpnt->sense[0], SRpnt->sense[2],
 
3071                                 SRpnt->sense[12], SRpnt->sense[13]);
 
3073                         if ((SRpnt->sense[0] & 0x70) == 0x70 &&
 
3074                             (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
 
3075                             (SRpnt->sense[2] & 0x0f) == NO_SENSE) {
 
3077                                 (STp->buffer)->buffer_bytes = 0;
 
3081                                 if (osst_write_error_recovery(STp, aSRpnt, 1)) {
 
3082                                         printk(KERN_ERR "%s:E: Error on flush write.\n", name);
 
3086                         STps->drv_block = (-1);         /* FIXME - even if write recovery succeeds? */
 
3089                         STp->first_frame_position++;
 
3091                         (STp->buffer)->buffer_bytes = 0;
 
3095         printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
 
3101 /* Flush the tape buffer. The tape will be positioned correctly unless
 
3102    seek_next is true. */
 
3103 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next)
 
3105         struct st_partstat * STps;
 
3106         int    backspace = 0, result = 0;
 
3108         char * name = tape_name(STp);
 
3112          * If there was a bus reset, block further access
 
3115         if( STp->pos_unknown)
 
3118         if (STp->ready != ST_READY)
 
3121         STps = &(STp->ps[STp->partition]);
 
3122         if (STps->rw == ST_WRITING || STp->dirty) {     /* Writing */
 
3123                 STp->write_type = OS_WRITE_DATA;
 
3124                 return osst_flush_write_buffer(STp, aSRpnt);
 
3126         if (STp->block_size == 0)
 
3130         printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
 
3133         if (!STp->can_bsr) {
 
3134                 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
 
3135                             ((STp->buffer)->read_pointer + STp->block_size - 1        ) / STp->block_size ;
 
3136                 (STp->buffer)->buffer_bytes = 0;
 
3137                 (STp->buffer)->read_pointer = 0;
 
3138                 STp->frame_in_buffer = 0;               /* FIXME is this relevant w. OSST? */
 
3142                 if (STps->eof == ST_FM_HIT) {
 
3143                         result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
 
3145                                 STps->eof = ST_NOEOF;
 
3147                                 if (STps->drv_file >= 0)
 
3149                                 STps->drv_block = 0;
 
3152                 if (!result && backspace > 0)   /* TODO -- design and run a test case for this */
 
3153                         result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
 
3155         else if (STps->eof == ST_FM_HIT) {
 
3156                 if (STps->drv_file >= 0)
 
3158                 STps->drv_block = 0;
 
3159                 STps->eof = ST_NOEOF;
 
3165 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous)
 
3167         unsigned char           cmd[MAX_COMMAND_SIZE];
 
3168         struct osst_request   * SRpnt;
 
3171         char                  * name = tape_name(STp);
 
3174         if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
 
3176                 printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
 
3178                 if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
 
3181                 /* error recovery may have bumped us past the header partition */
 
3182                 if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
 
3184                         printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
 
3186                 osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
 
3191                 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
 
3192                         if (osst_recover_wait_frame(STp, aSRpnt, 1))
 
3195 //      osst_build_stats(STp, &SRpnt);
 
3197         STp->ps[STp->partition].rw = ST_WRITING;
 
3198         STp->write_type            = OS_WRITE_DATA;
 
3200         memset(cmd, 0, MAX_COMMAND_SIZE);
 
3203         cmd[4]   = 1;                                           /* one frame at a time... */
 
3204         blks     = STp->buffer->buffer_bytes / STp->block_size;
 
3207                 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks, 
 
3208                         STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
 
3210         osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
 
3211                       STp->logical_blk_num - blks, STp->block_size, blks);
 
3215                 STp->write_pending = 1;
 
3217         SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
 
3218                                                                         MAX_RETRIES, synchronous);
 
3224                 if (STp->buffer->syscall_result != 0) {
 
3227                                 printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
 
3229                         if ((SRpnt->sense[0] & 0x70) == 0x70 &&
 
3230                             (SRpnt->sense[2] & 0x40)) {
 
3231                                 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW)
 
3235                                 if (osst_write_error_recovery(STp, aSRpnt, 1))
 
3240                         STp->first_frame_position++;
 
3248 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */
 
3249 static int do_door_lock(struct osst_tape * STp, int do_lock)
 
3253         cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
 
3255         printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
 
3257         retval = scsi_ioctl(STp->device, cmd, NULL);
 
3259                 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
 
3262                 STp->door_locked = ST_LOCK_FAILS;
 
3267 /* Set the internal state after reset */
 
3268 static void reset_state(struct osst_tape *STp)
 
3271         struct st_partstat *STps;
 
3273         STp->pos_unknown = 0;
 
3274         for (i = 0; i < ST_NBR_PARTITIONS; i++) {
 
3275                 STps = &(STp->ps[i]);
 
3277                 STps->eof = ST_NOEOF;
 
3279                 STps->last_block_valid = 0;
 
3280                 STps->drv_block = -1;
 
3281                 STps->drv_file = -1;
 
3286 /* Entry points to osst */
 
3289 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
 
3291         ssize_t               total, retval = 0;
 
3292         ssize_t               i, do_count, blks, transfer;
 
3293         int                   write_threshold;
 
3294         int                   doing_write = 0;
 
3295         const char   __user * b_point;
 
3296         struct osst_request * SRpnt = NULL;
 
3297         struct st_modedef   * STm;
 
3298         struct st_partstat  * STps;
 
3299         struct osst_tape    * STp  = filp->private_data;
 
3300         char                * name = tape_name(STp);
 
3303         if (mutex_lock_interruptible(&STp->lock))
 
3304                 return (-ERESTARTSYS);
 
3307          * If we are in the middle of error recovery, don't let anyone
 
3308          * else try and use this device.  Also, if error recovery fails, it
 
3309          * may try and take the device offline, in which case all further
 
3310          * access to the device is prohibited.
 
3312         if( !scsi_block_when_processing_errors(STp->device) ) {
 
3317         if (STp->ready != ST_READY) {
 
3318                 if (STp->ready == ST_NO_TAPE)
 
3319                         retval = (-ENOMEDIUM);
 
3324         STm = &(STp->modes[STp->current_mode]);
 
3325         if (!STm->defined) {
 
3333          * If there was a bus reset, block further access
 
3336         if (STp->pos_unknown) {
 
3343                 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
 
3349         if (STp->write_prot) {
 
3354         /* Write must be integral number of blocks */
 
3355         if (STp->block_size != 0 && (count % STp->block_size) != 0) {
 
3356                 printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
 
3357                                        name, count, STp->block_size<1024?
 
3358                                        STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
 
3363         if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
 
3364                 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
 
3365                                        name, STp->first_frame_position);
 
3370         if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
 
3371                 STp->door_locked = ST_LOCKED_AUTO;
 
3373         STps = &(STp->ps[STp->partition]);
 
3375         if (STps->rw == ST_READING) {
 
3377                 printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name, 
 
3378                                         STps->drv_file, STps->drv_block);
 
3380                 retval = osst_flush_buffer(STp, &SRpnt, 0);
 
3385         if (STps->rw != ST_WRITING) {
 
3386                 /* Are we totally rewriting this tape? */
 
3387                 if (!STp->header_ok ||
 
3388                     (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
 
3389                     (STps->drv_file == 0 && STps->drv_block == 0)) {
 
3390                         STp->wrt_pass_cntr++;
 
3392                         printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
 
3393                                                   name, STp->wrt_pass_cntr);
 
3395                         osst_reset_header(STp, &SRpnt);
 
3396                         STps->drv_file = STps->drv_block = 0;
 
3398                 /* Do we know where we'll be writing on the tape? */
 
3400                         if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
 
3401                                         STps->drv_file < 0 || STps->drv_block < 0) {
 
3402                                 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
 
3403                                         STps->drv_file = STp->filemark_cnt;
 
3404                                         STps->drv_block = 0;
 
3407                                         /* We have no idea where the tape is positioned - give up */
 
3410                                                 "%s:D: Cannot write at indeterminate position.\n", name);
 
3416                         if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
 
3417                                 STp->filemark_cnt = STps->drv_file;
 
3418                                 STp->last_mark_ppos =
 
3419                                         ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
 
3421                                         "%s:W: Overwriting file %d with old write pass counter %d\n",
 
3422                                                 name, STps->drv_file, STp->wrt_pass_cntr);
 
3424                                         "%s:W: may lead to stale data being accepted on reading back!\n",
 
3428                                   "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
 
3429                                         name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
 
3435         if (!STp->header_ok) {
 
3437                 printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
 
3443         if ((STp->buffer)->writing) {
 
3444 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
 
3445                 osst_write_behind_check(STp);
 
3446                 if ((STp->buffer)->syscall_result) {
 
3449                         printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
 
3450                                                  (STp->buffer)->midlevel_result);
 
3452                 if ((STp->buffer)->midlevel_result == INT_MAX)
 
3453                         STps->eof = ST_EOM_OK;
 
3455                         STps->eof = ST_EOM_ERROR;
 
3458         if (STps->eof == ST_EOM_OK) {
 
3462         else if (STps->eof == ST_EOM_ERROR) {
 
3467         /* Check the buffer readability in cases where copy_user might catch
 
3468                  the problems after some tape movement. */
 
3469         if ((copy_from_user(&i, buf, 1) != 0 ||
 
3470              copy_from_user(&i, buf + count - 1, 1) != 0)) {
 
3475         if (!STm->do_buffer_writes) {
 
3476                 write_threshold = 1;
 
3479                 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
 
3480         if (!STm->do_async_writes)
 
3486                 printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
 
3487                                 name, (int) count, STps->drv_file, STps->drv_block,
 
3488                                 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
 
3491         while ((STp->buffer)->buffer_bytes + count > write_threshold)
 
3494                 do_count = (STp->buffer)->buffer_blocks * STp->block_size -
 
3495                            (STp->buffer)->buffer_bytes;
 
3496                 if (do_count > count)
 
3499                 i = append_to_buffer(b_point, STp->buffer, do_count);
 
3505                 blks = do_count / STp->block_size;
 
3506                 STp->logical_blk_num += blks;  /* logical_blk_num is incremented as data is moved from user */
 
3508                 i = osst_write_frame(STp, &SRpnt, 1);
 
3510                 if (i == (-ENOSPC)) {
 
3511                         transfer = STp->buffer->writing;        /* FIXME -- check this logic */
 
3512                         if (transfer <= do_count) {
 
3513                                 filp->f_pos += do_count - transfer;
 
3514                                 count -= do_count - transfer;
 
3515                                 if (STps->drv_block >= 0) {
 
3516                                         STps->drv_block += (do_count - transfer) / STp->block_size;
 
3518                                 STps->eof = ST_EOM_OK;
 
3519                                 retval = (-ENOSPC);             /* EOM within current request */
 
3522                                       printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
 
3523                                                              name, (int) transfer);
 
3527                                 STps->eof = ST_EOM_ERROR;
 
3528                                 STps->drv_block = (-1);         /* Too cautious? */
 
3529                                 retval = (-EIO);                /* EOM for old data */
 
3532                                       printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
 
3540                         if (SRpnt != NULL) {
 
3541                                 osst_release_request(SRpnt);
 
3544                         STp->buffer->buffer_bytes = 0;
 
3547                                 retval = total - count;
 
3551                 filp->f_pos += do_count;
 
3552                 b_point += do_count;
 
3554                 if (STps->drv_block >= 0) {
 
3555                         STps->drv_block += blks;
 
3557                 STp->buffer->buffer_bytes = 0;
 
3559         }  /* end while write threshold exceeded */
 
3563                 i = append_to_buffer(b_point, STp->buffer, count);
 
3568                 blks = count / STp->block_size;
 
3569                 STp->logical_blk_num += blks;
 
3570                 if (STps->drv_block >= 0) {
 
3571                         STps->drv_block += blks;
 
3573                 filp->f_pos += count;
 
3577         if (doing_write && (STp->buffer)->syscall_result != 0) {
 
3578                 retval = (STp->buffer)->syscall_result;
 
3582         if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) { 
 
3583                 /* Schedule an asynchronous write */
 
3584                 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
 
3585                                            STp->block_size) * STp->block_size;
 
3586                 STp->dirty = !((STp->buffer)->writing ==
 
3587                                           (STp->buffer)->buffer_bytes);
 
3589                 i = osst_write_frame(STp, &SRpnt, 0);
 
3594                 SRpnt = NULL;                   /* Prevent releasing this request! */
 
3596         STps->at_sm &= (total == 0);
 
3598                 STps->eof = ST_NOEOF;
 
3603         if (SRpnt != NULL) osst_release_request(SRpnt);
 
3605         mutex_unlock(&STp->lock);
 
3612 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
 
3614         ssize_t               total, retval = 0;
 
3615         ssize_t               i, transfer;
 
3617         struct st_modedef   * STm;
 
3618         struct st_partstat  * STps;
 
3619         struct osst_request * SRpnt = NULL;
 
3620         struct osst_tape    * STp   = filp->private_data;
 
3621         char                * name  = tape_name(STp);
 
3624         if (mutex_lock_interruptible(&STp->lock))
 
3625                 return (-ERESTARTSYS);
 
3628          * If we are in the middle of error recovery, don't let anyone
 
3629          * else try and use this device.  Also, if error recovery fails, it
 
3630          * may try and take the device offline, in which case all further
 
3631          * access to the device is prohibited.
 
3633         if( !scsi_block_when_processing_errors(STp->device) ) {
 
3638         if (STp->ready != ST_READY) {
 
3639                 if (STp->ready == ST_NO_TAPE)
 
3640                         retval = (-ENOMEDIUM);
 
3645         STm = &(STp->modes[STp->current_mode]);
 
3646         if (!STm->defined) {
 
3652                 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
 
3657         /* Must have initialized medium */
 
3658         if (!STp->header_ok) {
 
3663         if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
 
3664                 STp->door_locked = ST_LOCKED_AUTO;
 
3666         STps = &(STp->ps[STp->partition]);
 
3667         if (STps->rw == ST_WRITING) {
 
3668                 retval = osst_flush_buffer(STp, &SRpnt, 0);
 
3672                 /* FIXME -- this may leave the tape without EOD and up2date headers */
 
3675         if ((count % STp->block_size) != 0) {
 
3677                     "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
 
3678                     STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
 
3682         if (debugging && STps->eof != ST_NOEOF)
 
3683                 printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
 
3684                                      STps->eof, (STp->buffer)->buffer_bytes);
 
3686         if ((STp->buffer)->buffer_bytes == 0 &&
 
3687              STps->eof >= ST_EOD_1) {
 
3688                 if (STps->eof < ST_EOD) {
 
3693                 retval = (-EIO);  /* EOM or Blank Check */
 
3697         /* Check the buffer writability before any tape movement. Don't alter
 
3699         if (copy_from_user(&i, buf, 1)             != 0 ||
 
3700             copy_to_user  (buf, &i, 1)             != 0 ||
 
3701             copy_from_user(&i, buf + count - 1, 1) != 0 ||
 
3702             copy_to_user  (buf + count - 1, &i, 1) != 0) {
 
3707         /* Loop until enough data in buffer or a special condition found */
 
3708         for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
 
3710                 /* Get new data if the buffer is empty */
 
3711                 if ((STp->buffer)->buffer_bytes == 0) {
 
3712                         if (STps->eof == ST_FM_HIT)
 
3714                         special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
 
3715                         if (special < 0) {                      /* No need to continue read */
 
3716                                 STp->frame_in_buffer = 0;
 
3722                 /* Move the data from driver buffer to user buffer */
 
3723                 if ((STp->buffer)->buffer_bytes > 0) {
 
3725                         if (debugging && STps->eof != ST_NOEOF)
 
3726                             printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
 
3727                                                  STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total));
 
3729                         /* force multiple of block size, note block_size may have been adjusted */
 
3730                         transfer = (((STp->buffer)->buffer_bytes < count - total ?
 
3731                                      (STp->buffer)->buffer_bytes : count - total)/
 
3732                                         STp->block_size) * STp->block_size;
 
3734                         if (transfer == 0) {
 
3736                                   "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
 
3737                                         name, count, STp->block_size < 1024?
 
3738                                         STp->block_size:STp->block_size/1024,
 
3739                                         STp->block_size<1024?'b':'k');
 
3742                         i = from_buffer(STp->buffer, buf, transfer);
 
3747                         STp->logical_blk_num += transfer / STp->block_size;
 
3748                         STps->drv_block      += transfer / STp->block_size;
 
3749                         filp->f_pos          += transfer;
 
3754                 if ((STp->buffer)->buffer_bytes == 0) {
 
3757                                 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
 
3758                                                 name, STp->frame_seq_number);
 
3760                         STp->frame_in_buffer = 0;
 
3761                         STp->frame_seq_number++;              /* frame to look for next time */
 
3763         } /* for (total = 0, special = 0; total < count && !special; ) */
 
3765         /* Change the eof state if no data from tape or buffer */
 
3767                 if (STps->eof == ST_FM_HIT) {
 
3768                         STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
 
3769                         STps->drv_block = 0;
 
3770                         if (STps->drv_file >= 0)
 
3773                 else if (STps->eof == ST_EOD_1) {
 
3774                         STps->eof = ST_EOD_2;
 
3775                         if (STps->drv_block > 0 && STps->drv_file >= 0)
 
3777                         STps->drv_block = 0;
 
3779                 else if (STps->eof == ST_EOD_2)
 
3782         else if (STps->eof == ST_FM)
 
3783                 STps->eof = ST_NOEOF;
 
3788         if (SRpnt != NULL) osst_release_request(SRpnt);
 
3790         mutex_unlock(&STp->lock);
 
3796 /* Set the driver options */
 
3797 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
 
3800 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
 
3801          name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
 
3802          STm->do_read_ahead);
 
3804 "%s:I:    can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
 
3805          name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
 
3807 "%s:I:    defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
 
3808          name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
 
3809          STp->scsi2_logical);
 
3811 "%s:I:    sysv: %d\n", name, STm->sysv);
 
3814          "%s:D:    debugging: %d\n",
 
3820 static int osst_set_options(struct osst_tape *STp, long options)
 
3824         struct st_modedef * STm;
 
3825         char              * name = tape_name(STp);
 
3827         STm = &(STp->modes[STp->current_mode]);
 
3828         if (!STm->defined) {
 
3829                 memcpy(STm, &(STp->modes[0]), sizeof(*STm));
 
3833                         printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
 
3834                                              name, STp->current_mode);
 
3838         code = options & MT_ST_OPTIONS;
 
3839         if (code == MT_ST_BOOLEANS) {
 
3840                 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
 
3841                 STm->do_async_writes  = (options & MT_ST_ASYNC_WRITES) != 0;
 
3842                 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
 
3843                 STm->do_read_ahead    = (options & MT_ST_READ_AHEAD) != 0;
 
3844                 STp->two_fm           = (options & MT_ST_TWO_FM) != 0;
 
3845                 STp->fast_mteom       = (options & MT_ST_FAST_MTEOM) != 0;
 
3846                 STp->do_auto_lock     = (options & MT_ST_AUTO_LOCK) != 0;
 
3847                 STp->can_bsr          = (options & MT_ST_CAN_BSR) != 0;
 
3848                 STp->omit_blklims     = (options & MT_ST_NO_BLKLIMS) != 0;
 
3849                 if ((STp->device)->scsi_level >= SCSI_2)
 
3850                         STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
 
3851                 STp->scsi2_logical    = (options & MT_ST_SCSI2LOGICAL) != 0;
 
3852                 STm->sysv             = (options & MT_ST_SYSV) != 0;
 
3854                 debugging = (options & MT_ST_DEBUGGING) != 0;
 
3856                 osst_log_options(STp, STm, name);
 
3858         else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
 
3859                 value = (code == MT_ST_SETBOOLEANS);
 
3860                 if ((options & MT_ST_BUFFER_WRITES) != 0)
 
3861                         STm->do_buffer_writes = value;
 
3862                 if ((options & MT_ST_ASYNC_WRITES) != 0)
 
3863                         STm->do_async_writes = value;
 
3864                 if ((options & MT_ST_DEF_WRITES) != 0)
 
3865                         STm->defaults_for_writes = value;
 
3866                 if ((options & MT_ST_READ_AHEAD) != 0)
 
3867                         STm->do_read_ahead = value;
 
3868                 if ((options & MT_ST_TWO_FM) != 0)
 
3869                         STp->two_fm = value;
 
3870                 if ((options & MT_ST_FAST_MTEOM) != 0)
 
3871                         STp->fast_mteom = value;
 
3872                 if ((options & MT_ST_AUTO_LOCK) != 0)
 
3873                         STp->do_auto_lock = value;
 
3874                 if ((options & MT_ST_CAN_BSR) != 0)
 
3875                         STp->can_bsr = value;
 
3876                 if ((options & MT_ST_NO_BLKLIMS) != 0)
 
3877                         STp->omit_blklims = value;
 
3878                 if ((STp->device)->scsi_level >= SCSI_2 &&
 
3879                     (options & MT_ST_CAN_PARTITIONS) != 0)
 
3880                         STp->can_partitions = value;
 
3881                 if ((options & MT_ST_SCSI2LOGICAL) != 0)
 
3882                         STp->scsi2_logical = value;
 
3883                 if ((options & MT_ST_SYSV) != 0)
 
3886                 if ((options & MT_ST_DEBUGGING) != 0)
 
3889                 osst_log_options(STp, STm, name);
 
3891         else if (code == MT_ST_WRITE_THRESHOLD) {
 
3892                 value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
 
3893                 if (value < 1 || value > osst_buffer_size) {
 
3894                         printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
 
3898                 STp->write_threshold = value;
 
3899                 printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
 
3902         else if (code == MT_ST_DEF_BLKSIZE) {
 
3903                 value = (options & ~MT_ST_OPTIONS);
 
3904                 if (value == ~MT_ST_OPTIONS) {
 
3905                         STm->default_blksize = (-1);
 
3906                         printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
 
3909                         if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
 
3910                                 printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
 
3914                         STm->default_blksize = value;
 
3915                         printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
 
3916                                           name, STm->default_blksize);
 
3919         else if (code == MT_ST_TIMEOUTS) {
 
3920                 value = (options & ~MT_ST_OPTIONS);
 
3921                 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
 
3922                         STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
 
3923                         printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
 
3924                                              (value & ~MT_ST_SET_LONG_TIMEOUT));
 
3927                         STp->timeout = value * HZ;
 
3928                         printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
 
3931         else if (code == MT_ST_DEF_OPTIONS) {
 
3932                 code = (options & ~MT_ST_CLEAR_DEFAULT);
 
3933                 value = (options & MT_ST_CLEAR_DEFAULT);
 
3934                 if (code == MT_ST_DEF_DENSITY) {
 
3935                         if (value == MT_ST_CLEAR_DEFAULT) {
 
3936                                 STm->default_density = (-1);
 
3937                                 printk(KERN_INFO "%s:I: Density default disabled.\n", name);
 
3940                                 STm->default_density = value & 0xff;
 
3941                                 printk(KERN_INFO "%s:I: Density default set to %x\n",
 
3942                                                   name, STm->default_density);
 
3945                 else if (code == MT_ST_DEF_DRVBUFFER) {
 
3946                         if (value == MT_ST_CLEAR_DEFAULT) {
 
3947                                 STp->default_drvbuffer = 0xff;
 
3948                                 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
 
3951                                 STp->default_drvbuffer = value & 7;
 
3952                                 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
 
3953                                                   name, STp->default_drvbuffer);
 
3956                 else if (code == MT_ST_DEF_COMPRESSION) {
 
3957                         if (value == MT_ST_CLEAR_DEFAULT) {
 
3958                                 STm->default_compression = ST_DONT_TOUCH;
 
3959                                 printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
 
3962                                 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
 
3963                                 printk(KERN_INFO "%s:I: Compression default set to %x\n",
 
3975 /* Internal ioctl function */
 
3976 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt,
 
3977                              unsigned int cmd_in, unsigned long arg)
 
3981         int                     i, ioctl_result;
 
3983         unsigned char           cmd[MAX_COMMAND_SIZE];
 
3984         struct osst_request   * SRpnt = * aSRpnt;
 
3985         struct st_partstat    * STps;
 
3986         int                     fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
 
3987         int                     datalen = 0, direction = DMA_NONE;
 
3988         char                  * name = tape_name(STp);
 
3990         if (STp->ready != ST_READY && cmd_in != MTLOAD) {
 
3991                 if (STp->ready == ST_NO_TAPE)
 
3992                         return (-ENOMEDIUM);
 
3996         timeout = STp->long_timeout;
 
3997         STps = &(STp->ps[STp->partition]);
 
3998         fileno = STps->drv_file;
 
3999         blkno = STps->drv_block;
 
4000         at_sm = STps->at_sm;
 
4001         frame_seq_numbr = STp->frame_seq_number;
 
4002         logical_blk_num = STp->logical_blk_num;
 
4004         memset(cmd, 0, MAX_COMMAND_SIZE);
 
4007                 chg_eof = 0; /* Changed from the FSF after this */
 
4011                 if (STp->linux_media)
 
4012                    ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
 
4014                    ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
 
4018                 at_sm &= (arg == 0);
 
4022                 chg_eof = 0; /* Changed from the FSF after this */
 
4026                 ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
 
4029                 blkno = (-1);  /* We can't know the block number */
 
4030                 at_sm &= (arg == 0);
 
4037                    printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
 
4038                                 name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
 
4040                 if (cmd_in == MTFSR) {
 
4041                    logical_blk_num += arg;
 
4042                    if (blkno >= 0) blkno += arg;
 
4045                    logical_blk_num -= arg;
 
4046                    if (blkno >= 0) blkno -= arg;
 
4048                 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
 
4049                 fileno = STps->drv_file;
 
4050                 blkno  = STps->drv_block;
 
4051                 at_sm &= (arg == 0);
 
4056                 cmd[1] = 0x04; /* Space Setmarks */   /* FIXME -- OS can't do this? */
 
4057                 cmd[2] = (arg >> 16);
 
4058                 cmd[3] = (arg >> 8);
 
4062                         printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
 
4063                 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
 
4066                         blkno = fileno = (-1);
 
4072                 cmd[1] = 0x04; /* Space Setmarks */   /* FIXME -- OS can't do this? */
 
4074                 cmd[2] = (ltmp >> 16);
 
4075                 cmd[3] = (ltmp >> 8);
 
4081                         ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
 
4082                         printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
 
4087                         blkno = fileno = (-1);
 
4092                  if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
 
4093                         STp->write_type = OS_WRITE_DATA;
 
4094                         ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
 
4099                            printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
 
4101                  for (i=0; i<arg; i++)
 
4102                         ioctl_result |= osst_write_filemark(STp, &SRpnt);
 
4103                  if (fileno >= 0) fileno += arg;
 
4104                  if (blkno  >= 0) blkno   = 0;
 
4108                  if (STp->write_prot)
 
4112                  cmd[0] = WRITE_FILEMARKS;   /* FIXME -- need OS version */
 
4113                  if (cmd_in == MTWSM)
 
4115                  cmd[2] = (arg >> 16);
 
4116                  cmd[3] = (arg >> 8);
 
4118                  timeout = STp->timeout;
 
4121                            printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
 
4122                                   cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
 
4127                  at_sm = (cmd_in == MTWSM);
 
4133                  cmd[0] = START_STOP;
 
4134                  cmd[1] = 1;                    /* Don't wait for completion */
 
4135                  if (cmd_in == MTLOAD) {
 
4136                      if (STp->ready == ST_NO_TAPE)
 
4137                          cmd[4] = 4;            /* open tray */
 
4139                          cmd[4] = 1;            /* load */
 
4141                  if (cmd_in == MTRETEN)
 
4142                          cmd[4] = 3;            /* retension then mount */
 
4143                  if (cmd_in == MTOFFL)
 
4144                          cmd[4] = 4;            /* rewind then eject */
 
4145                  timeout = STp->timeout;
 
4150                                          printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
 
4153                                          printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
 
4156                                          printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
 
4159                                          printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
 
4164        fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
 
4169                          printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
 
4171                  return 0;  /* Should do something ? */
 
4176                    printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
 
4178                 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
 
4179                             (osst_get_logical_frame(STp, &SRpnt, -1, 0)               < 0)) {
 
4180                    ioctl_result = -EIO;
 
4183                 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
 
4185                    printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
 
4187                    ioctl_result = -EIO;
 
4190                 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
 
4191                 fileno = STp->filemark_cnt;
 
4196                 if (STp->write_prot)
 
4198                 ioctl_result = osst_reset_header(STp, &SRpnt);
 
4199                 i = osst_write_eod(STp, &SRpnt);
 
4200                 if (i < ioctl_result) ioctl_result = i;
 
4201                 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
 
4202                 if (i < ioctl_result) ioctl_result = i;
 
4203                 fileno = blkno = at_sm = 0 ;
 
4207                 cmd[0] = REZERO_UNIT; /* rewind */
 
4211                    printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
 
4213                 fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
 
4216          case MTSETBLK:           /* Set block length */
 
4217                  if ((STps->drv_block == 0 )                      &&
 
4219                      ((STp->buffer)->buffer_bytes == 0)           &&
 
4220                      ((arg & MT_ST_BLKSIZE_MASK) >= 512 )         && 
 
4221                      ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
 
4222                      !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))  ) {
 
4224                           * Only allowed to change the block size if you opened the
 
4225                           * device at the beginning of a file before writing anything.
 
4226                           * Note, that when reading, changing block_size is futile,
 
4227                           * as the size used when writing overrides it.
 
4229                          STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
 
4230                          printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
 
4231                                            name, STp->block_size);
 
4234          case MTSETDENSITY:       /* Set tape density */
 
4235          case MTSETDRVBUFFER:     /* Set drive buffering */
 
4236          case SET_DENS_AND_BLK:   /* Set density and block size */
 
4238                  if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
 
4239                          return (-EIO);       /* Not allowed if data in buffer */
 
4240                  if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
 
4241                      (arg & MT_ST_BLKSIZE_MASK) != 0                    &&
 
4242                      (arg & MT_ST_BLKSIZE_MASK) != STp->block_size       ) {
 
4243                          printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
 
4244                                                 name, (int)(arg & MT_ST_BLKSIZE_MASK),
 
4245                                                 (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
 
4248                  return 0;  /* FIXME silently ignore if block size didn't change */
 
4254         SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
 
4256         ioctl_result = (STp->buffer)->syscall_result;
 
4260                 printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
 
4262                 return ioctl_result;
 
4265         if (!ioctl_result) {  /* SCSI command successful */
 
4266                 STp->frame_seq_number = frame_seq_numbr;
 
4267                 STp->logical_blk_num  = logical_blk_num;
 
4273                 printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
 
4276         if (!ioctl_result) {                            /* success */
 
4278                 if (cmd_in == MTFSFM) {
 
4282                 if (cmd_in == MTBSFM) {
 
4286                 STps->drv_block = blkno;
 
4287                 STps->drv_file = fileno;
 
4288                 STps->at_sm = at_sm;
 
4290                 if (cmd_in == MTEOM)
 
4292                 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
 
4293                         ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
 
4295                         STp->logical_blk_num++;
 
4296                         STp->frame_seq_number++;
 
4297                         STp->frame_in_buffer = 0;
 
4298                         STp->buffer->read_pointer = 0;
 
4300                 else if (cmd_in == MTFSF)
 
4301                         STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
 
4303                         STps->eof = ST_NOEOF;
 
4305                 if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
 
4306                         STp->rew_at_close = 0;
 
4307                 else if (cmd_in == MTLOAD) {
 
4308                         for (i=0; i < ST_NBR_PARTITIONS; i++) {
 
4309                             STp->ps[i].rw = ST_IDLE;
 
4310                             STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
 
4315                 if (cmd_in == MTREW) {
 
4316                         ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos); 
 
4317                         if (ioctl_result > 0)
 
4321         } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
 
4322                 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
 
4323                         STps->drv_file = STps->drv_block = -1;
 
4325                         STps->drv_file = STps->drv_block = 0;
 
4326                 STps->eof = ST_NOEOF;
 
4327         } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
 
4328                 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
 
4329                         STps->drv_file = STps->drv_block = -1;
 
4331                         STps->drv_file  = STp->filemark_cnt;
 
4332                         STps->drv_block = 0;
 
4335         } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
 
4336                 STps->drv_file = STps->drv_block = (-1);
 
4337                 STps->eof = ST_NOEOF;
 
4339         } else if (cmd_in == MTERASE) {
 
4341         } else if (SRpnt) {  /* SCSI command was not completely successful. */
 
4342                 if (SRpnt->sense[2] & 0x40) {
 
4343                         STps->eof = ST_EOM_OK;
 
4344                         STps->drv_block = 0;
 
4347                         STps->eof = ST_NOEOF;
 
4349                 if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK)
 
4352                 if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
 
4353                         ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
 
4357         return ioctl_result;
 
4361 /* Open the device */
 
4362 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
 
4364         unsigned short        flags;
 
4365         int                   i, b_size, new_session = 0, retval = 0;
 
4366         unsigned char         cmd[MAX_COMMAND_SIZE];
 
4367         struct osst_request * SRpnt = NULL;
 
4368         struct osst_tape    * STp;
 
4369         struct st_modedef   * STm;
 
4370         struct st_partstat  * STps;
 
4372         int                   dev  = TAPE_NR(inode);
 
4373         int                   mode = TAPE_MODE(inode);
 
4376          * We really want to do nonseekable_open(inode, filp); here, but some
 
4377          * versions of tar incorrectly call lseek on tapes and bail out if that
 
4378          * fails.  So we disallow pread() and pwrite(), but permit lseeks.
 
4380         filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
 
4382         write_lock(&os_scsi_tapes_lock);
 
4383         if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
 
4384             (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
 
4385                 write_unlock(&os_scsi_tapes_lock);
 
4389         name = tape_name(STp);
 
4392                 write_unlock(&os_scsi_tapes_lock);
 
4394                 printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
 
4398         if (scsi_device_get(STp->device)) {
 
4399                 write_unlock(&os_scsi_tapes_lock);
 
4401                 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
 
4405         filp->private_data = STp;
 
4407         write_unlock(&os_scsi_tapes_lock);
 
4408         STp->rew_at_close = TAPE_REWIND(inode);
 
4410         if( !scsi_block_when_processing_errors(STp->device) ) {
 
4414         if (mode != STp->current_mode) {
 
4417                         printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
 
4418                                                name, STp->current_mode, mode);
 
4421                 STp->current_mode = mode;
 
4423         STm = &(STp->modes[STp->current_mode]);
 
4425         flags = filp->f_flags;
 
4426         STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
 
4428         STp->raw = TAPE_IS_RAW(inode);
 
4432         /* Allocate data segments for this device's tape buffer */
 
4433         if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
 
4434                 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
 
4435                 retval = (-EOVERFLOW);
 
4438         if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
 
4439                 for (i = 0, b_size = 0; 
 
4440                      (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); 
 
4441                      b_size += STp->buffer->sg[i++].length);
 
4442                 STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
 
4444                 printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
 
4445                         STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
 
4446                 printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
 
4447                          STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
 
4450                 STp->buffer->aux = NULL; /* this had better never happen! */
 
4451                 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
 
4455         STp->buffer->writing = 0;
 
4456         STp->buffer->syscall_result = 0;
 
4458         for (i=0; i < ST_NBR_PARTITIONS; i++) {
 
4459                 STps = &(STp->ps[i]);
 
4462         STp->ready = ST_READY;
 
4464         STp->nbr_waits = STp->nbr_finished = 0;
 
4467         memset (cmd, 0, MAX_COMMAND_SIZE);
 
4468         cmd[0] = TEST_UNIT_READY;
 
4470         SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 
4472                 retval = (STp->buffer)->syscall_result;         /* FIXME - valid? */
 
4475         if ((SRpnt->sense[0] & 0x70) == 0x70      &&
 
4476             (SRpnt->sense[2] & 0x0f) == NOT_READY &&
 
4477              SRpnt->sense[12]        == 4         ) {
 
4479                 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]);
 
4481                 if (filp->f_flags & O_NONBLOCK) {
 
4485                 if (SRpnt->sense[13] == 2) {    /* initialize command required (LOAD) */
 
4486                         memset (cmd, 0, MAX_COMMAND_SIZE);
 
4487                         cmd[0] = START_STOP;
 
4490                         SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
 
4491                                              STp->timeout, MAX_RETRIES, 1);
 
4493                 osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
 
4495         if ((SRpnt->sense[0] & 0x70) == 0x70 &&
 
4496             (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
 
4498                 printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
 
4502                 for (i=0; i < 10; i++) {
 
4504                         memset (cmd, 0, MAX_COMMAND_SIZE);
 
4505                         cmd[0] = TEST_UNIT_READY;
 
4507                         SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
 
4508                                              STp->timeout, MAX_RETRIES, 1);
 
4509                         if ((SRpnt->sense[0] & 0x70) != 0x70 ||
 
4510                             (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
 
4514                 STp->pos_unknown = 0;
 
4515                 STp->partition = STp->new_partition = 0;
 
4516                 if (STp->can_partitions)
 
4517                         STp->nbr_partitions = 1;  /* This guess will be updated later if necessary */
 
4518                 for (i=0; i < ST_NBR_PARTITIONS; i++) {
 
4519                         STps = &(STp->ps[i]);
 
4520                         STps->rw = ST_IDLE;             /* FIXME - seems to be redundant... */
 
4521                         STps->eof = ST_NOEOF;
 
4523                         STps->last_block_valid = 0;
 
4524                         STps->drv_block = 0;
 
4525                         STps->drv_file = 0 ;
 
4528                 STp->recover_count = 0;
 
4529                 STp->abort_count = 0;
 
4532          * if we have valid headers from before, and the drive/tape seem untouched,
 
4533          * open without reconfiguring and re-reading the headers
 
4535         if (!STp->buffer->syscall_result && STp->header_ok &&
 
4536             !SRpnt->result && SRpnt->sense[0] == 0) {
 
4538                 memset(cmd, 0, MAX_COMMAND_SIZE);
 
4539                 cmd[0] = MODE_SENSE;
 
4541                 cmd[2] = VENDOR_IDENT_PAGE;
 
4542                 cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
4544                 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
 
4546                 if (STp->buffer->syscall_result                     ||
 
4547                     STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
 
4548                     STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
 
4549                     STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
 
4550                     STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4'  ) {
 
4552                         printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
 
4553                           STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
 
4554                           STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
 
4555                           STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
 
4556                           STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
 
4560                 i = STp->first_frame_position;
 
4561                 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
 
4562                         if (STp->door_locked == ST_UNLOCKED) {
 
4563                                 if (do_door_lock(STp, 1))
 
4564                                         printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
 
4566                                         STp->door_locked = ST_LOCKED_AUTO;
 
4568                         if (!STp->frame_in_buffer) {
 
4569                                 STp->block_size = (STm->default_blksize > 0) ?
 
4570                                                         STm->default_blksize : OS_DATA_SIZE;
 
4571                                 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
 
4573                         STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
 
4575                         osst_release_request(SRpnt);
 
4579                 if (i != STp->first_frame_position)
 
4580                         printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
 
4581                                                 name, i, STp->first_frame_position);
 
4587         if ((STp->buffer)->syscall_result != 0 &&   /* in all error conditions except no medium */ 
 
4588             (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) {
 
4590                 memset(cmd, 0, MAX_COMMAND_SIZE);
 
4591                 cmd[0] = MODE_SELECT;
 
4593                 cmd[4] = 4 + MODE_HEADER_LENGTH;
 
4595                 (STp->buffer)->b_data[0] = cmd[4] - 1;
 
4596                 (STp->buffer)->b_data[1] = 0;                   /* Medium Type - ignoring */
 
4597                 (STp->buffer)->b_data[2] = 0;                   /* Reserved */
 
4598                 (STp->buffer)->b_data[3] = 0;                   /* Block Descriptor Length */
 
4599                 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
 
4600                 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
 
4601                 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
 
4602                 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
 
4605                 printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
 
4607                 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
 
4611                 for (i=0; i < 10; i++) {
 
4613                         memset (cmd, 0, MAX_COMMAND_SIZE);
 
4614                         cmd[0] = TEST_UNIT_READY;
 
4616                         SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
 
4617                                                     STp->timeout, MAX_RETRIES, 1);
 
4618                         if ((SRpnt->sense[0] & 0x70) != 0x70 ||
 
4619                             (SRpnt->sense[2] & 0x0f) == NOT_READY)
 
4622                         if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
 
4623                                 STp->pos_unknown = 0;
 
4624                                 STp->partition = STp->new_partition = 0;
 
4625                                 if (STp->can_partitions)
 
4626                                         STp->nbr_partitions = 1;  /* This guess will be updated later if necessary */
 
4627                                 for (i=0; i < ST_NBR_PARTITIONS; i++) {
 
4628                                         STps = &(STp->ps[i]);
 
4630                                         STps->eof = ST_NOEOF;
 
4632                                         STps->last_block_valid = 0;
 
4633                                         STps->drv_block = 0;
 
4634                                         STps->drv_file = 0 ;
 
4641         if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0))           /* FIXME - not allowed with NOBLOCK */
 
4642                  printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
 
4644         if ((STp->buffer)->syscall_result != 0) {
 
4645                 if ((STp->device)->scsi_level >= SCSI_2 &&
 
4646                     (SRpnt->sense[0] & 0x70) == 0x70 &&
 
4647                     (SRpnt->sense[2] & 0x0f) == NOT_READY &&
 
4648                      SRpnt->sense[12] == 0x3a) { /* Check ASC */
 
4649                         STp->ready = ST_NO_TAPE;
 
4651                         STp->ready = ST_NOT_READY;
 
4652                 osst_release_request(SRpnt);
 
4654                 STp->density = 0;       /* Clear the erroneous "residue" */
 
4655                 STp->write_prot = 0;
 
4656                 STp->block_size = 0;
 
4657                 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
 
4658                 STp->partition = STp->new_partition = 0;
 
4659                 STp->door_locked = ST_UNLOCKED;
 
4663         osst_configure_onstream(STp, &SRpnt);
 
4665         STp->block_size = STp->raw ? OS_FRAME_SIZE : (
 
4666                              (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
 
4667         STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
 
4668         STp->buffer->buffer_bytes  =
 
4669         STp->buffer->read_pointer  =
 
4670         STp->frame_in_buffer       = 0;
 
4674                 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
 
4675                      name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
 
4676                      (STp->buffer)->buffer_blocks);
 
4679         if (STp->drv_write_prot) {
 
4680                 STp->write_prot = 1;
 
4683                         printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
 
4685                 if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
 
4691         if (new_session) {  /* Change the drive parameters for the new mode */
 
4694         printk(OSST_DEB_MSG "%s:D: New Session\n", name);
 
4696                 STp->density_changed = STp->blksize_changed = 0;
 
4697                 STp->compression_changed = 0;
 
4701          * properly position the tape and check the ADR headers
 
4703         if (STp->door_locked == ST_UNLOCKED) {
 
4704                  if (do_door_lock(STp, 1))
 
4705                         printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
 
4707                         STp->door_locked = ST_LOCKED_AUTO;
 
4710         osst_analyze_headers(STp, &SRpnt);
 
4712         osst_release_request(SRpnt);
 
4719                 osst_release_request(SRpnt);
 
4720         normalize_buffer(STp->buffer);
 
4723         scsi_device_put(STp->device);
 
4729 /* Flush the tape buffer before close */
 
4730 static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
 
4732         int                   result = 0, result2;
 
4733         struct osst_tape    * STp    = filp->private_data;
 
4734         struct st_modedef   * STm    = &(STp->modes[STp->current_mode]);
 
4735         struct st_partstat  * STps   = &(STp->ps[STp->partition]);
 
4736         struct osst_request * SRpnt  = NULL;
 
4737         char                * name   = tape_name(STp);
 
4739         if (file_count(filp) > 1)
 
4742         if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
 
4743                 STp->write_type = OS_WRITE_DATA;
 
4744                 result = osst_flush_write_buffer(STp, &SRpnt);
 
4745                 if (result != 0 && result != (-ENOSPC))
 
4748         if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
 
4752                         printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
 
4753                                                name, (long)(filp->f_pos));
 
4754                         printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
 
4755                                                name, STp->nbr_waits, STp->nbr_finished);
 
4758                 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
 
4761                         printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
 
4762                                                name, 1+STp->two_fm);
 
4765         else if (!STp->rew_at_close) {
 
4766                 STps = &(STp->ps[STp->partition]);
 
4767                 if (!STm->sysv || STps->rw != ST_READING) {
 
4769                                 result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
 
4770                         else if (STps->eof == ST_FM_HIT) {
 
4771                                 result = cross_eof(STp, &SRpnt, 0);
 
4773                                                 if (STps->drv_file >= 0)
 
4775                                                 STps->drv_block = 0;
 
4779                                                 STps->eof = ST_NOEOF;
 
4782                 else if ((STps->eof == ST_NOEOF &&
 
4783                           !(result = cross_eof(STp, &SRpnt, 1))) ||
 
4784                          STps->eof == ST_FM_HIT) {
 
4785                         if (STps->drv_file >= 0)
 
4787                         STps->drv_block = 0;
 
4793         if (STp->rew_at_close) {
 
4794                 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
 
4795                 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
 
4796                 if (result == 0 && result2 < 0)
 
4799         if (SRpnt) osst_release_request(SRpnt);
 
4801         if (STp->abort_count || STp->recover_count) {
 
4802                 printk(KERN_INFO "%s:I:", name);
 
4803                 if (STp->abort_count)
 
4804                         printk(" %d unrecovered errors", STp->abort_count);
 
4805                 if (STp->recover_count)
 
4806                         printk(" %d recovered errors", STp->recover_count);
 
4807                 if (STp->write_count)
 
4808                         printk(" in %d frames written", STp->write_count);
 
4809                 if (STp->read_count)
 
4810                         printk(" in %d frames read", STp->read_count);
 
4812                 STp->recover_count = 0;
 
4813                 STp->abort_count   = 0;
 
4815         STp->write_count = 0;
 
4816         STp->read_count  = 0;
 
4822 /* Close the device and release it */
 
4823 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
 
4826         struct osst_tape    * STp    = filp->private_data;
 
4828         if (STp->door_locked == ST_LOCKED_AUTO)
 
4829                 do_door_lock(STp, 0);
 
4834         normalize_buffer(STp->buffer);
 
4835         write_lock(&os_scsi_tapes_lock);
 
4837         write_unlock(&os_scsi_tapes_lock);
 
4839         scsi_device_put(STp->device);
 
4845 /* The ioctl command */
 
4846 static int osst_ioctl(struct inode * inode,struct file * file,
 
4847          unsigned int cmd_in, unsigned long arg)
 
4849         int                   i, cmd_nr, cmd_type, blk, retval = 0;
 
4850         struct st_modedef   * STm;
 
4851         struct st_partstat  * STps;
 
4852         struct osst_request * SRpnt = NULL;
 
4853         struct osst_tape    * STp   = file->private_data;
 
4854         char                * name  = tape_name(STp);
 
4855         void        __user  * p     = (void __user *)arg;
 
4857         if (mutex_lock_interruptible(&STp->lock))
 
4858                 return -ERESTARTSYS;
 
4861         if (debugging && !STp->in_use) {
 
4862                 printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
 
4867         STm = &(STp->modes[STp->current_mode]);
 
4868         STps = &(STp->ps[STp->partition]);
 
4871          * If we are in the middle of error recovery, don't let anyone
 
4872          * else try and use this device.  Also, if error recovery fails, it
 
4873          * may try and take the device offline, in which case all further
 
4874          * access to the device is prohibited.
 
4876         if( !scsi_block_when_processing_errors(STp->device) ) {
 
4881         cmd_type = _IOC_TYPE(cmd_in);
 
4882         cmd_nr   = _IOC_NR(cmd_in);
 
4884         printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
 
4885                             cmd_type, cmd_nr, STp->raw?"raw":"normal");
 
4887         if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
 
4891                 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
 
4896                 i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
 
4902                 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
 
4903                         printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
 
4908                 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
 
4913                 if (!STp->pos_unknown) {
 
4915                         if (STps->eof == ST_FM_HIT) {
 
4916                                 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
 
4918                                         if (STps->drv_file >= 0)
 
4919                                                 STps->drv_file += 1;
 
4921                                 else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
 
4923                                         if (STps->drv_file >= 0)
 
4924                                                 STps->drv_file += 1;
 
4928                         if (mtc.mt_op == MTSEEK) {
 
4929                                 /* Old position must be restored if partition will be changed */
 
4930                                 i = !STp->can_partitions || (STp->new_partition != STp->partition);
 
4933                                 i = mtc.mt_op == MTREW   || mtc.mt_op == MTOFFL ||
 
4934                                     mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM  ||
 
4935                                     mtc.mt_op == MTLOCK  || mtc.mt_op == MTLOAD ||
 
4936                                     mtc.mt_op == MTFSF   || mtc.mt_op == MTFSFM ||
 
4937                                     mtc.mt_op == MTBSF   || mtc.mt_op == MTBSFM ||
 
4938                                     mtc.mt_op == MTCOMPRESSION;
 
4940                         i = osst_flush_buffer(STp, &SRpnt, i);
 
4948                          * If there was a bus reset, block further access
 
4949                          * to this device.  If the user wants to rewind the tape,
 
4950                          * then reset the flag and allow access again.
 
4952                         if(mtc.mt_op != MTREW   &&
 
4953                            mtc.mt_op != MTOFFL  &&
 
4954                            mtc.mt_op != MTRETEN &&
 
4955                            mtc.mt_op != MTERASE &&
 
4956                            mtc.mt_op != MTSEEK  &&
 
4957                            mtc.mt_op != MTEOM)   {
 
4962                         /* remove this when the midlevel properly clears was_reset */
 
4963                         STp->device->was_reset = 0;
 
4966                 if (mtc.mt_op != MTCOMPRESSION  && mtc.mt_op != MTLOCK         &&
 
4967                     mtc.mt_op != MTNOP          && mtc.mt_op != MTSETBLK       &&
 
4968                     mtc.mt_op != MTSETDENSITY   && mtc.mt_op != MTSETDRVBUFFER && 
 
4969                     mtc.mt_op != MTMKPART       && mtc.mt_op != MTSETPART      &&
 
4970                     mtc.mt_op != MTWEOF         && mtc.mt_op != MTWSM           ) {
 
4973                          * The user tells us to move to another position on the tape.
 
4974                          * If we were appending to the tape content, that would leave
 
4975                          * the tape without proper end, in that case write EOD and
 
4976                          * update the header to reflect its position.
 
4979                         printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
 
4980                                         STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
 
4981                                         STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
 
4982                                         STp->logical_blk_num, STps->drv_file, STps->drv_block );
 
4984                         if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
 
4985                                 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
 
4986                                                         !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
 
4987                                 i = osst_write_trailer(STp, &SRpnt,
 
4988                                                         !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
 
4990                                 printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
 
4991                                                 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
 
4992                                                 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
 
5002                 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
 
5003                         do_door_lock(STp, 0);  /* Ignore result! */
 
5005                 if (mtc.mt_op == MTSETDRVBUFFER &&
 
5006                    (mtc.mt_count & MT_ST_OPTIONS) != 0) {
 
5007                         retval = osst_set_options(STp, mtc.mt_count);
 
5011                 if (mtc.mt_op == MTSETPART) {
 
5012                         if (mtc.mt_count >= STp->nbr_partitions)
 
5015                                 STp->new_partition = mtc.mt_count;
 
5021                 if (mtc.mt_op == MTMKPART) {
 
5022                         if (!STp->can_partitions) {
 
5026                         if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
 
5027                             (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
 
5031                         for (i=0; i < ST_NBR_PARTITIONS; i++) {
 
5032                                 STp->ps[i].rw = ST_IDLE;
 
5033                                 STp->ps[i].at_sm = 0;
 
5034                                 STp->ps[i].last_block_valid = 0;
 
5036                         STp->partition = STp->new_partition = 0;
 
5037                         STp->nbr_partitions = 1;  /* Bad guess ?-) */
 
5038                         STps->drv_block = STps->drv_file = 0;
 
5043                 if (mtc.mt_op == MTSEEK) {
 
5045                                 i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
 
5047                                 i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
 
5048                         if (!STp->can_partitions)
 
5049                                 STp->ps[0].rw = ST_IDLE;
 
5054                 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
 
5055                         retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
 
5060                         cross_eof(STp, &SRpnt, 0);
 
5062                 if (mtc.mt_op == MTCOMPRESSION)
 
5063                         retval = -EINVAL;       /* OnStream drives don't have compression hardware */
 
5065                         /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
 
5066                          * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
 
5067                         retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
 
5071         if (!STm->defined) {
 
5076         if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
 
5081         if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
 
5082                 struct mtget mt_status;
 
5084                 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
 
5089                 mt_status.mt_type = MT_ISONSTREAM_SC;
 
5090                 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
 
5091                 mt_status.mt_dsreg =
 
5092                         ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
 
5093                         ((STp->density    << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
 
5094                 mt_status.mt_blkno = STps->drv_block;
 
5095                 mt_status.mt_fileno = STps->drv_file;
 
5096                 if (STp->block_size != 0) {
 
5097                         if (STps->rw == ST_WRITING)
 
5098                                 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
 
5099                         else if (STps->rw == ST_READING)
 
5100                                 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
 
5101                                                         STp->block_size - 1) / STp->block_size;
 
5104                 mt_status.mt_gstat = 0;
 
5105                 if (STp->drv_write_prot)
 
5106                         mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
 
5107                 if (mt_status.mt_blkno == 0) {
 
5108                         if (mt_status.mt_fileno == 0)
 
5109                                 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
 
5111                                 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
 
5113                 mt_status.mt_resid = STp->partition;
 
5114                 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
 
5115                         mt_status.mt_gstat |= GMT_EOT(0xffffffff);
 
5116                 else if (STps->eof >= ST_EOM_OK)
 
5117                         mt_status.mt_gstat |= GMT_EOD(0xffffffff);
 
5118                 if (STp->density == 1)
 
5119                         mt_status.mt_gstat |= GMT_D_800(0xffffffff);
 
5120                 else if (STp->density == 2)
 
5121                         mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
 
5122                 else if (STp->density == 3)
 
5123                         mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
 
5124                 if (STp->ready == ST_READY)
 
5125                         mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
 
5126                 if (STp->ready == ST_NO_TAPE)
 
5127                         mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
 
5129                         mt_status.mt_gstat |= GMT_SM(0xffffffff);
 
5130                 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
 
5131                     STp->drv_buffer != 0)
 
5132                         mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
 
5134                 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
 
5140                 STp->recover_erreg = 0;  /* Clear after read */
 
5143         } /* End of MTIOCGET */
 
5145         if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
 
5146                 struct mtpos mt_pos;
 
5148                 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
 
5153                         blk = osst_get_frame_position(STp, &SRpnt);
 
5155                         blk = osst_get_sector(STp, &SRpnt);
 
5160                 mt_pos.mt_blkno = blk;
 
5161                 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
 
5166         if (SRpnt) osst_release_request(SRpnt);
 
5168         mutex_unlock(&STp->lock);
 
5170         return scsi_ioctl(STp->device, cmd_in, p);
 
5173         if (SRpnt) osst_release_request(SRpnt);
 
5175         mutex_unlock(&STp->lock);
 
5180 #ifdef CONFIG_COMPAT
 
5181 static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg)
 
5183         struct osst_tape *STp = file->private_data;
 
5184         struct scsi_device *sdev = STp->device;
 
5185         int ret = -ENOIOCTLCMD;
 
5186         if (sdev->host->hostt->compat_ioctl) {
 
5188                 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
 
5197 /* Memory handling routines */
 
5199 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
 
5200 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
 
5204         struct osst_buffer *tb;
 
5206         if (from_initialization)
 
5207                 priority = GFP_ATOMIC;
 
5209                 priority = GFP_KERNEL;
 
5211         i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
 
5212         tb = kzalloc(i, priority);
 
5214                 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
 
5218         tb->sg_segs = tb->orig_sg_segs = 0;
 
5219         tb->use_sg = max_sg;
 
5222         tb->buffer_size = 0;
 
5226                         "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
 
5227                            i, max_sg, need_dma);
 
5232 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
 
5233 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 
5235         int segs, nbr, max_segs, b_size, order, got;
 
5238         if (STbuffer->buffer_size >= OS_FRAME_SIZE)
 
5241         if (STbuffer->sg_segs) {
 
5242                 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
 
5243                 normalize_buffer(STbuffer);
 
5245         /* See how many segments we can use -- need at least two */
 
5246         nbr = max_segs = STbuffer->use_sg;
 
5250         priority = GFP_KERNEL /* | __GFP_NOWARN */;
 
5252                 priority |= GFP_DMA;
 
5254         /* Try to allocate the first segment up to OS_DATA_SIZE and the others
 
5255            big enough to reach the goal (code assumes no segments in place) */
 
5256         for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
 
5257                 struct page *page = alloc_pages(priority, order);
 
5259                 STbuffer->sg[0].offset = 0;
 
5261                     sg_set_page(&STbuffer->sg[0], page, b_size, 0);
 
5262                     STbuffer->b_data = page_address(page);
 
5266         if (sg_page(&STbuffer->sg[0]) == NULL) {
 
5267                 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
 
5270         /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
 
5271         for (segs=STbuffer->sg_segs=1, got=b_size;
 
5272              segs < max_segs && got < OS_FRAME_SIZE; ) {
 
5273                 struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
 
5274                 STbuffer->sg[segs].offset = 0;
 
5276                         if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
 
5277                                 b_size /= 2;  /* Large enough for the rest of the buffers */
 
5281                         printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
 
5284                         STbuffer->buffer_size = got;
 
5286                         normalize_buffer(STbuffer);
 
5289                 sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0);
 
5290                 got += STbuffer->sg[segs].length;
 
5291                 STbuffer->buffer_size = got;
 
5292                 STbuffer->sg_segs = ++segs;
 
5297                            "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
 
5298                            got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
 
5300                            "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
 
5301                            STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
 
5302                            STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
 
5310 /* Release the segments */
 
5311 static void normalize_buffer(struct osst_buffer *STbuffer)
 
5313   int i, order, b_size;
 
5315         for (i=0; i < STbuffer->sg_segs; i++) {
 
5317                 for (b_size = PAGE_SIZE, order = 0;
 
5318                      b_size < STbuffer->sg[i].length;
 
5319                      b_size *= 2, order++);
 
5321                 __free_pages(sg_page(&STbuffer->sg[i]), order);
 
5322                 STbuffer->buffer_size -= STbuffer->sg[i].length;
 
5325         if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
 
5326                 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
 
5327                              STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
 
5329         STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
 
5333 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
 
5334    negative error code. */
 
5335 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
 
5337         int i, cnt, res, offset;
 
5339         for (i=0, offset=st_bp->buffer_bytes;
 
5340              i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
 
5341         offset -= st_bp->sg[i].length;
 
5342         if (i == st_bp->sg_segs) {  /* Should never happen */
 
5343                 printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
 
5346         for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 
5347                 cnt = st_bp->sg[i].length - offset < do_count ?
 
5348                       st_bp->sg[i].length - offset : do_count;
 
5349                 res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
 
5353                 st_bp->buffer_bytes += cnt;
 
5357         if (do_count) {  /* Should never happen */
 
5358                 printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
 
5366 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
 
5367    negative error code. */
 
5368 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
 
5370         int i, cnt, res, offset;
 
5372         for (i=0, offset=st_bp->read_pointer;
 
5373              i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
 
5374                 offset -= st_bp->sg[i].length;
 
5375         if (i == st_bp->sg_segs) {  /* Should never happen */
 
5376                 printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
 
5379         for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 
5380                 cnt = st_bp->sg[i].length - offset < do_count ?
 
5381                       st_bp->sg[i].length - offset : do_count;
 
5382                 res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
 
5386                 st_bp->buffer_bytes -= cnt;
 
5387                 st_bp->read_pointer += cnt;
 
5391         if (do_count) {  /* Should never happen */
 
5392                 printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
 
5398 /* Sets the tail of the buffer after fill point to zero.
 
5399    Returns zero (success) or negative error code.        */
 
5400 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
 
5402         int     i, offset, do_count, cnt;
 
5404         for (i = 0, offset = st_bp->buffer_bytes;
 
5405              i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
 
5406                 offset -= st_bp->sg[i].length;
 
5407         if (i == st_bp->sg_segs) {  /* Should never happen */
 
5408                 printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
 
5411         for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
 
5412              i < st_bp->sg_segs && do_count > 0; i++) {
 
5413                 cnt = st_bp->sg[i].length - offset < do_count ?
 
5414                       st_bp->sg[i].length - offset : do_count ;
 
5415                 memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
 
5419         if (do_count) {  /* Should never happen */
 
5420                 printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
 
5426 /* Copy a osst 32K chunk of memory into the buffer.
 
5427    Returns zero (success) or negative error code.  */
 
5428 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 
5430         int     i, cnt, do_count = OS_DATA_SIZE;
 
5432         for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 
5433                 cnt = st_bp->sg[i].length < do_count ?
 
5434                       st_bp->sg[i].length : do_count ;
 
5435                 memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
 
5439         if (do_count || i != st_bp->sg_segs-1) {  /* Should never happen */
 
5440                 printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
 
5447 /* Copy a osst 32K chunk of memory from the buffer.
 
5448    Returns zero (success) or negative error code.  */
 
5449 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 
5451         int     i, cnt, do_count = OS_DATA_SIZE;
 
5453         for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 
5454                 cnt = st_bp->sg[i].length < do_count ?
 
5455                       st_bp->sg[i].length : do_count ;
 
5456                 memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
 
5460         if (do_count || i != st_bp->sg_segs-1) {  /* Should never happen */
 
5461                 printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
 
5469 /* Module housekeeping */
 
5471 static void validate_options (void)
 
5474                 osst_max_dev = max_dev;  
 
5475   if (write_threshold_kbs > 0)
 
5476                 osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
 
5477   if (osst_write_threshold > osst_buffer_size)
 
5478                 osst_write_threshold = osst_buffer_size;
 
5479   if (max_sg_segs >= OSST_FIRST_SG)
 
5480                 osst_max_sg_segs = max_sg_segs;
 
5482   printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
 
5483                            osst_max_dev, osst_write_threshold, osst_max_sg_segs);
 
5488 /* Set the boot options. Syntax: osst=xxx,yyy,...
 
5489    where xxx is write threshold in 1024 byte blocks,
 
5490    and   yyy is number of s/g segments to use. */
 
5491 static int __init osst_setup (char *str)
 
5496   stp = get_options(str, ARRAY_SIZE(ints), ints);
 
5499         for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
 
5500                   *parms[i].val = ints[i + 1];
 
5502         while (stp != NULL) {
 
5503                 for (i = 0; i < ARRAY_SIZE(parms); i++) {
 
5504                         int len = strlen(parms[i].name);
 
5505                         if (!strncmp(stp, parms[i].name, len) &&
 
5506                             (*(stp + len) == ':' || *(stp + len) == '=')) {
 
5508                                         simple_strtoul(stp + len + 1, NULL, 0);
 
5512                 if (i >= ARRAY_SIZE(parms))
 
5513                         printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
 
5515                 stp = strchr(stp, ',');
 
5524 __setup("osst=", osst_setup);
 
5528 static const struct file_operations osst_fops = {
 
5529         .owner =        THIS_MODULE,
 
5531         .write =        osst_write,
 
5532         .ioctl =        osst_ioctl,
 
5533 #ifdef CONFIG_COMPAT
 
5534         .compat_ioctl = osst_compat_ioctl,
 
5536         .open =         os_scsi_tape_open,
 
5537         .flush =        os_scsi_tape_flush,
 
5538         .release =      os_scsi_tape_close,
 
5541 static int osst_supports(struct scsi_device * SDp)
 
5543         struct  osst_support_data {
 
5547                 char *driver_hint; /* Name of the correct driver, NULL if unknown */
 
5550 static  struct  osst_support_data support_list[] = {
 
5551                 /* {"XXX", "Yy-", "", NULL},  example */
 
5555         struct  osst_support_data *rp;
 
5557         /* We are willing to drive OnStream SC-x0 as well as the
 
5558          *       * IDE, ParPort, FireWire, USB variants, if accessible by
 
5559          *               * emulation layer (ide-scsi, usb-storage, ...) */
 
5561         for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
 
5562                 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
 
5563                     !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
 
5564                     !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) 
 
5570  * sysfs support for osst driver parameter information
 
5573 static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
 
5575         return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
 
5578 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
 
5580 static int osst_create_sysfs_files(struct device_driver *sysfs)
 
5582         return driver_create_file(sysfs, &driver_attr_version);
 
5585 static void osst_remove_sysfs_files(struct device_driver *sysfs)
 
5587         driver_remove_file(sysfs, &driver_attr_version);
 
5591  * sysfs support for accessing ADR header information
 
5594 static ssize_t osst_adr_rev_show(struct device *dev,
 
5595                                  struct device_attribute *attr, char *buf)
 
5597         struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
 
5600         if (STp && STp->header_ok && STp->linux_media)
 
5601                 l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
 
5605 DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
 
5607 static ssize_t osst_linux_media_version_show(struct device *dev,
 
5608                                              struct device_attribute *attr,
 
5611         struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
 
5614         if (STp && STp->header_ok && STp->linux_media)
 
5615                 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
 
5619 DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
 
5621 static ssize_t osst_capacity_show(struct device *dev,
 
5622                                   struct device_attribute *attr, char *buf)
 
5624         struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
 
5627         if (STp && STp->header_ok && STp->linux_media)
 
5628                 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
 
5632 DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
 
5634 static ssize_t osst_first_data_ppos_show(struct device *dev,
 
5635                                          struct device_attribute *attr,
 
5638         struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
 
5641         if (STp && STp->header_ok && STp->linux_media)
 
5642                 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
 
5646 DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
 
5648 static ssize_t osst_eod_frame_ppos_show(struct device *dev,
 
5649                                         struct device_attribute *attr,
 
5652         struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
 
5655         if (STp && STp->header_ok && STp->linux_media)
 
5656                 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
 
5660 DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
 
5662 static ssize_t osst_filemark_cnt_show(struct device *dev,
 
5663                                       struct device_attribute *attr, char *buf)
 
5665         struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
 
5668         if (STp && STp->header_ok && STp->linux_media)
 
5669                 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
 
5673 DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
 
5675 static struct class *osst_sysfs_class;
 
5677 static int osst_sysfs_init(void)
 
5679         osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
 
5680         if (IS_ERR(osst_sysfs_class)) {
 
5681                 printk(KERN_ERR "osst :W: Unable to register sysfs class\n");
 
5682                 return PTR_ERR(osst_sysfs_class);
 
5688 static void osst_sysfs_destroy(dev_t dev)
 
5690         device_destroy(osst_sysfs_class, dev);
 
5693 static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
 
5695         struct device *osst_member;
 
5698         osst_member = device_create(osst_sysfs_class, device, dev, "%s", name);
 
5699         if (IS_ERR(osst_member)) {
 
5700                 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
 
5701                 return PTR_ERR(osst_member);
 
5704         dev_set_drvdata(osst_member, STp);
 
5705         err = device_create_file(osst_member, &dev_attr_ADR_rev);
 
5708         err = device_create_file(osst_member, &dev_attr_media_version);
 
5711         err = device_create_file(osst_member, &dev_attr_capacity);
 
5714         err = device_create_file(osst_member, &dev_attr_BOT_frame);
 
5717         err = device_create_file(osst_member, &dev_attr_EOD_frame);
 
5720         err = device_create_file(osst_member, &dev_attr_file_count);
 
5727         osst_sysfs_destroy(dev);
 
5731 static void osst_sysfs_cleanup(void)
 
5733         class_destroy(osst_sysfs_class);
 
5737  * osst startup / cleanup code
 
5740 static int osst_probe(struct device *dev)
 
5742         struct scsi_device * SDp = to_scsi_device(dev);
 
5743         struct osst_tape   * tpnt;
 
5744         struct st_modedef  * STm;
 
5745         struct st_partstat * STps;
 
5746         struct osst_buffer * buffer;
 
5747         struct gendisk     * drive;
 
5748         int                  i, dev_num, err = -ENODEV;
 
5750         if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
 
5753         drive = alloc_disk(1);
 
5755                 printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
 
5759         /* if this is the first attach, build the infrastructure */
 
5760         write_lock(&os_scsi_tapes_lock);
 
5761         if (os_scsi_tapes == NULL) {
 
5763                         (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *),
 
5765                 if (os_scsi_tapes == NULL) {
 
5766                         write_unlock(&os_scsi_tapes_lock);
 
5767                         printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
 
5770                 for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
 
5773         if (osst_nr_dev >= osst_max_dev) {
 
5774                 write_unlock(&os_scsi_tapes_lock);
 
5775                 printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
 
5779         /* find a free minor number */
 
5780         for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++);
 
5781         if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
 
5784         /* allocate a struct osst_tape for this device */
 
5785         tpnt = kzalloc(sizeof(struct osst_tape), GFP_ATOMIC);
 
5787                 write_unlock(&os_scsi_tapes_lock);
 
5788                 printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
 
5792         /* allocate a buffer for this device */
 
5793         i = SDp->host->sg_tablesize;
 
5794         if (osst_max_sg_segs < i)
 
5795                 i = osst_max_sg_segs;
 
5796         buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
 
5797         if (buffer == NULL) {
 
5798                 write_unlock(&os_scsi_tapes_lock);
 
5799                 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
 
5803         os_scsi_tapes[dev_num] = tpnt;
 
5804         tpnt->buffer = buffer;
 
5806         drive->private_data = &tpnt->driver;
 
5807         sprintf(drive->disk_name, "osst%d", dev_num);
 
5808         tpnt->driver = &osst_template;
 
5809         tpnt->drive = drive;
 
5811         tpnt->capacity = 0xfffff;
 
5813         tpnt->drv_buffer = 1;  /* Try buffering if no mode sense */
 
5814         tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
 
5816         tpnt->do_auto_lock = OSST_AUTO_LOCK;
 
5817         tpnt->can_bsr = OSST_IN_FILE_POS;
 
5818         tpnt->can_partitions = 0;
 
5819         tpnt->two_fm = OSST_TWO_FM;
 
5820         tpnt->fast_mteom = OSST_FAST_MTEOM;
 
5821         tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
 
5822         tpnt->write_threshold = osst_write_threshold;
 
5823         tpnt->default_drvbuffer = 0xff; /* No forced buffering */
 
5824         tpnt->partition = 0;
 
5825         tpnt->new_partition = 0;
 
5826         tpnt->nbr_partitions = 0;
 
5827         tpnt->min_block = 512;
 
5828         tpnt->max_block = OS_DATA_SIZE;
 
5829         tpnt->timeout = OSST_TIMEOUT;
 
5830         tpnt->long_timeout = OSST_LONG_TIMEOUT;
 
5832         /* Recognize OnStream tapes */
 
5833         /* We don't need to test for OnStream, as this has been done in detect () */
 
5834         tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
 
5835         tpnt->omit_blklims = 1;
 
5837         tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || 
 
5838                      (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
 
5839         tpnt->frame_in_buffer = 0;
 
5840         tpnt->header_ok = 0;
 
5841         tpnt->linux_media = 0;
 
5842         tpnt->header_cache = NULL;
 
5844         for (i=0; i < ST_NBR_MODES; i++) {
 
5845                 STm = &(tpnt->modes[i]);
 
5847                 STm->sysv = OSST_SYSV;
 
5848                 STm->defaults_for_writes = 0;
 
5849                 STm->do_async_writes = OSST_ASYNC_WRITES;
 
5850                 STm->do_buffer_writes = OSST_BUFFER_WRITES;
 
5851                 STm->do_read_ahead = OSST_READ_AHEAD;
 
5852                 STm->default_compression = ST_DONT_TOUCH;
 
5853                 STm->default_blksize = 512;
 
5854                 STm->default_density = (-1);  /* No forced density */
 
5857         for (i=0; i < ST_NBR_PARTITIONS; i++) {
 
5858                 STps = &(tpnt->ps[i]);
 
5860                 STps->eof = ST_NOEOF;
 
5862                 STps->last_block_valid = 0;
 
5863                 STps->drv_block = (-1);
 
5864                 STps->drv_file = (-1);
 
5867         tpnt->current_mode = 0;
 
5868         tpnt->modes[0].defined = 1;
 
5869         tpnt->modes[2].defined = 1;
 
5870         tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
 
5872         mutex_init(&tpnt->lock);
 
5874         write_unlock(&os_scsi_tapes_lock);
 
5880                 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
 
5882                         goto out_free_buffer;
 
5884                 /*  No-rewind entry  */
 
5885                 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
 
5886                 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
 
5888                         goto out_free_sysfs1;
 
5891         sdev_printk(KERN_INFO, SDp,
 
5892                 "osst :I: Attached OnStream %.5s tape as %s\n",
 
5893                 SDp->model, tape_name(tpnt));
 
5898         osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num));
 
5906 static int osst_remove(struct device *dev)
 
5908         struct scsi_device * SDp = to_scsi_device(dev);
 
5909         struct osst_tape * tpnt;
 
5912         if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
 
5915         write_lock(&os_scsi_tapes_lock);
 
5916         for(i=0; i < osst_max_dev; i++) {
 
5917                 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
 
5918                         osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
 
5919                         osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
 
5920                         tpnt->device = NULL;
 
5921                         put_disk(tpnt->drive);
 
5922                         os_scsi_tapes[i] = NULL;
 
5924                         write_unlock(&os_scsi_tapes_lock);
 
5925                         vfree(tpnt->header_cache);
 
5927                                 normalize_buffer(tpnt->buffer);
 
5928                                 kfree(tpnt->buffer);
 
5934         write_unlock(&os_scsi_tapes_lock);
 
5938 static int __init init_osst(void) 
 
5942         printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
 
5946         err = osst_sysfs_init();
 
5950         err = register_chrdev(OSST_MAJOR, "osst", &osst_fops);
 
5952                 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
 
5956         err = scsi_register_driver(&osst_template.gendrv);
 
5958                 goto err_out_chrdev;
 
5960         err = osst_create_sysfs_files(&osst_template.gendrv);
 
5962                 goto err_out_scsidrv;
 
5967         scsi_unregister_driver(&osst_template.gendrv);
 
5969         unregister_chrdev(OSST_MAJOR, "osst");
 
5971         osst_sysfs_cleanup();
 
5975 static void __exit exit_osst (void)
 
5978         struct osst_tape * STp;
 
5980         osst_remove_sysfs_files(&osst_template.gendrv);
 
5981         scsi_unregister_driver(&osst_template.gendrv);
 
5982         unregister_chrdev(OSST_MAJOR, "osst");
 
5983         osst_sysfs_cleanup();
 
5985         if (os_scsi_tapes) {
 
5986                 for (i=0; i < osst_max_dev; ++i) {
 
5987                         if (!(STp = os_scsi_tapes[i])) continue;
 
5988                         /* This is defensive, supposed to happen during detach */
 
5989                         vfree(STp->header_cache);
 
5991                                 normalize_buffer(STp->buffer);
 
5994                         put_disk(STp->drive);
 
5997                 kfree(os_scsi_tapes);
 
5999         printk(KERN_INFO "osst :I: Unloaded.\n");
 
6002 module_init(init_osst);
 
6003 module_exit(exit_osst);