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. flush_write_buffer
  5. flush_buffer
  6. scsi_tape_open
  7. scsi_tape_close
  8. st_write
  9. st_read
  10. st_int_ioctl
  11. st_ioctl
  12. st_attach
  13. st_init1
  14. st_init

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

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