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: Mon Jan 30 23:20:07 1995 by root@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 + ST_EXTRA_DEVS)
  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 = !((STp->buffer)->writing ==
 898                      (STp->buffer)->buffer_bytes);
 899 
 900       if (STp->block_size == 0)
 901         blks = (STp->buffer)->writing;
 902       else
 903         blks = (STp->buffer)->writing / STp->block_size;
 904       cmd[2] = blks >> 16;
 905       cmd[3] = blks >> 8;
 906       cmd[4] = blks;
 907       SCpnt->result = (STp->buffer)->last_result = -1;
 908       SCpnt->sense_buffer[0] = 0;
 909       SCpnt->request.dev = dev;
 910       scsi_do_cmd (SCpnt,
 911                    (void *) cmd, (STp->buffer)->b_data,
 912                    (STp->buffer)->writing,
 913                    st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 914     }
 915     else
 916       SCpnt->request.dev = -1;  /* Mark as not busy */
 917 
 918     STp->at_sm &= (total != 0);
 919     return( total);
 920 }   
 921 
 922 
 923 /* Read command */
 924         static int
 925 st_read(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 926 {
 927     int dev;
 928     int total;
 929     int transfer, blks, bytes;
 930     static unsigned char cmd[10];
 931     Scsi_Cmnd * SCpnt;
 932     Scsi_Tape * STp;
 933 
 934     dev = MINOR(inode->i_rdev) & 127;
 935     STp = &(scsi_tapes[dev]);
 936     if (STp->ready != ST_READY)
 937       return (-EIO);
 938 #ifdef DEBUG
 939     if (!STp->in_use) {
 940       printk("st%d: Incorrect device.\n", dev);
 941       return (-EIO);
 942     }
 943 #endif
 944 
 945     if (STp->block_size == 0 && count > st_buffer_size)
 946       return (-EOVERFLOW);
 947 
 948     if (!(STp->do_read_ahead) && STp->block_size != 0 &&
 949         (count % STp->block_size) != 0)
 950       return (-EIO);    /* Read must be integral number of blocks */
 951 
 952     if (STp->rw == ST_WRITING) {
 953       transfer = flush_buffer(inode, filp, 0);
 954       if (transfer)
 955         return transfer;
 956       STp->rw = ST_READING;
 957     }
 958     if (STp->moves_after_eof < 255)
 959       STp->moves_after_eof++;
 960 
 961 #ifdef DEBUG
 962     if (debugging && STp->eof != ST_NOEOF)
 963       printk("st%d: EOF flag up. Bytes %d\n", dev,
 964              (STp->buffer)->buffer_bytes);
 965 #endif
 966     if (((STp->buffer)->buffer_bytes == 0) &&
 967         (STp->eof == ST_EOM_OK || STp->eof == ST_EOD))
 968       return (-EIO);  /* EOM or Blank Check */
 969 
 970     STp->rw = ST_READING;
 971 
 972     SCpnt = allocate_device(NULL, STp->device, 1);
 973 
 974     for (total = 0; total < count; ) {
 975 
 976       if ((STp->buffer)->buffer_bytes == 0 &&
 977           STp->eof == ST_NOEOF) {
 978 
 979         memset(cmd, 0, 10);
 980         cmd[0] = READ_6;
 981         cmd[1] = (STp->block_size != 0);
 982         if (STp->block_size == 0)
 983           blks = bytes = count;
 984         else {
 985           if (STp->do_read_ahead) {
 986             blks = (STp->buffer)->buffer_blocks;
 987             bytes = blks * STp->block_size;
 988           }
 989           else {
 990             bytes = count;
 991             if (bytes > st_buffer_size)
 992               bytes = st_buffer_size;
 993             blks = bytes / STp->block_size;
 994             bytes = blks * STp->block_size;
 995           }
 996         }
 997         cmd[2] = blks >> 16;
 998         cmd[3] = blks >> 8;
 999         cmd[4] = blks;
1000 
1001         SCpnt->sense_buffer[0] = 0;
1002         SCpnt->request.dev = dev;
1003         scsi_do_cmd (SCpnt,
1004                      (void *) cmd, (STp->buffer)->b_data,
1005                      (STp->buffer)->buffer_size,
1006                      st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
1007 
1008         if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
1009 
1010         (STp->buffer)->read_pointer = 0;
1011         STp->eof_hit = 0;
1012         STp->at_sm = 0;
1013 
1014         if ((STp->buffer)->last_result_fatal) {
1015 #ifdef DEBUG
1016           if (debugging)
1017             printk("st%d: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", dev,
1018                    SCpnt->sense_buffer[0], SCpnt->sense_buffer[1],
1019                    SCpnt->sense_buffer[2], SCpnt->sense_buffer[3],
1020                    SCpnt->sense_buffer[4], SCpnt->sense_buffer[5],
1021                    SCpnt->sense_buffer[6], SCpnt->sense_buffer[7]);
1022 #endif
1023           if ((SCpnt->sense_buffer[0] & 0x70) == 0x70) { /* extended sense */
1024 
1025             if ((SCpnt->sense_buffer[2] & 0xe0) != 0) { /* EOF, EOM, or ILI */
1026 
1027               if ((SCpnt->sense_buffer[0] & 0x80) != 0)
1028                 transfer = (SCpnt->sense_buffer[3] << 24) |
1029                   (SCpnt->sense_buffer[4] << 16) |
1030                     (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];
1031               else
1032                 transfer = 0;
1033               if (STp->block_size == 0 &&
1034                   (SCpnt->sense_buffer[2] & 0x0f) == MEDIUM_ERROR)
1035                 transfer = bytes;
1036 
1037               if (SCpnt->sense_buffer[2] & 0x20) {
1038                 if (STp->block_size == 0) {
1039                   if (transfer <= 0)
1040                     transfer = 0;
1041                   (STp->buffer)->buffer_bytes = bytes - transfer;
1042                 }
1043                 else {
1044                   printk("st%d: Incorrect block size.\n", dev);
1045                   SCpnt->request.dev = -1;  /* Mark as not busy */
1046                   return (-EIO);
1047                 }
1048               }
1049               else if (SCpnt->sense_buffer[2] & 0x40) {
1050                 STp->eof = ST_EOM_OK;
1051                 if (STp->block_size == 0)
1052                   (STp->buffer)->buffer_bytes = bytes - transfer;
1053                 else
1054                   (STp->buffer)->buffer_bytes =
1055                     bytes - transfer * STp->block_size;
1056 #ifdef DEBUG
1057                 if (debugging)
1058                   printk("st%d: EOM detected (%d bytes read).\n", dev,
1059                          (STp->buffer)->buffer_bytes);
1060 #endif
1061               }
1062               else if (SCpnt->sense_buffer[2] & 0x80) {
1063                 STp->eof = ST_FM;
1064                 if (STp->block_size == 0)
1065                   (STp->buffer)->buffer_bytes = 0;
1066                 else
1067                   (STp->buffer)->buffer_bytes =
1068                     bytes - transfer * STp->block_size;
1069 #ifdef DEBUG
1070                 if (debugging)
1071                   printk(
1072                     "st%d: EOF detected (%d bytes read, transferred %d bytes).\n",
1073                          dev, (STp->buffer)->buffer_bytes, total);
1074 #endif
1075               }
1076             } /* end of EOF, EOM, ILI test */
1077             else { /* nonzero sense key */
1078 #ifdef DEBUG
1079               if (debugging)
1080                 printk("st%d: Tape error while reading.\n", dev);
1081 #endif
1082               SCpnt->request.dev = -1;
1083               STp->drv_block = (-1);
1084               if (total)
1085                 return total;
1086               else if (STp->moves_after_eof == 1 &&
1087                        (SCpnt->sense_buffer[2] & 0x0f) == BLANK_CHECK) {
1088 #ifdef DEBUG
1089                 if (debugging)
1090                   printk("st%d: Zero returned for first BLANK CHECK after EOF.\n",
1091                          dev);
1092 #endif
1093                 STp->eof = ST_EOD;
1094                 return 0; /* First BLANK_CHECK after EOF */
1095               }
1096               else
1097                 return -EIO;
1098             }
1099           } /* End of extended sense test */
1100           else {
1101             transfer = (STp->buffer)->last_result_fatal;
1102             SCpnt->request.dev = -1;  /* Mark as not busy */
1103             return transfer;
1104           }
1105         } /* End of error handling */
1106         else /* Read successful */
1107           (STp->buffer)->buffer_bytes = bytes;
1108 
1109         if (STp->drv_block >= 0) {
1110           if (STp->block_size == 0)
1111             STp->drv_block++;
1112           else
1113             STp->drv_block += (STp->buffer)->buffer_bytes / STp->block_size;
1114         }
1115 
1116       } /* if ((STp->buffer)->buffer_bytes == 0 &&
1117            STp->eof == ST_NOEOF) */
1118 
1119       if ((STp->buffer)->buffer_bytes > 0) {
1120 #ifdef DEBUG
1121         if (debugging && STp->eof != ST_NOEOF)
1122           printk("st%d: EOF up. Left %d, needed %d.\n", dev,
1123                  (STp->buffer)->buffer_bytes, count - total);
1124 #endif
1125         transfer = (STp->buffer)->buffer_bytes < count - total ?
1126           (STp->buffer)->buffer_bytes : count - total;
1127         memcpy_tofs(buf, (STp->buffer)->b_data +
1128                     (STp->buffer)->read_pointer,transfer);
1129         filp->f_pos += transfer;
1130         buf += transfer;
1131         total += transfer;
1132         (STp->buffer)->buffer_bytes -= transfer;
1133         (STp->buffer)->read_pointer += transfer;
1134       }
1135       else if (STp->eof != ST_NOEOF) {
1136         STp->eof_hit = 1;
1137         SCpnt->request.dev = -1;  /* Mark as not busy */
1138         if (total == 0 && STp->eof == ST_FM) {
1139           STp->eof = ST_NOEOF;
1140           STp->drv_block = 0;
1141           if (STp->moves_after_eof > 1)
1142             STp->moves_after_eof = 0;
1143           if ((STp->mt_status)->mt_fileno >= 0)
1144             (STp->mt_status)->mt_fileno++;
1145         }
1146         if (total == 0 && STp->eof == ST_EOM_OK)
1147           return (-EIO);  /* ST_EOM_ERROR not used in read */
1148         return total;
1149       }
1150 
1151       if (STp->block_size == 0)
1152         count = total;  /* Read only one variable length block */
1153 
1154     } /* for (total = 0; total < count; ) */
1155 
1156     SCpnt->request.dev = -1;  /* Mark as not busy */
1157 
1158     return total;
1159 }
1160 
1161 
1162 
1163 /* Set the driver options */
1164         static int
1165 st_set_options(struct inode * inode, long options)
     /* [previous][next][first][last][top][bottom][index][help] */
1166 {
1167   int dev, value;
1168   Scsi_Tape *STp;
1169 
1170   dev = MINOR(inode->i_rdev) & 127;
1171   STp = &(scsi_tapes[dev]);
1172   if ((options & MT_ST_OPTIONS) == MT_ST_BOOLEANS) {
1173     STp->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
1174     STp->do_async_writes  = (options & MT_ST_ASYNC_WRITES) != 0;
1175     STp->do_read_ahead    = (options & MT_ST_READ_AHEAD) != 0;
1176     STp->two_fm           = (options & MT_ST_TWO_FM) != 0;
1177     STp->fast_mteom       = (options & MT_ST_FAST_MTEOM) != 0;
1178 #ifdef DEBUG
1179     debugging = (options & MT_ST_DEBUGGING) != 0;
1180     printk(
1181 "st%d: options: buffer writes: %d, async writes: %d, read ahead: %d\n",
1182            dev, STp->do_buffer_writes, STp->do_async_writes,
1183            STp->do_read_ahead);
1184     printk("              two FMs: %d, fast mteom: %d debugging: %d\n",
1185            STp->two_fm, STp->fast_mteom, debugging);
1186 #endif
1187   }
1188   else if ((options & MT_ST_OPTIONS) == MT_ST_WRITE_THRESHOLD) {
1189     value = (options & ~MT_ST_OPTIONS) * ST_BLOCK_SIZE;
1190     if (value < 1 || value > st_buffer_size) {
1191       printk("st: Write threshold %d too small or too large.\n",
1192              value);
1193       return (-EIO);
1194     }
1195     STp->write_threshold = value;
1196 #ifdef DEBUG
1197     printk("st%d: Write threshold set to %d bytes.\n", dev,
1198            STp->write_threshold);
1199 #endif
1200   }
1201   else
1202     return (-EIO);
1203 
1204   return 0;
1205 }
1206 
1207 
1208 /* Internal ioctl function */
1209         static int
1210 st_int_ioctl(struct inode * inode,struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
1211              unsigned int cmd_in, unsigned long arg)
1212 {
1213    int dev = MINOR(inode->i_rdev);
1214    int timeout = ST_LONG_TIMEOUT;
1215    long ltmp;
1216    int ioctl_result;
1217    unsigned char cmd[10];
1218    Scsi_Cmnd * SCpnt;
1219    Scsi_Tape * STp;
1220    int fileno, blkno, at_sm, undone, datalen;
1221 
1222    dev = dev & 127;
1223    STp = &(scsi_tapes[dev]);
1224    if (STp->ready != ST_READY)
1225      return (-EIO);
1226    fileno = (STp->mt_status)->mt_fileno ;
1227    blkno = STp->drv_block;
1228    at_sm = STp->at_sm;
1229 
1230    memset(cmd, 0, 10);
1231    datalen = 0;
1232    switch (cmd_in) {
1233      case MTFSF:
1234      case MTFSFM:
1235        cmd[0] = SPACE;
1236        cmd[1] = 0x01; /* Space FileMarks */
1237        cmd[2] = (arg >> 16);
1238        cmd[3] = (arg >> 8);
1239        cmd[4] = arg;
1240 #ifdef DEBUG
1241        if (debugging)
1242          printk("st%d: Spacing tape forward over %d filemarks.\n", dev,
1243                 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1244 #endif
1245        if (fileno >= 0)
1246          fileno += arg;
1247        blkno = 0;
1248        at_sm &= (arg != 0);
1249        break; 
1250      case MTBSF:
1251      case MTBSFM:
1252        cmd[0] = SPACE;
1253        cmd[1] = 0x01; /* Space FileMarks */
1254        ltmp = (-arg);
1255        cmd[2] = (ltmp >> 16);
1256        cmd[3] = (ltmp >> 8);
1257        cmd[4] = ltmp;
1258 #ifdef DEBUG
1259        if (debugging) {
1260          if (cmd[2] & 0x80)
1261            ltmp = 0xff000000;
1262          ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
1263          printk("st%d: Spacing tape backward over %ld filemarks.\n", dev, (-ltmp));
1264        }
1265 #endif
1266        if (fileno >= 0)
1267          fileno -= arg;
1268        blkno = (-1);  /* We can't know the block number */
1269        at_sm &= (arg != 0);
1270        break; 
1271      case MTFSR:
1272        cmd[0] = SPACE;
1273        cmd[1] = 0x00; /* Space Blocks */
1274        cmd[2] = (arg >> 16);
1275        cmd[3] = (arg >> 8);
1276        cmd[4] = arg;
1277 #ifdef DEBUG
1278        if (debugging)
1279          printk("st%d: Spacing tape forward %d blocks.\n", dev,
1280                 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1281 #endif
1282        if (blkno >= 0)
1283          blkno += arg;
1284        at_sm &= (arg != 0);
1285        break; 
1286      case MTBSR:
1287        cmd[0] = SPACE;
1288        cmd[1] = 0x00; /* Space Blocks */
1289        ltmp = (-arg);
1290        cmd[2] = (ltmp >> 16);
1291        cmd[3] = (ltmp >> 8);
1292        cmd[4] = ltmp;
1293 #ifdef DEBUG
1294        if (debugging) {
1295          if (cmd[2] & 0x80)
1296            ltmp = 0xff000000;
1297          ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
1298          printk("st%d: Spacing tape backward %ld blocks.\n", dev, (-ltmp));
1299        }
1300 #endif
1301        if (blkno >= 0)
1302          blkno -= arg;
1303        at_sm &= (arg != 0);
1304        break; 
1305      case MTFSS:
1306        cmd[0] = SPACE;
1307        cmd[1] = 0x04; /* Space Setmarks */
1308        cmd[2] = (arg >> 16);
1309        cmd[3] = (arg >> 8);
1310        cmd[4] = arg;
1311 #ifdef DEBUG
1312        if (debugging)
1313          printk("st%d: Spacing tape forward %d setmarks.\n", dev,
1314                 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1315 #endif
1316        if (arg != 0) {
1317          blkno = fileno = (-1);
1318          at_sm = 1;
1319        }
1320        break; 
1321      case MTBSS:
1322        cmd[0] = SPACE;
1323        cmd[1] = 0x04; /* Space Setmarks */
1324        ltmp = (-arg);
1325        cmd[2] = (ltmp >> 16);
1326        cmd[3] = (ltmp >> 8);
1327        cmd[4] = ltmp;
1328 #ifdef DEBUG
1329        if (debugging) {
1330          if (cmd[2] & 0x80)
1331            ltmp = 0xff000000;
1332          ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
1333          printk("st%d: Spacing tape backward %ld setmarks.\n", dev, (-ltmp));
1334        }
1335 #endif
1336        if (arg != 0) {
1337          blkno = fileno = (-1);
1338          at_sm = 1;
1339        }
1340        break; 
1341      case MTWEOF:
1342      case MTWSM:
1343        if (STp->write_prot)
1344          return (-EACCES);
1345        cmd[0] = WRITE_FILEMARKS;
1346        if (cmd_in == MTWSM)
1347          cmd[1] = 2;
1348        cmd[2] = (arg >> 16);
1349        cmd[3] = (arg >> 8);
1350        cmd[4] = arg;
1351        timeout = ST_TIMEOUT;
1352 #ifdef DEBUG
1353        if (debugging) {
1354          if (cmd_in == MTWEOF)
1355            printk("st%d: Writing %d filemarks.\n", dev,
1356                   cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1357          else
1358            printk("st%d: Writing %d setmarks.\n", dev,
1359                   cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1360        }
1361 #endif
1362        if (fileno >= 0)
1363          fileno += arg;
1364        blkno = 0;
1365        at_sm = (cmd_in == MTWSM);
1366        break; 
1367      case MTREW:
1368        cmd[0] = REZERO_UNIT;
1369 #ifdef ST_NOWAIT
1370        cmd[1] = 1;  /* Don't wait for completion */
1371        timeout = ST_TIMEOUT;
1372 #endif
1373 #ifdef DEBUG
1374        if (debugging)
1375          printk("st%d: Rewinding tape.\n", dev);
1376 #endif
1377        fileno = blkno = at_sm = 0 ;
1378        break; 
1379      case MTOFFL:
1380        cmd[0] = START_STOP;
1381 #ifdef ST_NOWAIT
1382        cmd[1] = 1;  /* Don't wait for completion */
1383        timeout = ST_TIMEOUT;
1384 #endif
1385 #ifdef DEBUG
1386        if (debugging)
1387          printk("st%d: Unloading tape.\n", dev);
1388 #endif
1389        fileno = blkno = at_sm = 0 ;
1390        break; 
1391      case MTNOP:
1392 #ifdef DEBUG
1393        if (debugging)
1394          printk("st%d: No op on tape.\n", dev);
1395 #endif
1396        return 0;  /* Should do something ? */
1397        break;
1398      case MTRETEN:
1399        cmd[0] = START_STOP;
1400 #ifdef ST_NOWAIT
1401        cmd[1] = 1;  /* Don't wait for completion */
1402        timeout = ST_TIMEOUT;
1403 #endif
1404        cmd[4] = 3;
1405 #ifdef DEBUG
1406        if (debugging)
1407          printk("st%d: Retensioning tape.\n", dev);
1408 #endif
1409        fileno = blkno = at_sm = 0;
1410        break; 
1411      case MTEOM:
1412        if (!STp->fast_mteom) {
1413          /* space to the end of tape */
1414          ioctl_result = st_int_ioctl(inode, file, MTFSF, 0x3fff);
1415          fileno = (STp->mt_status)->mt_fileno ;
1416          if (STp->eof == ST_EOD || STp->eof == ST_EOM_OK)
1417            return 0;
1418          /* The next lines would hide the number of spaced FileMarks
1419             That's why I inserted the previous lines. I had no luck
1420             with detecting EOM with FSF, so we go now to EOM.
1421             Joerg Weule */
1422        }
1423        else
1424          fileno = (-1);
1425        cmd[0] = SPACE;
1426        cmd[1] = 3;
1427 #ifdef DEBUG
1428        if (debugging)
1429          printk("st%d: Spacing to end of recorded medium.\n", dev);
1430 #endif
1431        blkno = 0;
1432        at_sm = 0;
1433        break; 
1434      case MTERASE:
1435        if (STp->write_prot)
1436          return (-EACCES);
1437        cmd[0] = ERASE;
1438        cmd[1] = 1;  /* To the end of tape */
1439 #ifdef ST_NOWAIT
1440        cmd[1] |= 2;  /* Don't wait for completion */
1441        timeout = ST_TIMEOUT;
1442 #else
1443        timeout = ST_LONG_TIMEOUT * 8;
1444 #endif
1445 #ifdef DEBUG
1446        if (debugging)
1447          printk("st%d: Erasing tape.\n", dev);
1448 #endif
1449        fileno = blkno = at_sm = 0 ;
1450        break;
1451      case MTSEEK:
1452        if ((STp->device)->scsi_level < SCSI_2) {
1453          cmd[0] = QFA_SEEK_BLOCK;
1454          cmd[2] = (arg >> 16);
1455          cmd[3] = (arg >> 8);
1456          cmd[4] = arg;
1457          cmd[5] = 0;
1458        }
1459        else {
1460          cmd[0] = SEEK_10;
1461          cmd[1] = 4;
1462          cmd[3] = (arg >> 24);
1463          cmd[4] = (arg >> 16);
1464          cmd[5] = (arg >> 8);
1465          cmd[6] = arg;
1466        }
1467 #ifdef ST_NOWAIT
1468        cmd[1] |= 1;  /* Don't wait for completion */
1469        timeout = ST_TIMEOUT;
1470 #endif
1471 #ifdef DEBUG
1472        if (debugging)
1473          printk("st%d: Seeking tape to block %ld.\n", dev, arg);
1474 #endif
1475        fileno = blkno = (-1);
1476        at_sm = 0;
1477        break;
1478      case MTSETBLK:  /* Set block length */
1479      case MTSETDENSITY: /* Set tape density */
1480      case MTSETDRVBUFFER: /* Set drive buffering */
1481        if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
1482          return (-EIO);   /* Not allowed if data in buffer */
1483        if (cmd_in == MTSETBLK &&
1484            arg != 0 &&
1485            (arg < STp->min_block || arg > STp->max_block ||
1486             arg > st_buffer_size)) {
1487          printk("st%d: Illegal block size.\n", dev);
1488          return (-EINVAL);
1489        }
1490        cmd[0] = MODE_SELECT;
1491        cmd[4] = datalen = 12;
1492 
1493        memset((STp->buffer)->b_data, 0, 12);
1494        if (cmd_in == MTSETDRVBUFFER)
1495          (STp->buffer)->b_data[2] = (arg & 7) << 4;
1496        else
1497          (STp->buffer)->b_data[2] = 
1498            STp->drv_buffer << 4;
1499        (STp->buffer)->b_data[3] = 8;     /* block descriptor length */
1500        if (cmd_in == MTSETDENSITY)
1501          (STp->buffer)->b_data[4] = arg;
1502        else
1503          (STp->buffer)->b_data[4] = STp->density;
1504        if (cmd_in == MTSETBLK)
1505          ltmp = arg;
1506        else
1507          ltmp = STp->block_size;
1508        (STp->buffer)->b_data[9] = (ltmp >> 16);
1509        (STp->buffer)->b_data[10] = (ltmp >> 8);
1510        (STp->buffer)->b_data[11] = ltmp;
1511        timeout = ST_TIMEOUT;
1512 #ifdef DEBUG
1513        if (debugging) {
1514          if (cmd_in == MTSETBLK)
1515            printk("st%d: Setting block size to %d bytes.\n", dev,
1516                   (STp->buffer)->b_data[9] * 65536 +
1517                   (STp->buffer)->b_data[10] * 256 +
1518                   (STp->buffer)->b_data[11]);
1519          else if (cmd_in == MTSETDENSITY)
1520            printk("st%d: Setting density code to %x.\n", dev,
1521                   (STp->buffer)->b_data[4]);
1522          else
1523            printk("st%d: Setting drive buffer code to %d.\n", dev,
1524                   ((STp->buffer)->b_data[2] >> 4) & 7);
1525        }
1526 #endif
1527        break;
1528      default:
1529        printk("st%d: Unknown st_ioctl command %x.\n", dev, cmd_in);
1530        return (-ENOSYS);
1531      }
1532 
1533    SCpnt = allocate_device(NULL, STp->device, 1);
1534    SCpnt->sense_buffer[0] = 0;
1535    SCpnt->request.dev = dev;
1536    scsi_do_cmd(SCpnt,
1537                (void *) cmd, (void *) (STp->buffer)->b_data, datalen,
1538                st_sleep_done, timeout, MAX_RETRIES);
1539 
1540    if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
1541 
1542    ioctl_result = (STp->buffer)->last_result_fatal;
1543 
1544    SCpnt->request.dev = -1;  /* Mark as not busy */
1545 
1546    if (cmd_in == MTFSF)
1547      STp->moves_after_eof = 0;
1548    else
1549      STp->moves_after_eof = 1;
1550    if (!ioctl_result) {  /* SCSI command successful */
1551      if (cmd_in != MTSEEK) {
1552        STp->drv_block = blkno;
1553        (STp->mt_status)->mt_fileno = fileno;
1554        STp->at_sm = at_sm;
1555      }
1556      else {
1557        STp->drv_block = (STp->mt_status)->mt_fileno = (-1);
1558        STp->at_sm = 0;
1559      }
1560      if (cmd_in == MTBSFM)
1561        ioctl_result = st_int_ioctl(inode, file, MTFSF, 1);
1562      else if (cmd_in == MTFSFM)
1563        ioctl_result = st_int_ioctl(inode, file, MTBSF, 1);
1564      else if (cmd_in == MTSETBLK) {
1565        STp->block_size = arg;
1566        if (arg != 0) {
1567          (STp->buffer)->buffer_blocks =
1568            st_buffer_size / STp->block_size;
1569          (STp->buffer)->buffer_size =
1570            (STp->buffer)->buffer_blocks * STp->block_size;
1571        }
1572        else {
1573          (STp->buffer)->buffer_blocks = 1;
1574          (STp->buffer)->buffer_size = st_buffer_size;
1575        }
1576        (STp->buffer)->buffer_bytes =
1577          (STp->buffer)->read_pointer = 0;
1578      }
1579      else if (cmd_in == MTSETDRVBUFFER)
1580        STp->drv_buffer = (arg & 7);
1581      else if (cmd_in == MTSETDENSITY)
1582        STp->density = arg;
1583      else if (cmd_in == MTEOM) {
1584        STp->eof = ST_EOD;
1585        STp->eof_hit = 0;
1586      }
1587      else if (cmd_in != MTSETBLK && cmd_in != MTNOP) {
1588        STp->eof = ST_NOEOF;
1589        STp->eof_hit = 0;
1590      }
1591    } else {  /* SCSI command was not completely successful */
1592      if (SCpnt->sense_buffer[2] & 0x40) {
1593        if (cmd_in != MTBSF && cmd_in != MTBSFM &&
1594            cmd_in != MTBSR && cmd_in != MTBSS)
1595          STp->eof = ST_EOM_OK;
1596        STp->eof_hit = 0;
1597        STp->drv_block = 0;
1598      }
1599      undone = (
1600           (SCpnt->sense_buffer[3] << 24) +
1601           (SCpnt->sense_buffer[4] << 16) +
1602           (SCpnt->sense_buffer[5] << 8) +
1603           SCpnt->sense_buffer[6] );
1604      if ( (cmd_in == MTFSF) || (cmd_in == MTFSFM) ) {
1605        if (fileno >= 0)
1606          (STp->mt_status)->mt_fileno = fileno - undone ;
1607        else
1608          (STp->mt_status)->mt_fileno = fileno;
1609        STp->drv_block = 0;
1610      }
1611      else if ( (cmd_in == MTBSF) || (cmd_in == MTBSFM) ) {
1612        (STp->mt_status)->mt_fileno = fileno + undone ;
1613        STp->drv_block = 0;
1614      }
1615      else if (cmd_in == MTFSR) {
1616        if (SCpnt->sense_buffer[2] & 0x80) { /* Hit filemark */
1617          (STp->mt_status)->mt_fileno++;
1618          STp->drv_block = 0;
1619        }
1620        else {
1621          if (blkno >= undone)
1622            STp->drv_block = blkno - undone;
1623          else
1624            STp->drv_block = (-1);
1625        }
1626      }
1627      else if (cmd_in == MTBSR) {
1628        if (SCpnt->sense_buffer[2] & 0x80) { /* Hit filemark */
1629          (STp->mt_status)->mt_fileno--;
1630          STp->drv_block = (-1);
1631        }
1632        else {
1633          if (blkno >= 0)
1634            STp->drv_block = blkno + undone;
1635          else
1636            STp->drv_block = (-1);
1637        }
1638      }
1639      else if (cmd_in == MTEOM || cmd_in == MTSEEK) {
1640        (STp->mt_status)->mt_fileno = (-1);
1641        STp->drv_block = (-1);
1642      }
1643      if (STp->eof == ST_NOEOF &&
1644          (SCpnt->sense_buffer[2] & 0x0f) == BLANK_CHECK)
1645        STp->eof = ST_EOD;
1646    }
1647 
1648    return ioctl_result;
1649 }
1650 
1651 
1652 
1653 /* The ioctl command */
1654         static int
1655 st_ioctl(struct inode * inode,struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
1656          unsigned int cmd_in, unsigned long arg)
1657 {
1658    int dev = MINOR(inode->i_rdev);
1659    int i, cmd, result;
1660    struct mtop mtc;
1661    struct mtpos mt_pos;
1662    unsigned char scmd[10];
1663    Scsi_Cmnd *SCpnt;
1664    Scsi_Tape *STp;
1665 
1666    dev = dev & 127;
1667    STp = &(scsi_tapes[dev]);
1668 #ifdef DEBUG
1669    if (debugging && !STp->in_use) {
1670      printk("st%d: Incorrect device.\n", dev);
1671      return (-EIO);
1672    }
1673 #endif
1674 
1675    cmd = cmd_in & IOCCMD_MASK;
1676    if (cmd == (MTIOCTOP & IOCCMD_MASK)) {
1677 
1678      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(mtc))
1679        return (-EINVAL);
1680 
1681      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(mtc));
1682      if (i)
1683         return i;
1684 
1685      memcpy_fromfs((char *) &mtc, (char *)arg, sizeof(struct mtop));
1686 
1687      i = flush_buffer(inode, file, mtc.mt_op == MTSEEK ||
1688                       mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
1689                       mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM);
1690      if (i < 0)
1691        return i;
1692      if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
1693          mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
1694          mtc.mt_op != MTSETDRVBUFFER)
1695        STp->rw = ST_IDLE;  /* Prevent automatic WEOF */
1696 
1697      if (mtc.mt_op == MTSETDRVBUFFER &&
1698          (mtc.mt_count & MT_ST_OPTIONS) != 0)
1699        return st_set_options(inode, mtc.mt_count);
1700      else
1701        return st_int_ioctl(inode, file, mtc.mt_op, mtc.mt_count);
1702    }
1703    else if (cmd == (MTIOCGET & IOCCMD_MASK)) {
1704 
1705      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtget))
1706        return (-EINVAL);
1707      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct mtget));
1708      if (i)
1709        return i;
1710 
1711      (STp->mt_status)->mt_dsreg =
1712        ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
1713        ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
1714      (STp->mt_status)->mt_blkno = STp->drv_block;
1715      if (STp->block_size != 0) {
1716        if (STp->rw == ST_WRITING)
1717          (STp->mt_status)->mt_blkno +=
1718            (STp->buffer)->buffer_bytes / STp->block_size;
1719        else if (STp->rw == ST_READING)
1720          (STp->mt_status)->mt_blkno -= ((STp->buffer)->buffer_bytes +
1721            STp->block_size - 1) / STp->block_size;
1722      }
1723 
1724      (STp->mt_status)->mt_gstat = 0;
1725      if (STp->drv_write_prot)
1726        (STp->mt_status)->mt_gstat |= GMT_WR_PROT(0xffffffff);
1727      if ((STp->mt_status)->mt_blkno == 0) {
1728        if ((STp->mt_status)->mt_fileno == 0)
1729          (STp->mt_status)->mt_gstat |= GMT_BOT(0xffffffff);
1730        else
1731          (STp->mt_status)->mt_gstat |= GMT_EOF(0xffffffff);
1732      }
1733      if (STp->eof == ST_EOM_OK || STp->eof == ST_EOM_ERROR)
1734        (STp->mt_status)->mt_gstat |= GMT_EOT(0xffffffff);
1735      else if (STp->eof == ST_EOD)
1736        (STp->mt_status)->mt_gstat |= GMT_EOD(0xffffffff);
1737      if (STp->density == 1)
1738        (STp->mt_status)->mt_gstat |= GMT_D_800(0xffffffff);
1739      else if (STp->density == 2)
1740        (STp->mt_status)->mt_gstat |= GMT_D_1600(0xffffffff);
1741      else if (STp->density == 3)
1742        (STp->mt_status)->mt_gstat |= GMT_D_6250(0xffffffff);
1743      if (STp->ready == ST_READY)
1744        (STp->mt_status)->mt_gstat |= GMT_ONLINE(0xffffffff);
1745      if (STp->ready == ST_NO_TAPE)
1746        (STp->mt_status)->mt_gstat |= GMT_DR_OPEN(0xffffffff);
1747      if (STp->at_sm)
1748        (STp->mt_status)->mt_gstat |= GMT_SM(0xffffffff);
1749 
1750      memcpy_tofs((char *)arg, (char *)(STp->mt_status),
1751                  sizeof(struct mtget));
1752 
1753      (STp->mt_status)->mt_erreg = 0;  /* Clear after read */
1754      return 0;
1755    }
1756    else if (cmd == (MTIOCPOS & IOCCMD_MASK)) {
1757      if (STp->ready != ST_READY)
1758        return (-EIO);
1759 #ifdef DEBUG
1760      if (debugging)
1761        printk("st%d: get tape position.\n", dev);
1762 #endif
1763      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtpos))
1764        return (-EINVAL);
1765 
1766      i = flush_buffer(inode, file, 0);
1767      if (i < 0)
1768        return i;
1769 
1770      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct mtpos));
1771      if (i)
1772        return i;
1773 
1774      SCpnt = allocate_device(NULL, STp->device, 1);
1775 
1776      SCpnt->sense_buffer[0]=0;
1777      memset (scmd, 0, 10);
1778      if ((STp->device)->scsi_level < SCSI_2) {
1779        scmd[0] = QFA_REQUEST_BLOCK;
1780        scmd[4] = 3;
1781      }
1782      else {
1783        scmd[0] = READ_POSITION;
1784        scmd[1] = 1;
1785      }
1786      SCpnt->request.dev = dev;
1787      SCpnt->sense_buffer[0] = 0;
1788      scsi_do_cmd(SCpnt,
1789                  (void *) scmd, (void *) (STp->buffer)->b_data,
1790                  20, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
1791 
1792      if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
1793      
1794      if ((STp->buffer)->last_result_fatal != 0) {
1795        mt_pos.mt_blkno = (-1);
1796 #ifdef DEBUG
1797        if (debugging)
1798          printk("st%d: Can't read tape position.\n", dev);
1799 #endif
1800        result = (-EIO);
1801      }
1802      else {
1803        result = 0;
1804        if ((STp->device)->scsi_level < SCSI_2)
1805          mt_pos.mt_blkno = ((STp->buffer)->b_data[0] << 16) 
1806            + ((STp->buffer)->b_data[1] << 8) 
1807              + (STp->buffer)->b_data[2];
1808        else
1809          mt_pos.mt_blkno = ((STp->buffer)->b_data[4] << 24)
1810            + ((STp->buffer)->b_data[5] << 16) 
1811              + ((STp->buffer)->b_data[6] << 8) 
1812                + (STp->buffer)->b_data[7];
1813 
1814      }
1815 
1816      SCpnt->request.dev = -1;  /* Mark as not busy */
1817 
1818      memcpy_tofs((char *)arg, (char *) (&mt_pos), sizeof(struct mtpos));
1819      return result;
1820    }
1821    else if (STp->ready == ST_READY)
1822      return scsi_ioctl(STp->device, cmd_in, (void *) arg);
1823    else
1824      return (-EIO);
1825 }
1826 
1827 
1828 /* Set the boot options. Syntax: st=xxx,yyy
1829    where xxx is buffer size in 512 byte blocks and yyy is write threshold
1830    in 512 byte blocks. */
1831         void
1832 st_setup(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
1833 {
1834   if (ints[0] > 0 && ints[1] > 0)
1835     st_buffer_size = ints[1] * ST_BLOCK_SIZE;
1836   if (ints[0] > 1 && ints[2] > 0) {
1837     st_write_threshold = ints[2] * ST_BLOCK_SIZE;
1838     if (st_write_threshold > st_buffer_size)
1839       st_write_threshold = st_buffer_size;
1840   }
1841   if (ints[0] > 2 && ints[3] > 0)
1842     st_max_buffers = ints[3];
1843 }
1844 
1845 
1846 static struct file_operations st_fops = {
1847    NULL,            /* lseek - default */
1848    st_read,         /* read - general block-dev read */
1849    st_write,        /* write - general block-dev write */
1850    NULL,            /* readdir - bad */
1851    NULL,            /* select */
1852    st_ioctl,        /* ioctl */
1853    NULL,            /* mmap */
1854    scsi_tape_open,  /* open */
1855    scsi_tape_close, /* release */
1856    NULL             /* fsync */
1857 };
1858 
1859 static int st_attach(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
1860    Scsi_Tape * tpnt;
1861    int i;
1862 
1863    if(SDp->type != TYPE_TAPE) return 1;
1864 
1865    if(st_template.nr_dev >= st_template.dev_max) 
1866      {
1867         SDp->attached--;
1868         return 1;
1869      }
1870 
1871    for(tpnt = scsi_tapes, i=0; i<st_template.dev_max; i++, tpnt++) 
1872      if(!tpnt->device) break;
1873 
1874    if(i >= st_template.dev_max) panic ("scsi_devices corrupt (st)");
1875 
1876    scsi_tapes[i].device = SDp;
1877    if (SDp->scsi_level <= 2)
1878      scsi_tapes[i].mt_status->mt_type = MT_ISSCSI1;
1879    else
1880      scsi_tapes[i].mt_status->mt_type = MT_ISSCSI2;
1881 
1882    st_template.nr_dev++;
1883    return 0;
1884 };
1885 
1886 static int st_detect(Scsi_Device * SDp)
     /* [previous][next][first][last][top][bottom][index][help] */
1887 {
1888   if(SDp->type != TYPE_TAPE) return 0;
1889 
1890   printk("Detected scsi tape st%d at scsi%d, id %d, lun %d\n", 
1891          st_template.dev_noticed++,
1892          SDp->host->host_no , SDp->id, SDp->lun); 
1893   
1894   return 1;
1895 }
1896 
1897 /* Driver initialization */
1898 static void st_init()
     /* [previous][next][first][last][top][bottom][index][help] */
1899 {
1900   int i;
1901   Scsi_Tape * STp;
1902   static int st_registered = 0;
1903 
1904   if (st_template.dev_noticed == 0) return;
1905 
1906   if(!st_registered) {
1907     if (register_chrdev(MAJOR_NR,"st",&st_fops)) {
1908       printk("Unable to get major %d for SCSI tapes\n",MAJOR_NR);
1909       return;
1910     }
1911     st_registered++;
1912   }
1913 
1914   if (scsi_tapes) return;
1915   scsi_tapes = (Scsi_Tape *) scsi_init_malloc(
1916                 (st_template.dev_noticed + ST_EXTRA_DEVS) * 
1917                                               sizeof(Scsi_Tape), GFP_ATOMIC);
1918   st_template.dev_max = st_template.dev_noticed + ST_EXTRA_DEVS;
1919 
1920 #ifdef DEBUG
1921   printk("st: Buffer size %d bytes, write threshold %d bytes.\n",
1922          st_buffer_size, st_write_threshold);
1923 #endif
1924 
1925   for (i=0; i < st_template.dev_max; ++i) {
1926     STp = &(scsi_tapes[i]);
1927     STp->device = NULL;
1928     STp->capacity = 0xfffff;
1929     STp->dirty = 0;
1930     STp->rw = ST_IDLE;
1931     STp->eof = ST_NOEOF;
1932     STp->waiting = NULL;
1933     STp->in_use = 0;
1934     STp->drv_buffer = 1;  /* Try buffering if no mode sense */
1935     STp->density = 0;
1936     STp->do_buffer_writes = ST_BUFFER_WRITES;
1937     STp->do_async_writes = ST_ASYNC_WRITES;
1938     STp->do_read_ahead = ST_READ_AHEAD;
1939     STp->two_fm = ST_TWO_FM;
1940     STp->fast_mteom = ST_FAST_MTEOM;
1941     STp->write_threshold = st_write_threshold;
1942     STp->drv_block = 0;
1943     STp->moves_after_eof = 1;
1944     STp->at_sm = 0;
1945     STp->mt_status = (struct mtget *) scsi_init_malloc(sizeof(struct mtget), GFP_ATOMIC);
1946     /* Initialize status */
1947     memset((void *) scsi_tapes[i].mt_status, 0, sizeof(struct mtget));
1948   }
1949 
1950   /* Allocate the buffers */
1951   st_nbr_buffers = st_template.dev_noticed + ST_EXTRA_DEVS;
1952   if (st_nbr_buffers > st_max_buffers)
1953     st_nbr_buffers = st_max_buffers;
1954   st_buffers = (ST_buffer **) scsi_init_malloc(st_nbr_buffers * 
1955                                                sizeof(ST_buffer *), GFP_ATOMIC);
1956   /* FIXME - if we are hitting this because we are loading a tape module
1957   as a loadable driver, we should not use kmalloc - it will allocate
1958   a 64Kb region in order to buffer about 32Kb.  Try using 31 blocks
1959   instead. */
1960   
1961   for (i=0; i < st_nbr_buffers; i++) {
1962     st_buffers[i] = (ST_buffer *) scsi_init_malloc(sizeof(ST_buffer) - 
1963                                                    1 + st_buffer_size, GFP_ATOMIC | GFP_DMA);
1964 #ifdef DEBUG
1965 /*    printk("st: Buffer address: %p\n", st_buffers[i]); */
1966 #endif
1967     st_buffers[i]->in_use = 0;
1968     st_buffers[i]->writing = 0;
1969   }
1970   return;
1971 }
1972 
1973 static void st_detach(Scsi_Device * SDp)
     /* [previous][next][first][last][top][bottom][index][help] */
1974 {
1975   Scsi_Tape * tpnt;
1976   int i;
1977   
1978   for(tpnt = scsi_tapes, i=0; i<st_template.dev_max; i++, tpnt++) 
1979     if(tpnt->device == SDp) {
1980       tpnt->device = NULL;
1981       SDp->attached--;
1982       st_template.nr_dev--;
1983       st_template.dev_noticed--;
1984       return;
1985     }
1986   return;
1987 }

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