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

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