root/drivers/scsi/st.c

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

DEFINITIONS

This source file includes following definitions.
  1. st_chk_result
  2. st_sleep_done
  3. write_behind_check
  4. back_over_eof
  5. flush_write_buffer
  6. flush_buffer
  7. scsi_tape_open
  8. scsi_tape_close
  9. st_write
  10. st_read
  11. st_set_options
  12. st_int_ioctl
  13. st_ioctl
  14. st_setup
  15. st_attach
  16. st_detect
  17. st_init

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

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