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
  18. st_detach

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

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