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

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