root/drivers/scsi/st.c

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

DEFINITIONS

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

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

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