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. st_do_scsi
  4. write_behind_check
  5. back_over_eof
  6. flush_write_buffer
  7. flush_buffer
  8. scsi_tape_open
  9. scsi_tape_close
  10. st_write
  11. st_read
  12. st_set_options
  13. st_int_ioctl
  14. st_ioctl
  15. new_tape_buffer
  16. enlarge_buffer
  17. normalize_buffer
  18. st_setup
  19. st_attach
  20. st_detect
  21. st_init
  22. st_detach
  23. init_module
  24. cleanup_module

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

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