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

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