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

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