root/drivers/scsi/st.c

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

DEFINITIONS

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

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

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