root/drivers/scsi/st.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. st_chk_result
  2. st_sleep_done
  3. write_behind_check
  4. back_over_eof
  5. flush_write_buffer
  6. flush_buffer
  7. scsi_tape_open
  8. scsi_tape_close
  9. st_write
  10. st_read
  11. st_set_options
  12. st_int_ioctl
  13. st_ioctl
  14. st_setup
  15. st_attach
  16. st_init1
  17. st_init

   1 /*
   2   SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
   3   file README.st for more information.
   4 
   5   History:
   6   Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
   7   Contribution and ideas from several people including (in alphabetical
   8   order) Klaus Ehrenfried, Wolfgang Denk, J"org Weule, and
   9   Eric Youngdale.
  10 
  11   Copyright 1992, 1993, 1994 Kai Makisara
  12                  email makisara@vtinsx.ins.vtt.fi or Kai.Makisara@vtt.fi
  13 
  14   Last modified: Wed May  4 20:29:42 1994 by root@kai.home
  15 */
  16 
  17 #include <linux/fs.h>
  18 #include <linux/kernel.h>
  19 #include <linux/sched.h>
  20 #include <linux/string.h>
  21 #include <linux/errno.h>
  22 #include <linux/mtio.h>
  23 #include <linux/ioctl.h>
  24 #include <linux/fcntl.h>
  25 #include <asm/segment.h>
  26 #include <asm/system.h>
  27 
  28 #define MAJOR_NR SCSI_TAPE_MAJOR
  29 #include "../block/blk.h"
  30 #include "scsi.h"
  31 #include "scsi_ioctl.h"
  32 #include "st.h"
  33 #include "constants.h"
  34 
  35 /* #define DEBUG */
  36 
  37 /* #define ST_NOWAIT */
  38 
  39 /* #define ST_IN_FILE_POS */
  40 
  41 /* #define ST_RECOVERED_WRITE_FATAL */
  42 
  43 #define ST_BUFFER_WRITES 1
  44 
  45 #define ST_ASYNC_WRITES 1
  46 
  47 #define ST_READ_AHEAD 1
  48 
  49 #define ST_BLOCK_SIZE 1024
  50 
  51 #define ST_MAX_BUFFERS 2
  52 
  53 #define ST_BUFFER_BLOCKS 32
  54 
  55 #define ST_WRITE_THRESHOLD_BLOCKS 30
  56 
  57 #define ST_BUFFER_SIZE (ST_BUFFER_BLOCKS * ST_BLOCK_SIZE)
  58 #define ST_WRITE_THRESHOLD (ST_WRITE_THRESHOLD_BLOCKS * ST_BLOCK_SIZE)
  59 
  60 /* The buffer size should fit into the 24 bits for length in the
  61    6-byte SCSI read and write commands. */
  62 #if ST_BUFFER_SIZE >= (2 << 24 - 1)
  63 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
  64 #endif
  65 
  66 #ifdef DEBUG
  67 static int debugging = 1;
  68 #endif
  69 
  70 #define MAX_RETRIES 0
  71 #define MAX_READY_RETRIES 5
  72 #define NO_TAPE  NOT_READY
  73 
  74 #define ST_TIMEOUT 9000
  75 #define ST_LONG_TIMEOUT 200000
  76 
  77 static int st_nbr_buffers;
  78 static ST_buffer **st_buffers;
  79 static int st_buffer_size = ST_BUFFER_SIZE;
  80 static int st_write_threshold = ST_WRITE_THRESHOLD;
  81 static int st_max_buffers = ST_MAX_BUFFERS;
  82 
  83 static Scsi_Tape * scsi_tapes;
  84 int NR_ST=0;
  85 int MAX_ST=0;
  86 
  87 static int st_int_ioctl(struct inode * inode,struct file * file,
  88              unsigned int cmd_in, unsigned long arg);
  89 
  90 
  91 
  92 
  93 /* Convert the result to success code */
  94         static int
  95 st_chk_result(Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97   int dev = SCpnt->request.dev;
  98   int result = SCpnt->result;
  99   unsigned char * sense = SCpnt->sense_buffer;
 100   char *stp;
 101 
 102   if (!result && SCpnt->sense_buffer[0] == 0)
 103     return 0;
 104 #ifdef DEBUG
 105   if (debugging) {
 106     printk("st%d: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n", dev, result,
 107            SCpnt->cmnd[0], SCpnt->cmnd[1], SCpnt->cmnd[2],
 108            SCpnt->cmnd[3], SCpnt->cmnd[4], SCpnt->cmnd[5],
 109            SCpnt->request_bufflen);
 110     if (driver_byte(result) & DRIVER_SENSE)
 111       print_sense("st", SCpnt);
 112   }
 113 #endif
 114 /*  if ((sense[0] & 0x70) == 0x70 &&
 115        ((sense[2] & 0x80) ))
 116     return 0; */
 117   if ((sense[0] & 0x70) == 0x70 &&
 118       sense[2] == RECOVERED_ERROR
 119 #ifdef ST_RECOVERED_WRITE_FATAL
 120       && SCpnt->cmnd[0] != WRITE_6
 121       && SCpnt->cmnd[0] != WRITE_FILEMARKS
 122 #endif
 123       ) {
 124     scsi_tapes[dev].recover_count++;
 125     scsi_tapes[dev].mt_status->mt_erreg += (1 << MT_ST_SOFTERR_SHIFT);
 126     if (SCpnt->cmnd[0] == READ_6)
 127       stp = "read";
 128     else if (SCpnt->cmnd[0] == WRITE_6)
 129       stp = "write";
 130     else
 131       stp = "ioctl";
 132     printk("st%d: Recovered %s error (%d).\n", dev, stp,
 133            scsi_tapes[dev].recover_count);
 134     return 0;
 135   }
 136   return (-EIO);
 137 }
 138 
 139 
 140 /* Wakeup from interrupt */
 141         static void
 142 st_sleep_done (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144   int st_nbr, remainder;
 145   Scsi_Tape * STp;
 146 
 147   if ((st_nbr = SCpnt->request.dev) < NR_ST && st_nbr >= 0) {
 148     STp = &(scsi_tapes[st_nbr]);
 149     if ((STp->buffer)->writing &&
 150         (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 151         (SCpnt->sense_buffer[2] & 0x40)) {
 152       /* EOM at write-behind, has all been written? */
 153       if ((SCpnt->sense_buffer[0] & 0x80) != 0)
 154         remainder = (SCpnt->sense_buffer[3] << 24) |
 155               (SCpnt->sense_buffer[4] << 16) |
 156                 (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];
 157       else
 158         remainder = 0;
 159       if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW ||
 160           remainder > 0)
 161         (STp->buffer)->last_result = SCpnt->result; /* Error */
 162       else
 163         (STp->buffer)->last_result = INT_MAX; /* OK */
 164     }
 165     else
 166       (STp->buffer)->last_result = SCpnt->result;
 167     (STp->buffer)->last_result_fatal = st_chk_result(SCpnt);
 168     if ((STp->buffer)->writing)
 169       SCpnt->request.dev = -1;
 170     else
 171       SCpnt->request.dev = 0xffff;
 172     if ((STp->buffer)->writing <= 0)
 173       wake_up( &(STp->waiting) );
 174   }
 175 #ifdef DEBUG
 176   else if (debugging)
 177     printk("st?: Illegal interrupt device %x\n", st_nbr);
 178 #endif
 179 }
 180 
 181 
 182 /* Handle the write-behind checking */
 183         static void
 184 write_behind_check(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 185 {
 186   Scsi_Tape * STp;
 187   ST_buffer * STbuffer;
 188 
 189   STp = &(scsi_tapes[dev]);
 190   STbuffer = STp->buffer;
 191 
 192   cli();
 193   if (STbuffer->last_result < 0) {
 194     STbuffer->writing = (- STbuffer->writing);
 195     sleep_on( &(STp->waiting) );
 196     STbuffer->writing = (- STbuffer->writing);
 197   }
 198   sti();
 199 
 200   if (STbuffer->writing < STbuffer->buffer_bytes)
 201     memcpy(STbuffer->b_data,
 202            STbuffer->b_data + STbuffer->writing,
 203            STbuffer->buffer_bytes - STbuffer->writing);
 204   STbuffer->buffer_bytes -= STbuffer->writing;
 205   if (STp->drv_block >= 0) {
 206     if (STp->block_size == 0)
 207       STp->drv_block++;
 208     else
 209       STp->drv_block += STbuffer->writing / STp->block_size;
 210   }
 211   STbuffer->writing = 0;
 212 
 213   return;
 214 }
 215 
 216 
 217 /* Back over EOF if it has been inadvertently crossed (ioctl not used because
 218    it messes up the block number). */
 219         static int
 220 back_over_eof(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 221 {
 222   Scsi_Cmnd *SCpnt;
 223   Scsi_Tape *STp = &(scsi_tapes[dev]);
 224   unsigned char cmd[10];
 225 
 226   cmd[0] = SPACE;
 227   cmd[1] = 0x01; /* Space FileMarks */
 228   cmd[2] = cmd[3] = cmd[4] = 0xff;  /* -1 filemarks */
 229   cmd[5] = 0;
 230 
 231   SCpnt = allocate_device(NULL, (STp->device)->index, 1);
 232   SCpnt->sense_buffer[0] = 0;
 233   SCpnt->request.dev = dev;
 234   scsi_do_cmd(SCpnt,
 235               (void *) cmd, (void *) (STp->buffer)->b_data, 0,
 236               st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 237 
 238   if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 239   SCpnt->request.dev = -1;
 240 
 241   return (STp->buffer)->last_result_fatal;
 242 }
 243 
 244 
 245 /* Flush the write buffer (never need to write if variable blocksize). */
 246         static int
 247 flush_write_buffer(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 248 {
 249   int offset, transfer, blks;
 250   int result;
 251   unsigned char cmd[10];
 252   Scsi_Cmnd *SCpnt;
 253   Scsi_Tape *STp = &(scsi_tapes[dev]);
 254 
 255   if ((STp->buffer)->writing) {
 256     write_behind_check(dev);
 257     if ((STp->buffer)->last_result_fatal) {
 258 #ifdef DEBUG
 259       if (debugging)
 260         printk("st%d: Async write error (flush) %x.\n", dev,
 261                (STp->buffer)->last_result);
 262 #endif
 263       if ((STp->buffer)->last_result == INT_MAX)
 264         return (-ENOSPC);
 265       return (-EIO);
 266     }
 267   }
 268 
 269   result = 0;
 270   if (STp->dirty == 1) {
 271     SCpnt = allocate_device(NULL, (STp->device)->index, 1);
 272 
 273     offset = (STp->buffer)->buffer_bytes;
 274     transfer = ((offset + STp->block_size - 1) /
 275                 STp->block_size) * STp->block_size;
 276 #ifdef DEBUG
 277     if (debugging)
 278       printk("st%d: Flushing %d bytes.\n", dev, transfer);
 279 #endif
 280     memset((STp->buffer)->b_data + offset, 0, transfer - offset);
 281 
 282     SCpnt->sense_buffer[0] = 0;
 283     memset(cmd, 0, 10);
 284     cmd[0] = WRITE_6;
 285     cmd[1] = 1;
 286     blks = transfer / STp->block_size;
 287     cmd[2] = blks >> 16;
 288     cmd[3] = blks >> 8;
 289     cmd[4] = blks;
 290     SCpnt->request.dev = dev;
 291     scsi_do_cmd (SCpnt,
 292                  (void *) cmd, (STp->buffer)->b_data, transfer,
 293                  st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 294 
 295     if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 296 
 297     if ((STp->buffer)->last_result_fatal != 0) {
 298       printk("st%d: Error on flush.\n", dev);
 299       if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 300           (SCpnt->sense_buffer[2] & 0x40) &&
 301           (SCpnt->sense_buffer[2] & 0x0f) != VOLUME_OVERFLOW) {
 302         STp->dirty = 0;
 303         (STp->buffer)->buffer_bytes = 0;
 304         result = (-ENOSPC);
 305       }
 306       else
 307         result = (-EIO);
 308       STp->drv_block = (-1);
 309     }
 310     else {
 311       if (STp->drv_block >= 0)
 312         STp->drv_block += blks;
 313       STp->dirty = 0;
 314       (STp->buffer)->buffer_bytes = 0;
 315     }
 316     SCpnt->request.dev = -1;  /* Mark as not busy */
 317   }
 318   return result;
 319 }
 320 
 321 
 322 /* Flush the tape buffer. The tape will be positioned correctly unless
 323    seek_next is true. */
 324         static int
 325 flush_buffer(struct inode * inode, struct file * filp, int seek_next)
     /* [previous][next][first][last][top][bottom][index][help] */
 326 {
 327   int dev;
 328   int backspace, result;
 329   Scsi_Tape * STp;
 330   ST_buffer * STbuffer;
 331 
 332   dev = MINOR(inode->i_rdev) & 127;
 333   STp = &(scsi_tapes[dev]);
 334   STbuffer = STp->buffer;
 335 
 336   if (STp->rw == ST_WRITING)  /* Writing */
 337     return flush_write_buffer(dev);
 338 
 339   if (STp->block_size == 0)
 340     return 0;
 341 
 342   backspace = ((STp->buffer)->buffer_bytes +
 343     (STp->buffer)->read_pointer) / STp->block_size -
 344       ((STp->buffer)->read_pointer + STp->block_size - 1) /
 345         STp->block_size;
 346   (STp->buffer)->buffer_bytes = 0;
 347   (STp->buffer)->read_pointer = 0;
 348   result = 0;
 349   if (!seek_next) {
 350     if ((STp->eof == ST_FM) && !STp->eof_hit) {
 351       result = back_over_eof(dev); /* Back over the EOF hit */
 352       if (!result) {
 353         STp->eof = ST_NOEOF;
 354         STp->eof_hit = 0;
 355       }
 356     }
 357     if (!result && backspace > 0)
 358       result = st_int_ioctl(inode, filp, MTBSR, backspace);
 359   }
 360   return result;
 361 
 362 }
 363 
 364 
 365 /* Open the device */
 366         static int
 367 scsi_tape_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 368 {
 369     int dev;
 370     unsigned short flags;
 371     int i;
 372     unsigned char cmd[10];
 373     Scsi_Cmnd * SCpnt;
 374     Scsi_Tape * STp;
 375 
 376     dev = MINOR(inode->i_rdev) & 127;
 377     if (dev >= NR_ST)
 378       return (-ENXIO);
 379     STp = &(scsi_tapes[dev]);
 380     if (STp->in_use) {
 381       printk("st%d: Device already in use.\n", dev);
 382       return (-EBUSY);
 383     }
 384 
 385     /* Allocate buffer for this user */
 386     for (i=0; i < st_nbr_buffers; i++)
 387       if (!st_buffers[i]->in_use)
 388         break;
 389     if (i >= st_nbr_buffers) {
 390       printk("st%d: No free buffers.\n", dev);
 391       return (-EBUSY);
 392     }
 393     STp->buffer = st_buffers[i];
 394     (STp->buffer)->in_use = 1;
 395     (STp->buffer)->writing = 0;
 396     STp->in_use = 1;
 397 
 398     flags = filp->f_flags;
 399     STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
 400 
 401     STp->dirty = 0;
 402     STp->rw = ST_IDLE;
 403     STp->eof = ST_NOEOF;
 404     STp->eof_hit = 0;
 405     STp->recover_count = 0;
 406 
 407     SCpnt = allocate_device(NULL, (STp->device)->index, 1);
 408     if (!SCpnt) {
 409       printk("st%d: Tape request not allocated", dev);
 410       return (-EBUSY);
 411     }
 412 
 413     SCpnt->sense_buffer[0]=0;
 414     memset ((void *) &cmd[0], 0, 10);
 415     cmd[0] = TEST_UNIT_READY;
 416     SCpnt->request.dev = dev;
 417     scsi_do_cmd(SCpnt,
 418                 (void *) cmd, (void *) (STp->buffer)->b_data,
 419                 0, st_sleep_done, ST_LONG_TIMEOUT,
 420                 MAX_READY_RETRIES);
 421 
 422     if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 423 
 424     if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 425         (SCpnt->sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
 426       (STp->mt_status)->mt_fileno = 0 ;
 427       SCpnt->sense_buffer[0]=0;
 428       memset ((void *) &cmd[0], 0, 10);
 429       cmd[0] = TEST_UNIT_READY;
 430       SCpnt->request.dev = dev;
 431       scsi_do_cmd(SCpnt,
 432                   (void *) cmd, (void *) (STp->buffer)->b_data,
 433                   0, st_sleep_done, ST_LONG_TIMEOUT,
 434                   MAX_READY_RETRIES);
 435 
 436       if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 437       (STp->mt_status)->mt_fileno = STp->drv_block = 0;
 438     }
 439 
 440     if ((STp->buffer)->last_result_fatal != 0) {
 441       if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 442           (SCpnt->sense_buffer[2] & 0x0f) == NO_TAPE) {
 443         (STp->mt_status)->mt_fileno = STp->drv_block = 0 ;
 444         printk("st%d: No tape.\n", dev);
 445       } else {
 446         printk("st%d: Error %x.\n", dev, SCpnt->result);
 447         (STp->mt_status)->mt_fileno = STp->drv_block = (-1);
 448       }
 449       (STp->buffer)->in_use = 0;
 450       STp->in_use = 0;
 451       SCpnt->request.dev = -1;  /* Mark as not busy */
 452       return (-EIO);
 453     }
 454 
 455     SCpnt->sense_buffer[0]=0;
 456     memset ((void *) &cmd[0], 0, 10);
 457     cmd[0] = READ_BLOCK_LIMITS;
 458     SCpnt->request.dev = dev;
 459     scsi_do_cmd(SCpnt,
 460                 (void *) cmd, (void *) (STp->buffer)->b_data,
 461                 6, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
 462 
 463     if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 464 
 465     if (!SCpnt->result && !SCpnt->sense_buffer[0]) {
 466       STp->max_block = ((STp->buffer)->b_data[1] << 16) |
 467         ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
 468       STp->min_block = ((STp->buffer)->b_data[4] << 8) |
 469         (STp->buffer)->b_data[5];
 470 #ifdef DEBUG
 471       if (debugging)
 472         printk("st%d: Block limits %d - %d bytes.\n", dev, STp->min_block,
 473                STp->max_block);
 474 #endif
 475     }
 476     else {
 477       STp->min_block = STp->max_block = (-1);
 478 #ifdef DEBUG
 479       if (debugging)
 480         printk("st%d: Can't read block limits.\n", dev);
 481 #endif
 482     }
 483 
 484     SCpnt->sense_buffer[0]=0;
 485     memset ((void *) &cmd[0], 0, 10);
 486     cmd[0] = MODE_SENSE;
 487     cmd[4] = 12;
 488     SCpnt->request.dev = dev;
 489     scsi_do_cmd(SCpnt,
 490                 (void *) cmd, (void *) (STp->buffer)->b_data,
 491                 12, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
 492 
 493     if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 494 
 495     if ((STp->buffer)->last_result_fatal != 0) {
 496 #ifdef DEBUG
 497       if (debugging)
 498         printk("st%d: No Mode Sense.\n", dev);
 499 #endif
 500       (STp->buffer)->b_data[2] =
 501       (STp->buffer)->b_data[3] = 0;
 502     }
 503     SCpnt->request.dev = -1;  /* Mark as not busy */
 504 
 505 #ifdef DEBUG
 506     if (debugging)
 507       printk("st%d: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n", dev,
 508              (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
 509              (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]);
 510 #endif
 511 
 512     if ((STp->buffer)->b_data[3] >= 8) {
 513       STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
 514       STp->density = (STp->buffer)->b_data[4];
 515       STp->block_size = (STp->buffer)->b_data[9] * 65536 +
 516         (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
 517 #ifdef DEBUG
 518       if (debugging)
 519         printk("st%d: Density %x, tape length: %x, blocksize: %d, drv buffer: %d\n",
 520                dev, STp->density, (STp->buffer)->b_data[5] * 65536 +
 521                (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
 522                STp->block_size, STp->drv_buffer);
 523 #endif
 524       if (STp->block_size > st_buffer_size) {
 525         printk("st%d: Blocksize %d too large for buffer.\n", dev,
 526                STp->block_size);
 527         (STp->buffer)->in_use = 0;
 528         STp->in_use = 0;
 529         return (-EIO);
 530       }
 531 
 532     }
 533     else
 534       STp->block_size = 512;  /* "Educated Guess" (?) */
 535 
 536     if (STp->block_size > 0) {
 537       (STp->buffer)->buffer_blocks = st_buffer_size / STp->block_size;
 538       (STp->buffer)->buffer_size =
 539         (STp->buffer)->buffer_blocks * STp->block_size;
 540     }
 541     else {
 542       (STp->buffer)->buffer_blocks = 1;
 543       (STp->buffer)->buffer_size = st_buffer_size;
 544     }
 545     (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
 546 
 547 #ifdef DEBUG
 548     if (debugging)
 549       printk("st%d: Block size: %d, buffer size: %d (%d blocks).\n", dev,
 550              STp->block_size, (STp->buffer)->buffer_size,
 551              (STp->buffer)->buffer_blocks);
 552 #endif
 553 
 554     if ((STp->buffer)->b_data[2] & 0x80) {
 555       STp->write_prot = 1;
 556 #ifdef DEBUG
 557       if (debugging)
 558         printk( "st%d: Write protected\n", dev);
 559 #endif
 560     }
 561 
 562     return 0;
 563 }
 564 
 565 
 566 /* Close the device*/
 567         static void
 568 scsi_tape_close(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 569 {
 570     int dev;
 571     int result;
 572     int rewind;
 573     static unsigned char cmd[10];
 574     Scsi_Cmnd * SCpnt;
 575     Scsi_Tape * STp;
 576    
 577     dev = MINOR(inode->i_rdev);
 578     rewind = (dev & 0x80) == 0;
 579     dev = dev & 127;
 580     STp = &(scsi_tapes[dev]);
 581 
 582     if ( STp->rw == ST_WRITING) {
 583 
 584       result = flush_write_buffer(dev);
 585 
 586 #ifdef DEBUG
 587       if (debugging)
 588         printk("st%d: File length %ld bytes.\n", dev, filp->f_pos);
 589 #endif
 590 
 591       if (result == 0 || result == (-ENOSPC)) {
 592         SCpnt = allocate_device(NULL, (STp->device)->index, 1);
 593 
 594         SCpnt->sense_buffer[0] = 0;
 595         memset(cmd, 0, 10);
 596         cmd[0] = WRITE_FILEMARKS;
 597         cmd[4] = 1;
 598         SCpnt->request.dev = dev;
 599         scsi_do_cmd( SCpnt,
 600                     (void *) cmd, (void *) (STp->buffer)->b_data,
 601                     0, st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 602 
 603         if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 604 
 605         if ((STp->buffer)->last_result_fatal != 0)
 606           printk("st%d: Error on write filemark.\n", dev);
 607         else {
 608           (STp->mt_status)->mt_fileno++ ;
 609           STp->drv_block = 0;
 610         }
 611 
 612         SCpnt->request.dev = -1;  /* Mark as not busy */
 613       }
 614 
 615 #ifdef DEBUG
 616       if (debugging)
 617         printk("st%d: Buffer flushed, EOF written\n", dev);
 618 #endif
 619     }
 620     else if (!rewind) {
 621 #ifndef ST_IN_FILE_POS
 622       if ((STp->eof == ST_FM) && !STp->eof_hit)
 623         back_over_eof(dev);
 624 #else
 625       flush_buffer(inode, filp, 0);
 626 #endif
 627     }
 628 
 629     if (rewind)
 630       st_int_ioctl(inode, filp, MTREW, 1);
 631 
 632     (STp->buffer)->in_use = 0;
 633     STp->in_use = 0;
 634 
 635     return;
 636 }
 637 
 638 
 639 /* Write command */
 640         static int
 641 st_write(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 642 {
 643     int dev;
 644     int total, do_count, blks, retval, transfer;
 645     int write_threshold;
 646     static unsigned char cmd[10];
 647     char *b_point;
 648     Scsi_Cmnd * SCpnt;
 649     Scsi_Tape * STp;
 650 
 651     dev = MINOR(inode->i_rdev) & 127;
 652     STp = &(scsi_tapes[dev]);
 653 #ifdef DEBUG
 654     if (!STp->in_use) {
 655       printk("st%d: Incorrect device.\n", dev);
 656       return (-EIO);
 657     }
 658 #endif
 659 
 660     if (STp->write_prot)
 661       return (-EACCES);
 662 
 663     if (STp->block_size == 0 && count > st_buffer_size)
 664       return (-EOVERFLOW);
 665 
 666     if (STp->rw == ST_READING) {
 667       retval = flush_buffer(inode, filp, 0);
 668       if (retval)
 669         return retval;
 670       STp->rw = ST_WRITING;
 671     }
 672 
 673     if ((STp->buffer)->writing) {
 674       write_behind_check(dev);
 675       if ((STp->buffer)->last_result_fatal) {
 676 #ifdef DEBUG
 677         if (debugging)
 678           printk("st%d: Async write error (write) %x.\n", dev,
 679                  (STp->buffer)->last_result);
 680 #endif
 681         if ((STp->buffer)->last_result == INT_MAX) {
 682           retval = (-ENOSPC);  /* All has been written */
 683           STp->eof = ST_EOM_OK;
 684         }
 685         else
 686           retval = (-EIO);
 687         return retval;
 688       }
 689     }
 690 
 691     if (STp->eof == ST_EOM_OK)
 692       return (-ENOSPC);
 693     else if (STp->eof == ST_EOM_ERROR)
 694       return (-EIO);
 695 
 696     if (!STp->do_buffer_writes) {
 697       if (STp->block_size != 0 && (count % STp->block_size) != 0)
 698         return (-EIO);   /* Write must be integral number of blocks */
 699       write_threshold = 1;
 700     }
 701     else
 702       write_threshold = (STp->buffer)->buffer_size;
 703     if (!STp->do_async_writes)
 704       write_threshold--;
 705 
 706     SCpnt = allocate_device(NULL, (STp->device)->index, 1);
 707 
 708     total = count;
 709 
 710     memset(cmd, 0, 10);
 711     cmd[0] = WRITE_6;
 712     cmd[1] = (STp->block_size != 0);
 713 
 714     STp->rw = ST_WRITING;
 715 
 716     b_point = buf;
 717     while((STp->block_size == 0 && !STp->do_async_writes && count > 0) ||
 718           (STp->block_size != 0 &&
 719            (STp->buffer)->buffer_bytes + count > write_threshold))
 720     {
 721       if (STp->block_size == 0)
 722         do_count = count;
 723       else {
 724         do_count = (STp->buffer)->buffer_size - (STp->buffer)->buffer_bytes;
 725         if (do_count > count)
 726           do_count = count;
 727       }
 728       memcpy_fromfs((STp->buffer)->b_data +
 729                     (STp->buffer)->buffer_bytes, b_point, do_count);
 730 
 731       if (STp->block_size == 0)
 732         blks = transfer = do_count;
 733       else {
 734         blks = ((STp->buffer)->buffer_bytes + do_count) /
 735           STp->block_size;
 736         transfer = blks * STp->block_size;
 737       }
 738       cmd[2] = blks >> 16;
 739       cmd[3] = blks >> 8;
 740       cmd[4] = blks;
 741       SCpnt->sense_buffer[0] = 0;
 742       SCpnt->request.dev = dev;
 743       scsi_do_cmd (SCpnt,
 744                    (void *) cmd, (STp->buffer)->b_data, transfer,
 745                    st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 746 
 747       if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 748 
 749       if ((STp->buffer)->last_result_fatal != 0) {
 750 #ifdef DEBUG
 751         if (debugging)
 752           printk("st%d: Error on write:\n", dev);
 753 #endif
 754         if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 755             (SCpnt->sense_buffer[2] & 0x40)) {
 756           if (STp->block_size != 0 && (SCpnt->sense_buffer[0] & 0x80) != 0)
 757             transfer = (SCpnt->sense_buffer[3] << 24) |
 758               (SCpnt->sense_buffer[4] << 16) |
 759                 (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];
 760           else if (STp->block_size == 0 &&
 761                    (SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
 762             transfer = do_count;
 763           else
 764             transfer = 0;
 765           if (STp->block_size != 0)
 766             transfer *= STp->block_size;
 767           if (transfer <= do_count) {
 768             filp->f_pos += do_count - transfer;
 769             count -= do_count - transfer;
 770             if (STp->drv_block >= 0) {
 771               if (STp->block_size == 0 && transfer < do_count)
 772                 STp->drv_block++;
 773               else if (STp->block_size != 0)
 774                 STp->drv_block += (do_count - transfer) / STp->block_size;
 775             }
 776             STp->eof = ST_EOM_OK;
 777             retval = (-ENOSPC); /* EOM within current request */
 778 #ifdef DEBUG
 779             if (debugging)
 780               printk("st%d: EOM with %d bytes unwritten.\n",
 781                      dev, transfer);
 782 #endif
 783           }
 784           else {
 785             STp->eof = ST_EOM_ERROR;
 786             STp->drv_block = (-1);    /* Too cautious? */
 787             retval = (-EIO); /* EOM for old data */
 788 #ifdef DEBUG
 789             if (debugging)
 790               printk("st%d: EOM with lost data.\n", dev);
 791 #endif
 792           }
 793         }
 794         else {
 795           STp->drv_block = (-1);    /* Too cautious? */
 796           retval = (-EIO);
 797         }
 798 
 799         SCpnt->request.dev = -1;  /* Mark as not busy */
 800         (STp->buffer)->buffer_bytes = 0;
 801         STp->dirty = 0;
 802         if (count < total)
 803           return total - count;
 804         else
 805           return retval;
 806       }
 807       filp->f_pos += do_count;
 808       b_point += do_count;
 809       count -= do_count;
 810       if (STp->drv_block >= 0) {
 811         if (STp->block_size == 0)
 812           STp->drv_block++;
 813         else
 814           STp->drv_block += blks;
 815       }
 816       (STp->buffer)->buffer_bytes = 0;
 817       STp->dirty = 0;
 818     }
 819     if (count != 0) {
 820       STp->dirty = 1;
 821       memcpy_fromfs((STp->buffer)->b_data +
 822                     (STp->buffer)->buffer_bytes,b_point,count);
 823       filp->f_pos += count;
 824       (STp->buffer)->buffer_bytes += count;
 825       count = 0;
 826     }
 827 
 828     if ((STp->buffer)->last_result_fatal != 0) {
 829       SCpnt->request.dev = -1;
 830       return (STp->buffer)->last_result_fatal;
 831     }
 832 
 833     if (STp->do_async_writes &&
 834         ((STp->buffer)->buffer_bytes >= STp->write_threshold ||
 835          STp->block_size == 0) ) {
 836       /* Schedule an asynchronous write */
 837       if (STp->block_size == 0)
 838         (STp->buffer)->writing = (STp->buffer)->buffer_bytes;
 839       else
 840         (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
 841           STp->block_size) * STp->block_size;
 842       STp->dirty = 0;
 843 
 844       if (STp->block_size == 0)
 845         blks = (STp->buffer)->writing;
 846       else
 847         blks = (STp->buffer)->writing / STp->block_size;
 848       cmd[2] = blks >> 16;
 849       cmd[3] = blks >> 8;
 850       cmd[4] = blks;
 851       SCpnt->result = (STp->buffer)->last_result = -1;
 852       SCpnt->sense_buffer[0] = 0;
 853       SCpnt->request.dev = dev;
 854       scsi_do_cmd (SCpnt,
 855                    (void *) cmd, (STp->buffer)->b_data,
 856                    (STp->buffer)->writing,
 857                    st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 858     }
 859     else
 860       SCpnt->request.dev = -1;  /* Mark as not busy */
 861 
 862     return( total);
 863 }   
 864 
 865 
 866 /* Read command */
 867         static int
 868 st_read(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 869 {
 870     int dev;
 871     int total;
 872     int transfer, blks, bytes;
 873     static unsigned char cmd[10];
 874     Scsi_Cmnd * SCpnt;
 875     Scsi_Tape * STp;
 876 
 877     dev = MINOR(inode->i_rdev) & 127;
 878     STp = &(scsi_tapes[dev]);
 879 #ifdef DEBUG
 880     if (!STp->in_use) {
 881       printk("st%d: Incorrect device.\n", dev);
 882       return (-EIO);
 883     }
 884 #endif
 885 
 886     if (STp->block_size == 0 && count > st_buffer_size)
 887       return (-EOVERFLOW);
 888 
 889     if (!(STp->do_read_ahead) && STp->block_size != 0 &&
 890         (count % STp->block_size) != 0)
 891       return (-EIO);    /* Read must be integral number of blocks */
 892 
 893     if (STp->rw == ST_WRITING) {
 894       transfer = flush_buffer(inode, filp, 0);
 895       if (transfer)
 896         return transfer;
 897       STp->rw = ST_READING;
 898     }
 899 
 900 #ifdef DEBUG
 901     if (debugging && STp->eof != ST_NOEOF)
 902       printk("st%d: EOF flag up. Bytes %d\n", dev,
 903              (STp->buffer)->buffer_bytes);
 904 #endif
 905     if (((STp->buffer)->buffer_bytes == 0) &&
 906         STp->eof == ST_EOM_OK)  /* EOM or Blank Check */
 907       return (-EIO);
 908 
 909     STp->rw = ST_READING;
 910 
 911     SCpnt = allocate_device(NULL, (STp->device)->index, 1);
 912 
 913     for (total = 0; total < count; ) {
 914 
 915       if ((STp->buffer)->buffer_bytes == 0 &&
 916           STp->eof == ST_NOEOF) {
 917 
 918         memset(cmd, 0, 10);
 919         cmd[0] = READ_6;
 920         cmd[1] = (STp->block_size != 0);
 921         if (STp->block_size == 0)
 922           blks = bytes = count;
 923         else {
 924           if (STp->do_read_ahead) {
 925             blks = (STp->buffer)->buffer_blocks;
 926             bytes = blks * STp->block_size;
 927           }
 928           else {
 929             bytes = count;
 930             if (bytes > st_buffer_size)
 931               bytes = st_buffer_size;
 932             blks = bytes / STp->block_size;
 933             bytes = blks * STp->block_size;
 934           }
 935         }
 936         cmd[2] = blks >> 16;
 937         cmd[3] = blks >> 8;
 938         cmd[4] = blks;
 939 
 940         SCpnt->sense_buffer[0] = 0;
 941         SCpnt->request.dev = dev;
 942         scsi_do_cmd (SCpnt,
 943                      (void *) cmd, (STp->buffer)->b_data,
 944                      (STp->buffer)->buffer_size,
 945                      st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 946 
 947         if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 948 
 949         (STp->buffer)->read_pointer = 0;
 950         STp->eof_hit = 0;
 951 
 952         if ((STp->buffer)->last_result_fatal) {
 953 #ifdef DEBUG
 954           if (debugging)
 955             printk("st%d: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", dev,
 956                    SCpnt->sense_buffer[0], SCpnt->sense_buffer[1],
 957                    SCpnt->sense_buffer[2], SCpnt->sense_buffer[3],
 958                    SCpnt->sense_buffer[4], SCpnt->sense_buffer[5],
 959                    SCpnt->sense_buffer[6], SCpnt->sense_buffer[7]);
 960 #endif
 961           if ((SCpnt->sense_buffer[0] & 0x70) == 0x70) { /* extended sense */
 962 
 963             if ((SCpnt->sense_buffer[2] & 0xe0) != 0) { /* EOF, EOM, or ILI */
 964 
 965               if ((SCpnt->sense_buffer[0] & 0x80) != 0)
 966                 transfer = (SCpnt->sense_buffer[3] << 24) |
 967                   (SCpnt->sense_buffer[4] << 16) |
 968                     (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];
 969               else
 970                 transfer = 0;
 971               if (STp->block_size == 0 &&
 972                   (SCpnt->sense_buffer[2] & 0x0f) == MEDIUM_ERROR)
 973                 transfer = bytes;
 974 
 975               if (SCpnt->sense_buffer[2] & 0x20) {
 976                 if (STp->block_size == 0) {
 977                   if (transfer <= 0)
 978                     transfer = 0;
 979                   (STp->buffer)->buffer_bytes = bytes - transfer;
 980                 }
 981                 else {
 982                   printk("st%d: Incorrect block size.\n", dev);
 983                   SCpnt->request.dev = -1;  /* Mark as not busy */
 984                   return (-EIO);
 985                 }
 986               }
 987               else if (SCpnt->sense_buffer[2] & 0x40) {
 988                 STp->eof = ST_EOM_OK;
 989                 if (STp->block_size == 0)
 990                   (STp->buffer)->buffer_bytes = bytes - transfer;
 991                 else
 992                   (STp->buffer)->buffer_bytes =
 993                     bytes - transfer * STp->block_size;
 994 #ifdef DEBUG
 995                 if (debugging)
 996                   printk("st%d: EOM detected (%d bytes read).\n", dev,
 997                          (STp->buffer)->buffer_bytes);
 998 #endif
 999               }
1000               else if (SCpnt->sense_buffer[2] & 0x80) {
1001                 STp->eof = ST_FM;
1002                 if (STp->block_size == 0)
1003                   (STp->buffer)->buffer_bytes = 0;
1004                 else
1005                   (STp->buffer)->buffer_bytes =
1006                     bytes - transfer * STp->block_size;
1007 #ifdef DEBUG
1008                 if (debugging)
1009                   printk(
1010                     "st%d: EOF detected (%d bytes read, transferred %d bytes).\n",
1011                          dev, (STp->buffer)->buffer_bytes, total);
1012 #endif
1013               } /* end of EOF, EOM, ILI test */
1014             }
1015             else { /* nonzero sense key */
1016 #ifdef DEBUG
1017               if (debugging)
1018                 printk("st%d: Tape error while reading.\n", dev);
1019 #endif
1020               SCpnt->request.dev = -1;
1021               STp->drv_block = (-1);
1022               if (total)
1023                 return total;
1024               else
1025                 return -EIO;
1026             }
1027           }
1028           else {
1029             transfer = (STp->buffer)->last_result_fatal;
1030             SCpnt->request.dev = -1;  /* Mark as not busy */
1031             return transfer;
1032           }
1033         }
1034         else /* Read successful */
1035           (STp->buffer)->buffer_bytes = bytes;
1036 
1037         if (STp->drv_block >= 0) {
1038           if (STp->block_size == 0)
1039             STp->drv_block++;
1040           else
1041             STp->drv_block += (STp->buffer)->buffer_bytes / STp->block_size;
1042         }
1043 
1044       } /* if ((STp->buffer)->buffer_bytes == 0 &&
1045            STp->eof == ST_NOEOF) */
1046 
1047       if ((STp->buffer)->buffer_bytes > 0) {
1048 #ifdef DEBUG
1049         if (debugging && STp->eof != ST_NOEOF)
1050           printk("st%d: EOF up. Left %d, needed %d.\n", dev,
1051                  (STp->buffer)->buffer_bytes, count - total);
1052 #endif
1053         transfer = (STp->buffer)->buffer_bytes < count - total ?
1054           (STp->buffer)->buffer_bytes : count - total;
1055         memcpy_tofs(buf, (STp->buffer)->b_data +
1056                     (STp->buffer)->read_pointer,transfer);
1057         filp->f_pos += transfer;
1058         buf += transfer;
1059         total += transfer;
1060         (STp->buffer)->buffer_bytes -= transfer;
1061         (STp->buffer)->read_pointer += transfer;
1062       }
1063       else if (STp->eof != ST_NOEOF) {
1064         STp->eof_hit = 1;
1065         SCpnt->request.dev = -1;  /* Mark as not busy */
1066         if (total == 0 && STp->eof == ST_FM) {
1067           STp->eof = 0;
1068           STp->drv_block = 0;
1069           (STp->mt_status)->mt_fileno++;
1070         }
1071         if (total == 0 && STp->eof == ST_EOM_OK)
1072           return (-EIO);  /* ST_EOM_ERROR not used in read */
1073         return total;
1074       }
1075 
1076       if (STp->block_size == 0)
1077         count = total;  /* Read only one variable length block */
1078 
1079     } /* for (total = 0; total < count; ) */
1080 
1081     SCpnt->request.dev = -1;  /* Mark as not busy */
1082 
1083     return total;
1084 }
1085 
1086 
1087 
1088 /* Set the driver options */
1089         static int
1090 st_set_options(struct inode * inode, long options)
     /* [previous][next][first][last][top][bottom][index][help] */
1091 {
1092   int dev, value;
1093   Scsi_Tape *STp;
1094 
1095   dev = MINOR(inode->i_rdev) & 127;
1096   STp = &(scsi_tapes[dev]);
1097   if ((options & MT_ST_OPTIONS) == MT_ST_BOOLEANS) {
1098     STp->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
1099     STp->do_async_writes  = (options & MT_ST_ASYNC_WRITES) != 0;
1100     STp->do_read_ahead    = (options & MT_ST_READ_AHEAD) != 0;
1101 #ifdef DEBUG
1102     debugging = (options & MT_ST_DEBUGGING) != 0;
1103     printk(
1104 "st%d: options: buffer writes: %d, async writes: %d, read ahead: %d\n",
1105            dev, STp->do_buffer_writes, STp->do_async_writes,
1106            STp->do_read_ahead);
1107     printk("              debugging: %d\n", debugging);
1108 #endif
1109   }
1110   else if ((options & MT_ST_OPTIONS) == MT_ST_WRITE_THRESHOLD) {
1111     value = (options & ~MT_ST_OPTIONS) * ST_BLOCK_SIZE;
1112     if (value < 1 || value > st_buffer_size) {
1113       printk("st: Write threshold %d too small or too large.\n",
1114              value);
1115       return (-EIO);
1116     }
1117     STp->write_threshold = value;
1118 #ifdef DEBUG
1119     printk("st%d: Write threshold set to %d bytes.\n", dev,
1120            STp->write_threshold);
1121 #endif
1122   }
1123   else
1124     return (-EIO);
1125 
1126   return 0;
1127 }
1128 
1129 
1130 /* Internal ioctl function */
1131         static int
1132 st_int_ioctl(struct inode * inode,struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
1133              unsigned int cmd_in, unsigned long arg)
1134 {
1135    int dev = MINOR(inode->i_rdev);
1136    int timeout = ST_LONG_TIMEOUT;
1137    long ltmp;
1138    int ioctl_result;
1139    unsigned char cmd[10];
1140    Scsi_Cmnd * SCpnt;
1141    Scsi_Tape * STp;
1142    int fileno, blkno, undone, datalen;
1143 
1144    dev = dev & 127;
1145    STp = &(scsi_tapes[dev]);
1146    fileno = (STp->mt_status)->mt_fileno ;
1147    blkno = STp->drv_block;
1148 
1149    memset(cmd, 0, 10);
1150    datalen = 0;
1151    switch (cmd_in) {
1152      case MTFSF:
1153      case MTFSFM:
1154        cmd[0] = SPACE;
1155        cmd[1] = 0x01; /* Space FileMarks */
1156        cmd[2] = (arg >> 16);
1157        cmd[3] = (arg >> 8);
1158        cmd[4] = arg;
1159 #ifdef DEBUG
1160        if (debugging)
1161          printk("st%d: Spacing tape forward over %d filemarks.\n", dev,
1162                 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1163 #endif
1164        fileno += arg;
1165        blkno = 0;
1166        break; 
1167      case MTBSF:
1168      case MTBSFM:
1169        cmd[0] = SPACE;
1170        cmd[1] = 0x01; /* Space FileMarks */
1171        ltmp = (-arg);
1172        cmd[2] = (ltmp >> 16);
1173        cmd[3] = (ltmp >> 8);
1174        cmd[4] = ltmp;
1175 #ifdef DEBUG
1176        if (debugging) {
1177          if (cmd[2] & 0x80)
1178            ltmp = 0xff000000;
1179          ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
1180          printk("st%d: Spacing tape backward over %ld filemarks.\n", dev, (-ltmp));
1181        }
1182 #endif
1183        fileno -= arg;
1184        blkno = (-1);  /* We can't know the block number */
1185        break; 
1186       case MTFSR:
1187        cmd[0] = SPACE;
1188        cmd[1] = 0x00; /* Space Blocks */
1189        cmd[2] = (arg >> 16);
1190        cmd[3] = (arg >> 8);
1191        cmd[4] = arg;
1192 #ifdef DEBUG
1193        if (debugging)
1194          printk("st%d: Spacing tape forward %d blocks.\n", dev,
1195                 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1196 #endif
1197        if (blkno >= 0)
1198          blkno += arg;
1199        break; 
1200      case MTBSR:
1201        cmd[0] = SPACE;
1202        cmd[1] = 0x00; /* Space Blocks */
1203        ltmp = (-arg);
1204        cmd[2] = (ltmp >> 16);
1205        cmd[3] = (ltmp >> 8);
1206        cmd[4] = ltmp;
1207 #ifdef DEBUG
1208        if (debugging) {
1209          if (cmd[2] & 0x80)
1210            ltmp = 0xff000000;
1211          ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
1212          printk("st%d: Spacing tape backward %ld blocks.\n", dev, (-ltmp));
1213        }
1214 #endif
1215        if (blkno >= 0)
1216          blkno -= arg;
1217        break; 
1218      case MTWEOF:
1219        if (STp->write_prot)
1220          return (-EACCES);
1221        cmd[0] = WRITE_FILEMARKS;
1222        cmd[2] = (arg >> 16);
1223        cmd[3] = (arg >> 8);
1224        cmd[4] = arg;
1225        timeout = ST_TIMEOUT;
1226 #ifdef DEBUG
1227        if (debugging)
1228          printk("st%d: Writing %d filemarks.\n", dev,
1229                 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1230 #endif
1231        fileno += arg;
1232        blkno = 0;
1233        break; 
1234      case MTREW:
1235        cmd[0] = REZERO_UNIT;
1236 #ifdef ST_NOWAIT
1237        cmd[1] = 1;  /* Don't wait for completion */
1238        timeout = ST_TIMEOUT;
1239 #endif
1240 #ifdef DEBUG
1241        if (debugging)
1242          printk("st%d: Rewinding tape.\n", dev);
1243 #endif
1244        fileno = blkno = 0 ;
1245        break; 
1246      case MTOFFL:
1247        cmd[0] = START_STOP;
1248 #ifdef ST_NOWAIT
1249        cmd[1] = 1;  /* Don't wait for completion */
1250        timeout = ST_TIMEOUT;
1251 #endif
1252 #ifdef DEBUG
1253        if (debugging)
1254          printk("st%d: Unloading tape.\n", dev);
1255 #endif
1256        fileno = blkno = 0 ;
1257        break; 
1258      case MTNOP:
1259 #ifdef DEBUG
1260        if (debugging)
1261          printk("st%d: No op on tape.\n", dev);
1262 #endif
1263        return 0;  /* Should do something ? */
1264        break;
1265      case MTRETEN:
1266        cmd[0] = START_STOP;
1267 #ifdef ST_NOWAIT
1268        cmd[1] = 1;  /* Don't wait for completion */
1269        timeout = ST_TIMEOUT;
1270 #endif
1271        cmd[4] = 3;
1272 #ifdef DEBUG
1273        if (debugging)
1274          printk("st%d: Retensioning tape.\n", dev);
1275 #endif
1276        fileno = blkno = 0 ;
1277        break; 
1278      case MTEOM:
1279        /* space to the end of tape */
1280        ioctl_result = st_int_ioctl(inode, file, MTFSF, 0x3fff);
1281        fileno = (STp->mt_status)->mt_fileno ;
1282        /* The next lines would hide the number of spaced FileMarks
1283           That's why I inserted the previous lines. I had no luck
1284           with detecting EOM with FSF, so we go now to EOM.
1285           Joerg Weule */
1286        cmd[0] = SPACE;
1287        cmd[1] = 3;
1288 #ifdef DEBUG
1289        if (debugging)
1290          printk("st%d: Spacing to end of recorded medium.\n", dev);
1291 #endif
1292        blkno = (-1);
1293        break; 
1294      case MTERASE:
1295        if (STp->write_prot)
1296          return (-EACCES);
1297        cmd[0] = ERASE;
1298        cmd[1] = 1;  /* To the end of tape */
1299 #ifdef DEBUG
1300        if (debugging)
1301          printk("st%d: Erasing tape.\n", dev);
1302 #endif
1303        fileno = blkno = 0 ;
1304        break;
1305      case MTSEEK:
1306        if ((STp->device)->scsi_level < SCSI_2) {
1307          cmd[0] = QFA_SEEK_BLOCK;
1308          cmd[2] = (arg >> 16);
1309          cmd[3] = (arg >> 8);
1310          cmd[4] = arg;
1311          cmd[5] = 0;
1312        }
1313        else {
1314          cmd[0] = SEEK_10;
1315          cmd[1] = 4;
1316          cmd[3] = (arg >> 24);
1317          cmd[4] = (arg >> 16);
1318          cmd[5] = (arg >> 8);
1319          cmd[6] = arg;
1320        }
1321 #ifdef ST_NOWAIT
1322        cmd[1] |= 1;  /* Don't wait for completion */
1323        timeout = ST_TIMEOUT;
1324 #endif
1325 #ifdef DEBUG
1326        if (debugging)
1327          printk("st%d: Seeking tape to block %ld.\n", dev, arg);
1328 #endif
1329        fileno = blkno = (-1);
1330        break;
1331      case MTSETBLK:  /* Set block length */
1332      case MTSETDENSITY: /* Set tape density */
1333      case MTSETDRVBUFFER: /* Set drive buffering */
1334        if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
1335          return (-EIO);   /* Not allowed if data in buffer */
1336        if (cmd_in == MTSETBLK &&
1337            arg != 0 &&
1338            (arg < STp->min_block || arg > STp->max_block ||
1339             arg > st_buffer_size)) {
1340          printk("st%d: Illegal block size.\n", dev);
1341          return (-EINVAL);
1342        }
1343        cmd[0] = MODE_SELECT;
1344        cmd[4] = datalen = 12;
1345 
1346        memset((STp->buffer)->b_data, 0, 12);
1347        if (cmd_in == MTSETDRVBUFFER)
1348          (STp->buffer)->b_data[2] = (arg & 7) << 4;
1349        else
1350          (STp->buffer)->b_data[2] = 
1351            STp->drv_buffer << 4;
1352        (STp->buffer)->b_data[3] = 8;     /* block descriptor length */
1353        if (cmd_in == MTSETDENSITY)
1354          (STp->buffer)->b_data[4] = arg;
1355        else
1356          (STp->buffer)->b_data[4] = STp->density;
1357        if (cmd_in == MTSETBLK)
1358          ltmp = arg;
1359        else
1360          ltmp = STp->block_size;
1361        (STp->buffer)->b_data[9] = (ltmp >> 16);
1362        (STp->buffer)->b_data[10] = (ltmp >> 8);
1363        (STp->buffer)->b_data[11] = ltmp;
1364        timeout = ST_TIMEOUT;
1365 #ifdef DEBUG
1366        if (debugging) {
1367          if (cmd_in == MTSETBLK)
1368            printk("st%d: Setting block size to %d bytes.\n", dev,
1369                   (STp->buffer)->b_data[9] * 65536 +
1370                   (STp->buffer)->b_data[10] * 256 +
1371                   (STp->buffer)->b_data[11]);
1372          else if (cmd_in == MTSETDENSITY)
1373            printk("st%d: Setting density code to %x.\n", dev,
1374                   (STp->buffer)->b_data[4]);
1375          else
1376            printk("st%d: Setting drive buffer code to %d.\n", dev,
1377                   ((STp->buffer)->b_data[2] >> 4) & 7);
1378        }
1379 #endif
1380        break;
1381      default:
1382        printk("st%d: Unknown st_ioctl command %x.\n", dev, cmd_in);
1383        return (-ENOSYS);
1384      }
1385 
1386    SCpnt = allocate_device(NULL, (STp->device)->index, 1);
1387    SCpnt->sense_buffer[0] = 0;
1388    SCpnt->request.dev = dev;
1389    scsi_do_cmd(SCpnt,
1390                (void *) cmd, (void *) (STp->buffer)->b_data, datalen,
1391                st_sleep_done, timeout, MAX_RETRIES);
1392 
1393    if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
1394 
1395    ioctl_result = (STp->buffer)->last_result_fatal;
1396 
1397    SCpnt->request.dev = -1;  /* Mark as not busy */
1398 
1399    if (!ioctl_result) {
1400      STp->drv_block = blkno;
1401      (STp->mt_status)->mt_fileno = fileno;
1402      if (cmd_in == MTBSFM)
1403        ioctl_result = st_int_ioctl(inode, file, MTFSF, 1);
1404      else if (cmd_in == MTFSFM)
1405        ioctl_result = st_int_ioctl(inode, file, MTBSF, 1);
1406      else if (cmd_in == MTSETBLK) {
1407        STp->block_size = arg;
1408        if (arg != 0) {
1409          (STp->buffer)->buffer_blocks =
1410            st_buffer_size / STp->block_size;
1411          (STp->buffer)->buffer_size =
1412            (STp->buffer)->buffer_blocks * STp->block_size;
1413        }
1414        else {
1415          (STp->buffer)->buffer_blocks = 1;
1416          (STp->buffer)->buffer_size = st_buffer_size;
1417        }
1418        (STp->buffer)->buffer_bytes =
1419          (STp->buffer)->read_pointer = 0;
1420      }
1421      else if (cmd_in == MTSETDRVBUFFER)
1422        STp->drv_buffer = arg;
1423      else if (cmd_in == MTSETDENSITY)
1424        STp->density = arg;
1425      else if (cmd_in == MTEOM || cmd_in == MTWEOF) {
1426        STp->eof = ST_EOM_OK;
1427        STp->eof_hit = 0;
1428      }
1429      else if (cmd_in != MTSETBLK && cmd_in != MTNOP) {
1430        STp->eof = ST_NOEOF;
1431        STp->eof_hit = 0;
1432      }
1433    } else {
1434      if (SCpnt->sense_buffer[2] & 0x40) {
1435        STp->eof = ST_EOM_OK;
1436        STp->eof_hit = 0;
1437        STp->drv_block = 0;
1438      }
1439      undone = (
1440           (SCpnt->sense_buffer[3] << 24) +
1441           (SCpnt->sense_buffer[4] << 16) +
1442           (SCpnt->sense_buffer[5] << 8) +
1443           SCpnt->sense_buffer[6] );
1444      if ( (cmd_in == MTFSF) || (cmd_in == MTFSFM) )
1445        (STp->mt_status)->mt_fileno = fileno - undone ;
1446      else if ( (cmd_in == MTBSF) || (cmd_in == MTBSFM) )
1447        (STp->mt_status)->mt_fileno = fileno + undone ;
1448      else if (cmd_in == MTFSR) {
1449        if (blkno >= undone)
1450          STp->drv_block = blkno - undone;
1451        else
1452          STp->drv_block = (-1);
1453      }
1454      else if (cmd_in == MTBSR && blkno >= 0) {
1455        if (blkno >= 0)
1456          STp->drv_block = blkno + undone;
1457        else
1458          STp->drv_block = (-1);
1459      }
1460    }
1461 
1462    return ioctl_result ;
1463 }
1464 
1465 
1466 
1467 /* The ioctl command */
1468         static int
1469 st_ioctl(struct inode * inode,struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
1470          unsigned int cmd_in, unsigned long arg)
1471 {
1472    int dev = MINOR(inode->i_rdev);
1473    int i, cmd, result;
1474    struct mtop mtc;
1475    struct mtpos mt_pos;
1476    unsigned char scmd[10];
1477    Scsi_Cmnd *SCpnt;
1478    Scsi_Tape *STp;
1479 
1480    dev = dev & 127;
1481    STp = &(scsi_tapes[dev]);
1482 #ifdef DEBUG
1483    if (debugging && !STp->in_use) {
1484      printk("st%d: Incorrect device.\n", dev);
1485      return (-EIO);
1486    }
1487 #endif
1488 
1489    cmd = cmd_in & IOCCMD_MASK;
1490    if (cmd == (MTIOCTOP & IOCCMD_MASK)) {
1491 
1492      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(mtc))
1493        return (-EINVAL);
1494 
1495      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(mtc));
1496      if (i)
1497         return i;
1498 
1499      memcpy_fromfs((char *) &mtc, (char *)arg, sizeof(struct mtop));
1500 
1501      i = flush_buffer(inode, file, mtc.mt_op == MTSEEK ||
1502                       mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
1503                       mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM);
1504      if (i < 0)
1505        return i;
1506 
1507      if (mtc.mt_op == MTSETDRVBUFFER &&
1508          (mtc.mt_count & MT_ST_OPTIONS) != 0)
1509        return st_set_options(inode, mtc.mt_count);
1510      else
1511        return st_int_ioctl(inode, file, mtc.mt_op, mtc.mt_count);
1512    }
1513    else if (cmd == (MTIOCGET & IOCCMD_MASK)) {
1514 
1515      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtget))
1516        return (-EINVAL);
1517      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct mtget));
1518      if (i)
1519        return i;
1520 
1521      (STp->mt_status)->mt_dsreg =
1522        ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
1523        ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
1524      (STp->mt_status)->mt_blkno = STp->drv_block;
1525      if (STp->block_size != 0) {
1526        if (STp->rw == ST_WRITING)
1527          (STp->mt_status)->mt_blkno +=
1528            (STp->buffer)->buffer_bytes / STp->block_size;
1529        else if (STp->rw == ST_READING)
1530          (STp->mt_status)->mt_blkno -= ((STp->buffer)->buffer_bytes +
1531            STp->block_size - 1) / STp->block_size;
1532      }
1533 
1534      memcpy_tofs((char *)arg, (char *)(STp->mt_status),
1535                  sizeof(struct mtget));
1536 
1537      (STp->mt_status)->mt_erreg = 0;  /* Clear after read */
1538      return 0;
1539    }
1540    else if (cmd == (MTIOCPOS & IOCCMD_MASK)) {
1541 #ifdef DEBUG
1542      if (debugging)
1543        printk("st%d: get tape position.\n", dev);
1544 #endif
1545      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtpos))
1546        return (-EINVAL);
1547 
1548      i = flush_buffer(inode, file, 0);
1549      if (i < 0)
1550        return i;
1551 
1552      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct mtpos));
1553      if (i)
1554        return i;
1555 
1556      SCpnt = allocate_device(NULL, (STp->device)->index, 1);
1557 
1558      SCpnt->sense_buffer[0]=0;
1559      memset (scmd, 0, 10);
1560      if ((STp->device)->scsi_level < SCSI_2) {
1561        scmd[0] = QFA_REQUEST_BLOCK;
1562        scmd[4] = 3;
1563      }
1564      else {
1565        scmd[0] = READ_POSITION;
1566        scmd[1] = 1;
1567      }
1568      SCpnt->request.dev = dev;
1569      SCpnt->sense_buffer[0] = 0;
1570      scsi_do_cmd(SCpnt,
1571                  (void *) scmd, (void *) (STp->buffer)->b_data,
1572                  20, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
1573 
1574      if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
1575      
1576      if ((STp->buffer)->last_result_fatal != 0) {
1577        mt_pos.mt_blkno = (-1);
1578 #ifdef DEBUG
1579        if (debugging)
1580          printk("st%d: Can't read tape position.\n", dev);
1581 #endif
1582        result = (-EIO);
1583      }
1584      else {
1585        result = 0;
1586        if ((STp->device)->scsi_level < SCSI_2)
1587          mt_pos.mt_blkno = ((STp->buffer)->b_data[0] << 16) 
1588            + ((STp->buffer)->b_data[1] << 8) 
1589              + (STp->buffer)->b_data[2];
1590        else
1591          mt_pos.mt_blkno = ((STp->buffer)->b_data[4] << 24)
1592            + ((STp->buffer)->b_data[5] << 16) 
1593              + ((STp->buffer)->b_data[6] << 8) 
1594                + (STp->buffer)->b_data[7];
1595 
1596      }
1597 
1598      SCpnt->request.dev = -1;  /* Mark as not busy */
1599 
1600      memcpy_tofs((char *)arg, (char *) (&mt_pos), sizeof(struct mtpos));
1601      return result;
1602    }
1603    else
1604      return scsi_ioctl(STp->device, cmd_in, (void *) arg);
1605 }
1606 
1607 
1608 /* Set the boot options. Syntax: st=xxx,yyy
1609    where xxx is buffer size in 512 byte blocks and yyy is write threshold
1610    in 512 byte blocks. */
1611         void
1612 st_setup(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
1613 {
1614   if (ints[0] > 0 && ints[1] > 0)
1615     st_buffer_size = ints[1] * ST_BLOCK_SIZE;
1616   if (ints[0] > 1 && ints[2] > 0) {
1617     st_write_threshold = ints[2] * ST_BLOCK_SIZE;
1618     if (st_write_threshold > st_buffer_size)
1619       st_write_threshold = st_buffer_size;
1620   }
1621   if (ints[0] > 2 && ints[3] > 0)
1622     st_max_buffers = ints[3];
1623 }
1624 
1625 
1626 static struct file_operations st_fops = {
1627    NULL,            /* lseek - default */
1628    st_read,         /* read - general block-dev read */
1629    st_write,        /* write - general block-dev write */
1630    NULL,            /* readdir - bad */
1631    NULL,            /* select */
1632    st_ioctl,        /* ioctl */
1633    NULL,            /* mmap */
1634    scsi_tape_open,  /* open */
1635    scsi_tape_close, /* release */
1636    NULL             /* fsync */
1637 };
1638 
1639 void st_attach(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
1640   scsi_tapes[NR_ST++].device = SDp;
1641   if(NR_ST > MAX_ST) panic ("scsi_devices corrupt (st)");
1642 };
1643 
1644 unsigned long st_init1(unsigned long mem_start, unsigned long mem_end){
     /* [previous][next][first][last][top][bottom][index][help] */
1645   scsi_tapes = (Scsi_Tape *) mem_start;
1646   mem_start += MAX_ST * sizeof(Scsi_Tape);
1647   return mem_start;
1648 };
1649 
1650 /* Driver initialization */
1651 unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
1652 {
1653   int i, dev_nbr;
1654   Scsi_Tape * STp;
1655 
1656   if (register_chrdev(MAJOR_NR,"st",&st_fops)) {
1657     printk("Unable to get major %d for SCSI tapes\n",MAJOR_NR);
1658     return mem_start;
1659   }
1660   if (NR_ST == 0) return mem_start;
1661 
1662 #ifdef DEBUG
1663   printk("st: Buffer size %d bytes, write threshold %d bytes.\n",
1664          st_buffer_size, st_write_threshold);
1665 #endif
1666 
1667   for (i=0, dev_nbr=(-1); i < NR_ST; ++i) {
1668     STp = &(scsi_tapes[i]);
1669     STp->capacity = 0xfffff;
1670     STp->dirty = 0;
1671     STp->rw = ST_IDLE;
1672     STp->eof = ST_NOEOF;
1673     STp->waiting = NULL;
1674     STp->in_use = 0;
1675     STp->drv_buffer = 1;  /* Try buffering if no mode sense */
1676     STp->density = 0;
1677     STp->do_buffer_writes = ST_BUFFER_WRITES;
1678     STp->do_async_writes = ST_ASYNC_WRITES;
1679     STp->do_read_ahead = ST_READ_AHEAD;
1680     STp->write_threshold = st_write_threshold;
1681     STp->drv_block = 0;
1682     STp->mt_status = (struct mtget *) mem_start;
1683     mem_start += sizeof(struct mtget);
1684     /* Initialize status */
1685     memset((void *) scsi_tapes[i].mt_status, 0, sizeof(struct mtget));
1686     for (dev_nbr++; dev_nbr < NR_SCSI_DEVICES; dev_nbr++)
1687       if (scsi_devices[dev_nbr].type == TYPE_TAPE)
1688         break;
1689     if (dev_nbr >= NR_SCSI_DEVICES)
1690       printk("st%d: ERROR: Not found in scsi chain.\n", i);
1691     else {
1692       if (scsi_devices[dev_nbr].scsi_level <= 2)
1693         STp->mt_status->mt_type = MT_ISSCSI1;
1694       else
1695         STp->mt_status->mt_type = MT_ISSCSI2;
1696     }
1697   }
1698 
1699   /* Allocate the buffers */
1700   st_nbr_buffers = NR_ST;
1701   if (st_nbr_buffers > st_max_buffers)
1702     st_nbr_buffers = st_max_buffers;
1703   st_buffers = (ST_buffer **)mem_start;
1704   mem_start += st_nbr_buffers * sizeof(ST_buffer *);
1705   for (i=0; i < st_nbr_buffers; i++) {
1706     st_buffers[i] = (ST_buffer *) mem_start;
1707 #ifdef DEBUG
1708 /*    printk("st: Buffer address: %p\n", st_buffers[i]); */
1709 #endif
1710     mem_start += sizeof(ST_buffer) - 1 + st_buffer_size;
1711     st_buffers[i]->in_use = 0;
1712     st_buffers[i]->writing = 0;
1713   }
1714 
1715   return mem_start;
1716 }

/* [previous][next][first][last][top][bottom][index][help] */