This source file includes following definitions.
- st_chk_result
 
- st_sleep_done
 
- write_behind_check
 
- flush_write_buffer
 
- flush_buffer
 
- scsi_tape_open
 
- scsi_tape_close
 
- st_write
 
- st_read
 
- st_int_ioctl
 
- st_ioctl
 
- st_attach
 
- st_init1
 
- st_init
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 #include <linux/fs.h>
  43 #include <linux/kernel.h>
  44 #include <linux/sched.h>
  45 #include <linux/string.h>
  46 #include <linux/errno.h>
  47 #include <linux/mtio.h>
  48 #include <linux/ioctl.h>
  49 #include <linux/fcntl.h>
  50 #include <asm/segment.h>
  51 #include <asm/system.h>
  52 
  53 #define MAJOR_NR SCSI_TAPE_MAJOR
  54 #include "../block/blk.h"
  55 #include "scsi.h"
  56 #include "scsi_ioctl.h"
  57 #include "st.h"
  58 #include "constants.h"
  59 
  60 
  61 
  62 
  63 
  64 
  65 
  66 
  67 
  68 
  69 
  70 
  71 
  72 
  73 
  74 
  75 
  76 
  77 
  78 #define ST_BUFFER_BLOCKS 64
  79 
  80 
  81 #define ST_WRITE_THRESHOLD_BLOCKS 60
  82 #define ST_BLOCK_SIZE 512
  83 #define ST_BUFFER_SIZE (ST_BUFFER_BLOCKS * ST_BLOCK_SIZE)
  84 #define ST_WRITE_THRESHOLD (ST_WRITE_THRESHOLD_BLOCKS * ST_BLOCK_SIZE)
  85 
  86 #ifdef ST_NO_DELAYED_WRITES
  87 #undef ST_WRITE_THRESHOLD_BLOCKS
  88 #define ST_WRITE_THRESHOLD_BLOCKS ST_BUFFER_BLOCKS
  89 #endif
  90 
  91 
  92 
  93 #if ST_BUFFER_SIZE >= (2 << 24 - 1)
  94 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
  95 #endif
  96 
  97 
  98 
  99 #define MAX_RETRIES 0
 100 #define MAX_READY_RETRIES 5
 101 #define NO_TAPE  NOT_READY
 102 
 103 #define ST_TIMEOUT 9000
 104 #define ST_LONG_TIMEOUT 200000
 105 
 106 static int st_nbr_buffers;
 107 static ST_buffer *st_buffers[2];
 108 
 109 static Scsi_Tape * scsi_tapes;
 110 int NR_ST=0;
 111 int MAX_ST=0;
 112 
 113 static int st_int_ioctl(struct inode * inode,struct file * file,
 114              unsigned int cmd_in, unsigned long arg);
 115 
 116 
 117 
 118 
 119 
 120         static int
 121 st_chk_result(Scsi_Cmnd * SCpnt)
     
 122 {
 123   int dev = SCpnt->request.dev;
 124   int result = SCpnt->result;
 125   unsigned char * sense = SCpnt->sense_buffer;
 126   char *stp;
 127 
 128   if (!result && SCpnt->sense_buffer[0] == 0)
 129     return 0;
 130 #ifdef DEBUG
 131   printk("st%d: Error: %x\n", dev, result);
 132   print_sense("st", SCpnt);
 133 #endif
 134 
 135 
 136 
 137   if ((sense[0] & 0x70) == 0x70 &&
 138       sense[2] == RECOVERED_ERROR
 139 #ifdef ST_RECOVERED_WRITE_FATAL
 140       && SCpnt->cmnd[0] != WRITE_6
 141       && SCpnt->cmnd[0] != WRITE_FILEMARKS
 142 #endif
 143       ) {
 144     scsi_tapes[dev].recover_count++;
 145     if (SCpnt->cmnd[0] == READ_6)
 146       stp = "read";
 147     else if (SCpnt->cmnd[0] == WRITE_6)
 148       stp = "write";
 149     else
 150       stp = "ioctl";
 151     printk("st%d: Recovered %s error (%d).\n", dev, stp,
 152            scsi_tapes[dev].recover_count);
 153     return 0;
 154   }
 155   return (-EIO);
 156 }
 157 
 158 
 159 
 160         static void
 161 st_sleep_done (Scsi_Cmnd * SCpnt)
     
 162 {
 163   int st_nbr, remainder;
 164   Scsi_Tape * STp;
 165 
 166   if ((st_nbr = SCpnt->request.dev) < NR_ST && st_nbr >= 0) {
 167     STp = &(scsi_tapes[st_nbr]);
 168     if ((STp->buffer)->writing &&
 169         (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 170         (SCpnt->sense_buffer[2] & 0x40)) {
 171       
 172       if ((SCpnt->sense_buffer[0] & 0x80) != 0)
 173         remainder = (SCpnt->sense_buffer[3] << 24) |
 174               (SCpnt->sense_buffer[4] << 16) |
 175                 (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];
 176       else
 177         remainder = 0;
 178       if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW ||
 179           remainder > 0)
 180         (STp->buffer)->last_result = SCpnt->result; 
 181       else
 182         (STp->buffer)->last_result = INT_MAX; 
 183     }
 184     else
 185       (STp->buffer)->last_result = SCpnt->result;
 186     (STp->buffer)->last_result_fatal = st_chk_result(SCpnt);
 187     if ((STp->buffer)->writing)
 188       SCpnt->request.dev = -1;
 189     else
 190       SCpnt->request.dev = 0xffff;
 191     if ((STp->buffer)->writing <= 0)
 192       wake_up( &(STp->waiting) );
 193   }
 194 #ifdef DEBUG
 195   else
 196     printk("st?: Illegal interrupt device %x\n", st_nbr);
 197 #endif
 198 }
 199 
 200 
 201 #if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
 202 
 203         static void
 204 write_behind_check(int dev)
     
 205 {
 206   Scsi_Tape * STp;
 207   ST_buffer * STbuffer;
 208 
 209   STp = &(scsi_tapes[dev]);
 210   STbuffer = STp->buffer;
 211 
 212   cli();
 213   if (STbuffer->last_result < 0) {
 214     STbuffer->writing = (- STbuffer->writing);
 215     sleep_on( &(STp->waiting) );
 216     STbuffer->writing = (- STbuffer->writing);
 217   }
 218   sti();
 219 
 220   if (STbuffer->writing < STbuffer->buffer_bytes)
 221     memcpy(STbuffer->b_data,
 222            STbuffer->b_data + STbuffer->writing,
 223            STbuffer->buffer_bytes - STbuffer->writing);
 224   STbuffer->buffer_bytes -= STbuffer->writing;
 225   STbuffer->writing = 0;
 226 
 227   return;
 228 }
 229 #endif
 230 
 231 
 232 
 233         static int
 234 flush_write_buffer(int dev)
     
 235 {
 236   int offset, transfer, blks;
 237   int result;
 238   unsigned char cmd[10];
 239   Scsi_Cmnd *SCpnt;
 240   Scsi_Tape *STp = &(scsi_tapes[dev]);
 241 
 242 #if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
 243   if ((STp->buffer)->writing) {
 244     write_behind_check(dev);
 245     if ((STp->buffer)->last_result_fatal) {
 246 #ifdef DEBUG
 247       printk("st%d: Async write error %x.\n", dev,
 248              (STp->buffer)->last_result);
 249 #endif
 250       if ((STp->buffer)->last_result == INT_MAX)
 251         return (-ENOSPC);
 252       return (-EIO);
 253     }
 254   }
 255 #endif
 256 
 257   result = 0;
 258   if (STp->dirty == 1) {
 259     SCpnt = allocate_device(NULL, (STp->device)->index, 1);
 260 
 261     offset = (STp->buffer)->buffer_bytes;
 262     transfer = ((offset + STp->block_size - 1) /
 263                 STp->block_size) * STp->block_size;
 264 #ifdef DEBUG
 265     printk("st%d: Flushing %d bytes.\n", dev, transfer);
 266 #endif
 267     memset((STp->buffer)->b_data + offset, 0, transfer - offset);
 268 
 269     SCpnt->sense_buffer[0] = 0;
 270     memset(cmd, 0, 10);
 271     cmd[0] = WRITE_6;
 272     cmd[1] = 1;
 273     blks = transfer / STp->block_size;
 274     cmd[2] = blks >> 16;
 275     cmd[3] = blks >> 8;
 276     cmd[4] = blks;
 277     SCpnt->request.dev = dev;
 278     scsi_do_cmd (SCpnt,
 279                  (void *) cmd, (STp->buffer)->b_data, transfer,
 280                  st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 281 
 282     if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 283 
 284     if ((STp->buffer)->last_result_fatal != 0) {
 285       printk("st%d: Error on flush.\n", dev);
 286       if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 287           (SCpnt->sense_buffer[2] & 0x40) &&
 288           (SCpnt->sense_buffer[2] & 0x0f) != VOLUME_OVERFLOW) {
 289         STp->dirty = 0;
 290         (STp->buffer)->buffer_bytes = 0;
 291         result = (-ENOSPC);
 292       }
 293       else
 294         result = (-EIO);
 295     }
 296     else {
 297       STp->dirty = 0;
 298       (STp->buffer)->buffer_bytes = 0;
 299     }
 300     SCpnt->request.dev = -1;  
 301   }
 302   return result;
 303 }
 304 
 305 
 306 
 307 
 308         static int
 309 flush_buffer(struct inode * inode, struct file * filp, int seek_next)
     
 310 {
 311   int dev;
 312   int backspace, result;
 313   Scsi_Tape * STp;
 314   ST_buffer * STbuffer;
 315 
 316   dev = MINOR(inode->i_rdev) & 127;
 317   STp = &(scsi_tapes[dev]);
 318   STbuffer = STp->buffer;
 319 
 320   if (STp->rw == ST_WRITING)  
 321     return flush_write_buffer(dev);
 322 
 323   if (STp->block_size == 0)
 324     return 0;
 325 
 326   backspace = ((STp->buffer)->buffer_bytes +
 327     (STp->buffer)->read_pointer) / STp->block_size -
 328       ((STp->buffer)->read_pointer + STp->block_size - 1) /
 329         STp->block_size;
 330   (STp->buffer)->buffer_bytes = 0;
 331   (STp->buffer)->read_pointer = 0;
 332   result = 0;
 333   if (!seek_next) {
 334     if ((STp->eof == ST_FM) && !STp->eof_hit) {
 335       result = st_int_ioctl(inode, filp, MTBSF, 1); 
 336       if (!result) {
 337         STp->eof = ST_NOEOF;
 338         STp->eof_hit = 0;
 339       }
 340     }
 341     if (!result && backspace > 0)
 342       result = st_int_ioctl(inode, filp, MTBSR, backspace);
 343   }
 344   return result;
 345 
 346 }
 347 
 348 
 349 
 350         static int
 351 scsi_tape_open(struct inode * inode, struct file * filp)
     
 352 {
 353     int dev;
 354     unsigned short flags;
 355     int i;
 356     unsigned char cmd[10];
 357     Scsi_Cmnd * SCpnt;
 358     Scsi_Tape * STp;
 359 
 360     dev = MINOR(inode->i_rdev) & 127;
 361     if (dev >= NR_ST)
 362       return (-ENODEV);
 363     STp = &(scsi_tapes[dev]);
 364     if (STp->in_use) {
 365       printk("st%d: Device already in use.\n", dev);
 366       return (-EBUSY);
 367     }
 368 
 369     
 370     for (i=0; i < st_nbr_buffers; i++)
 371       if (!st_buffers[i]->in_use)
 372         break;
 373     if (i >= st_nbr_buffers) {
 374       printk("st%d: No free buffers.\n", dev);
 375       return (-EBUSY);
 376     }
 377     STp->buffer = st_buffers[i];
 378     (STp->buffer)->in_use = 1;
 379     (STp->buffer)->writing = 0;
 380     STp->in_use = 1;
 381 
 382     flags = filp->f_flags;
 383     STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
 384 
 385     STp->dirty = 0;
 386     STp->rw = ST_IDLE;
 387     STp->eof = ST_NOEOF;
 388     STp->eof_hit = 0;
 389     STp->recover_count = 0;
 390 
 391     SCpnt = allocate_device(NULL, (STp->device)->index, 1);
 392     if (!SCpnt) {
 393       printk("st%d: Tape request not allocated", dev);
 394       return (-EBUSY);
 395     }
 396 
 397     SCpnt->sense_buffer[0]=0;
 398     memset ((void *) &cmd[0], 0, 10);
 399     cmd[0] = TEST_UNIT_READY;
 400     SCpnt->request.dev = dev;
 401     scsi_do_cmd(SCpnt,
 402                 (void *) cmd, (void *) (STp->buffer)->b_data,
 403                 ST_BLOCK_SIZE, st_sleep_done, ST_LONG_TIMEOUT,
 404                 MAX_READY_RETRIES);
 405 
 406     if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 407 
 408     if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 409         (SCpnt->sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { 
 410       SCpnt->sense_buffer[0]=0;
 411       memset ((void *) &cmd[0], 0, 10);
 412       cmd[0] = TEST_UNIT_READY;
 413       SCpnt->request.dev = dev;
 414       scsi_do_cmd(SCpnt,
 415                   (void *) cmd, (void *) (STp->buffer)->b_data,
 416                   ST_BLOCK_SIZE, st_sleep_done, ST_LONG_TIMEOUT,
 417                   MAX_READY_RETRIES);
 418 
 419       if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 420     }
 421 
 422     if ((STp->buffer)->last_result_fatal != 0) {
 423       if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 424           (SCpnt->sense_buffer[2] & 0x0f) == NO_TAPE)
 425         printk("st%d: No tape.\n", dev);
 426       else
 427         printk("st%d: Error %x.\n", dev, SCpnt->result);
 428       (STp->buffer)->in_use = 0;
 429       STp->in_use = 0;
 430       SCpnt->request.dev = -1;  
 431       return (-EIO);
 432     }
 433 
 434     SCpnt->sense_buffer[0]=0;
 435     memset ((void *) &cmd[0], 0, 10);
 436     cmd[0] = READ_BLOCK_LIMITS;
 437     SCpnt->request.dev = dev;
 438     scsi_do_cmd(SCpnt,
 439                 (void *) cmd, (void *) (STp->buffer)->b_data,
 440                 ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
 441 
 442     if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 443 
 444     if (!SCpnt->result && !SCpnt->sense_buffer[0]) {
 445       STp->max_block = ((STp->buffer)->b_data[1] << 16) |
 446         ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
 447       STp->min_block = ((STp->buffer)->b_data[4] << 8) |
 448         (STp->buffer)->b_data[5];
 449 #ifdef DEBUG
 450       printk("st%d: Block limits %d - %d bytes.\n", dev, STp->min_block,
 451              STp->max_block);
 452 #endif
 453     }
 454     else {
 455       STp->min_block = STp->max_block = (-1);
 456 #ifdef DEBUG
 457       printk("st%d: Can't read block limits.\n", dev);
 458 #endif
 459     }
 460 
 461     SCpnt->sense_buffer[0]=0;
 462     memset ((void *) &cmd[0], 0, 10);
 463     cmd[0] = MODE_SENSE;
 464     cmd[4] = 12;
 465     SCpnt->request.dev = dev;
 466     scsi_do_cmd(SCpnt,
 467                 (void *) cmd, (void *) (STp->buffer)->b_data,
 468                 ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
 469 
 470     if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 471 
 472     if ((STp->buffer)->last_result_fatal != 0) {
 473 #ifdef DEBUG
 474       printk("st%d: No Mode Sense.\n", dev);
 475 #endif
 476       (STp->buffer)->b_data[2] =
 477       (STp->buffer)->b_data[3] = 0;
 478     }
 479     SCpnt->request.dev = -1;  
 480 
 481 #ifdef DEBUG
 482     printk("st%d: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n", dev,
 483            (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
 484            (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]);
 485 #endif
 486 
 487     if ((STp->buffer)->b_data[3] >= 8) {
 488       STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
 489       STp->density = (STp->buffer)->b_data[4];
 490       STp->block_size = (STp->buffer)->b_data[9] * 65536 +
 491         (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
 492 #ifdef DEBUG
 493       printk(
 494         "st%d: Density %x, tape length: %x, blocksize: %d, drv buffer: %d\n",
 495              dev, STp->density, (STp->buffer)->b_data[5] * 65536 +
 496              (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
 497              STp->block_size, STp->drv_buffer);
 498 #endif
 499       if (STp->block_size > ST_BUFFER_SIZE) {
 500         printk("st%d: Blocksize %d too large for buffer.\n", dev,
 501                STp->block_size);
 502         (STp->buffer)->in_use = 0;
 503         STp->in_use = 0;
 504         return (-EIO);
 505       }
 506 
 507     }
 508     else
 509       STp->block_size = ST_BLOCK_SIZE;
 510 
 511     if (STp->block_size > 0) {
 512       (STp->buffer)->buffer_blocks = ST_BUFFER_SIZE / STp->block_size;
 513       (STp->buffer)->buffer_size =
 514         (STp->buffer)->buffer_blocks * STp->block_size;
 515     }
 516     else {
 517       (STp->buffer)->buffer_blocks = 1;
 518       (STp->buffer)->buffer_size = ST_BUFFER_SIZE;
 519     }
 520     (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
 521 
 522 #ifdef DEBUG
 523     printk("st%d: Block size: %d, buffer size: %d (%d blocks).\n", dev,
 524            STp->block_size, (STp->buffer)->buffer_size,
 525            (STp->buffer)->buffer_blocks);
 526 #endif
 527 
 528     if ((STp->buffer)->b_data[2] & 0x80) {
 529       STp->write_prot = 1;
 530 #ifdef DEBUG
 531       printk( "st%d: Write protected\n", dev);
 532 #endif
 533     }
 534 
 535     return 0;
 536 }
 537 
 538 
 539 
 540         static void
 541 scsi_tape_close(struct inode * inode, struct file * filp)
     
 542 {
 543     int dev;
 544     int result;
 545     int rewind;
 546     static unsigned char cmd[10];
 547     Scsi_Cmnd * SCpnt;
 548     Scsi_Tape * STp;
 549    
 550     dev = MINOR(inode->i_rdev);
 551     rewind = (dev & 0x80) == 0;
 552     dev = dev & 127;
 553     STp = &(scsi_tapes[dev]);
 554 
 555     if ( STp->rw == ST_WRITING) {
 556 
 557       result = flush_write_buffer(dev);
 558 
 559 #ifdef DEBUG
 560       printk("st%d: File length %d bytes.\n", dev, filp->f_pos);
 561 #endif
 562 
 563       if (result == 0 || result == (-ENOSPC)) {
 564         SCpnt = allocate_device(NULL, (STp->device)->index, 1);
 565 
 566         SCpnt->sense_buffer[0] = 0;
 567         memset(cmd, 0, 10);
 568         cmd[0] = WRITE_FILEMARKS;
 569         cmd[4] = 1;
 570         SCpnt->request.dev = dev;
 571         scsi_do_cmd( SCpnt,
 572                     (void *) cmd, (void *) (STp->buffer)->b_data,
 573                     ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 574 
 575         if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 576 
 577         if ((STp->buffer)->last_result_fatal != 0)
 578           printk("st%d: Error on write filemark.\n", dev);
 579 
 580         SCpnt->request.dev = -1;  
 581       }
 582 
 583 #ifdef DEBUG
 584       printk("st%d: Buffer flushed, EOF written\n", dev);
 585 #endif
 586     }
 587     else if (!rewind) {
 588 #ifndef ST_IN_FILE_POS
 589       if ((STp->eof == ST_FM) && !STp->eof_hit)
 590         st_int_ioctl(inode, filp, MTBSF, 1); 
 591 #else
 592       flush_buffer(inode, filp, 0);
 593 #endif
 594     }
 595 
 596     if (rewind)
 597       st_int_ioctl(inode, filp, MTREW, 1);
 598 
 599     (STp->buffer)->in_use = 0;
 600     STp->in_use = 0;
 601 
 602     return;
 603 }
 604 
 605 
 606 
 607         static int
 608 st_write(struct inode * inode, struct file * filp, char * buf, int count)
     
 609 {
 610     int dev;
 611     int total, do_count, blks, retval, transfer;
 612     int write_threshold;
 613     static unsigned char cmd[10];
 614     char *b_point;
 615     Scsi_Cmnd * SCpnt;
 616     Scsi_Tape * STp;
 617 
 618     dev = MINOR(inode->i_rdev) & 127;
 619     STp = &(scsi_tapes[dev]);
 620 #ifdef DEBUG
 621     if (!STp->in_use) {
 622       printk("st%d: Incorrect device.\n", dev);
 623       return (-EIO);
 624     }
 625 #endif
 626 
 627     if (STp->write_prot)
 628       return (-EACCES);
 629 
 630     if (STp->block_size == 0 && count > ST_BUFFER_SIZE)
 631       return (-EOVERFLOW);
 632 
 633     if (STp->rw == ST_READING) {
 634       retval = flush_buffer(inode, filp, 0);
 635       if (retval)
 636         return retval;
 637       STp->rw = ST_WRITING;
 638     }
 639 
 640 #if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
 641     if ((STp->buffer)->writing) {
 642       write_behind_check(dev);
 643       if ((STp->buffer)->last_result_fatal) {
 644 #ifdef DEBUG
 645         printk("st%d: Async write error %x.\n", dev,
 646                (STp->buffer)->last_result);
 647 #endif
 648         if ((STp->buffer)->last_result == INT_MAX) {
 649           retval = (-ENOSPC);  
 650           STp->eof = ST_EOM_OK;
 651         }
 652         else
 653           retval = (-EIO);
 654         return retval;
 655       }
 656     }
 657 #endif
 658 
 659     if (STp->eof == ST_EOM_OK)
 660       return (-ENOSPC);
 661     else if (STp->eof == ST_EOM_ERROR)
 662       return (-EIO);
 663 
 664 #ifdef ST_NO_DELAYED_WRITES
 665     if (STp->block_size != 0 && (count % STp->block_size) != 0)
 666       return (-EIO);   
 667     write_threshold = 1;
 668 #else
 669     write_threshold = (STp->buffer)->buffer_size;
 670 #endif
 671 
 672     SCpnt = allocate_device(NULL, (STp->device)->index, 1);
 673 
 674     total = count;
 675 
 676     memset(cmd, 0, 10);
 677     cmd[0] = WRITE_6;
 678     cmd[1] = (STp->block_size != 0);
 679 
 680     STp->rw = ST_WRITING;
 681 
 682     b_point = buf;
 683     while(
 684 #if ST_WRITE_THRESHOLD_BLOCKS  < ST_BUFFER_BLOCKS
 685           STp->block_size != 0 &&
 686           ((STp->buffer)->buffer_bytes + count) >
 687           write_threshold)
 688 #else
 689           (STp->block_size == 0 && count > 0) ||
 690           ((STp->buffer)->buffer_bytes + count) >=
 691           write_threshold)
 692 #endif
 693     {
 694       if (STp->block_size == 0)
 695         do_count = count;
 696       else {
 697         do_count = (STp->buffer)->buffer_size - (STp->buffer)->buffer_bytes;
 698         if (do_count > count)
 699           do_count = count;
 700       }
 701       memcpy_fromfs((STp->buffer)->b_data +
 702                     (STp->buffer)->buffer_bytes, b_point, do_count);
 703 
 704       if (STp->block_size == 0)
 705         blks = do_count;
 706       else
 707         blks = ((STp->buffer)->buffer_bytes + do_count) /
 708           STp->block_size;
 709       cmd[2] = blks >> 16;
 710       cmd[3] = blks >> 8;
 711       cmd[4] = blks;
 712       SCpnt->sense_buffer[0] = 0;
 713       SCpnt->request.dev = dev;
 714       scsi_do_cmd (SCpnt,
 715                    (void *) cmd, (STp->buffer)->b_data,
 716                    (STp->buffer)->buffer_size,
 717                    st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 718 
 719       if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 720 
 721       if ((STp->buffer)->last_result_fatal != 0) {
 722 #ifdef DEBUG
 723         printk("st%d: Error on write:\n", dev);
 724 #endif
 725         if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 726             (SCpnt->sense_buffer[2] & 0x40)) {
 727           if (STp->block_size != 0 && (SCpnt->sense_buffer[0] & 0x80) != 0)
 728             transfer = (SCpnt->sense_buffer[3] << 24) |
 729               (SCpnt->sense_buffer[4] << 16) |
 730                 (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];
 731           else if (STp->block_size == 0 &&
 732                    (SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
 733             transfer = do_count;
 734           else
 735             transfer = 0;
 736           if (STp->block_size != 0)
 737             transfer *= STp->block_size;
 738           if (transfer <= do_count) {
 739             filp->f_pos += do_count - transfer;
 740             count -= do_count - transfer;
 741             STp->eof = ST_EOM_OK;
 742             retval = (-ENOSPC); 
 743 #ifdef DEBUG
 744             printk("st%d: EOM with %d bytes unwritten.\n",
 745                    dev, transfer);
 746 #endif
 747           }
 748           else {
 749             STp->eof = ST_EOM_ERROR;
 750             retval = (-EIO); 
 751 #ifdef DEBUG
 752             printk("st%d: EOM with lost data.\n", dev);
 753 #endif
 754           }
 755         }
 756         else
 757           retval = (-EIO);
 758 
 759         SCpnt->request.dev = -1;  
 760         (STp->buffer)->buffer_bytes = 0;
 761         STp->dirty = 0;
 762         if (count < total)
 763           return total - count;
 764         else
 765           return retval;
 766       }
 767       filp->f_pos += do_count;
 768       b_point += do_count;
 769       count -= do_count;
 770       (STp->buffer)->buffer_bytes = 0;
 771       STp->dirty = 0;
 772     }
 773     if (count != 0) {
 774       STp->dirty = 1;
 775       memcpy_fromfs((STp->buffer)->b_data +
 776                     (STp->buffer)->buffer_bytes,b_point,count);
 777       filp->f_pos += count;
 778       (STp->buffer)->buffer_bytes += count;
 779       count = 0;
 780     }
 781 
 782     if ((STp->buffer)->last_result_fatal != 0) {
 783       SCpnt->request.dev = -1;
 784       return (STp->buffer)->last_result_fatal;
 785     }
 786 
 787 #if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
 788     if ((STp->buffer)->buffer_bytes >= ST_WRITE_THRESHOLD ||
 789         STp->block_size == 0) {
 790       
 791       if (STp->block_size == 0)
 792         (STp->buffer)->writing = (STp->buffer)->buffer_bytes;
 793       else
 794         (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
 795           STp->block_size) * STp->block_size;
 796       STp->dirty = 0;
 797 
 798       if (STp->block_size == 0)
 799         blks = (STp->buffer)->writing;
 800       else
 801         blks = (STp->buffer)->writing / STp->block_size;
 802       cmd[2] = blks >> 16;
 803       cmd[3] = blks >> 8;
 804       cmd[4] = blks;
 805       SCpnt->result = (STp->buffer)->last_result = -1;
 806       SCpnt->sense_buffer[0] = 0;
 807       SCpnt->request.dev = dev;
 808       scsi_do_cmd (SCpnt,
 809                    (void *) cmd, (STp->buffer)->b_data,
 810                    (STp->buffer)->writing,
 811                    st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 812     }
 813     else
 814 #endif
 815       SCpnt->request.dev = -1;  
 816 
 817     return( total);
 818 }   
 819 
 820 
 821 
 822         static int
 823 st_read(struct inode * inode, struct file * filp, char * buf, int count)
     
 824 {
 825     int dev;
 826     int total;
 827     int transfer, blks, bytes;
 828     static unsigned char cmd[10];
 829     Scsi_Cmnd * SCpnt;
 830     Scsi_Tape * STp;
 831 
 832     dev = MINOR(inode->i_rdev) & 127;
 833     STp = &(scsi_tapes[dev]);
 834 #ifdef DEBUG
 835     if (!STp->in_use) {
 836       printk("st%d: Incorrect device.\n", dev);
 837       return (-EIO);
 838     }
 839 #endif
 840 
 841     if (STp->block_size == 0 && count > ST_BUFFER_SIZE)
 842       return (-EOVERFLOW);
 843 
 844     if (STp->rw == ST_WRITING) {
 845       transfer = flush_buffer(inode, filp, 0);
 846       if (transfer)
 847         return transfer;
 848       STp->rw = ST_READING;
 849     }
 850 
 851 #ifdef DEBUG
 852     if (STp->eof != ST_NOEOF)
 853       printk("st%d: EOF flag up. Bytes %d\n", dev,
 854              (STp->buffer)->buffer_bytes);
 855 #endif
 856     if (((STp->buffer)->buffer_bytes == 0) &&
 857         STp->eof == ST_EOM_OK)  
 858       return (-EIO);
 859 
 860     STp->rw = ST_READING;
 861 
 862     SCpnt = allocate_device(NULL, (STp->device)->index, 1);
 863 
 864     for (total = 0; total < count; ) {
 865 
 866       if ((STp->buffer)->buffer_bytes == 0 &&
 867           STp->eof == ST_NOEOF) {
 868 
 869         memset(cmd, 0, 10);
 870         cmd[0] = READ_6;
 871         cmd[1] = (STp->block_size != 0);
 872         if (STp->block_size == 0)
 873           blks = bytes = count;
 874         else {
 875           blks = (STp->buffer)->buffer_blocks;
 876           bytes = blks * STp->block_size;
 877         }
 878         cmd[2] = blks >> 16;
 879         cmd[3] = blks >> 8;
 880         cmd[4] = blks;
 881 
 882         SCpnt->sense_buffer[0] = 0;
 883         SCpnt->request.dev = dev;
 884         scsi_do_cmd (SCpnt,
 885                      (void *) cmd, (STp->buffer)->b_data,
 886                      (STp->buffer)->buffer_size,
 887                      st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
 888 
 889         if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 890 
 891         (STp->buffer)->read_pointer = 0;
 892         STp->eof_hit = 0;
 893 
 894         if ((STp->buffer)->last_result_fatal) {
 895 #ifdef DEBUG
 896           printk("st%d: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", dev,
 897                  SCpnt->sense_buffer[0], SCpnt->sense_buffer[1],
 898                  SCpnt->sense_buffer[2], SCpnt->sense_buffer[3],
 899                  SCpnt->sense_buffer[4], SCpnt->sense_buffer[5],
 900                  SCpnt->sense_buffer[6], SCpnt->sense_buffer[7]);
 901 #endif
 902           if ((SCpnt->sense_buffer[0] & 0x70) == 0x70) { 
 903 
 904             if ((SCpnt->sense_buffer[2] & 0xe0) != 0) { 
 905 
 906               if ((SCpnt->sense_buffer[0] & 0x80) != 0)
 907                 transfer = (SCpnt->sense_buffer[3] << 24) |
 908                   (SCpnt->sense_buffer[4] << 16) |
 909                     (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];
 910               else
 911                 transfer = 0;
 912               if (STp->block_size == 0 &&
 913                   (SCpnt->sense_buffer[2] & 0x0f) == MEDIUM_ERROR)
 914                 transfer = bytes;
 915 
 916               if (SCpnt->sense_buffer[2] & 0x20) {
 917                 if (STp->block_size == 0) {
 918                   if (transfer <= 0)
 919                     transfer = 0;
 920                   (STp->buffer)->buffer_bytes = count - transfer;
 921                 }
 922                 else {
 923                   printk("st%d: Incorrect block size.\n", dev);
 924                   SCpnt->request.dev = -1;  
 925                   return (-EIO);
 926                 }
 927               }
 928               else if (SCpnt->sense_buffer[2] & 0x40) {
 929                 STp->eof = ST_EOM_OK;
 930                 if (STp->block_size == 0)
 931                   (STp->buffer)->buffer_bytes = count - transfer;
 932                 else
 933                   (STp->buffer)->buffer_bytes =
 934                     ((STp->buffer)->buffer_blocks - transfer) *
 935                       STp->block_size;
 936 #ifdef DEBUG
 937                 printk("st%d: EOM detected (%d bytes read).\n", dev,
 938                        (STp->buffer)->buffer_bytes);
 939 #endif
 940               }
 941               else if (SCpnt->sense_buffer[2] & 0x80) {
 942                 STp->eof = ST_FM;
 943                 if (STp->block_size == 0)
 944                   (STp->buffer)->buffer_bytes = 0;
 945                 else
 946                   (STp->buffer)->buffer_bytes =
 947                     ((STp->buffer)->buffer_blocks - transfer) *
 948                       STp->block_size;
 949 #ifdef DEBUG
 950                 printk(
 951                  "st%d: EOF detected (%d bytes read, transferred %d bytes).\n",
 952                        dev, (STp->buffer)->buffer_bytes, total);
 953 #endif
 954               } 
 955             }
 956             else { 
 957 #ifdef DEBUG
 958               printk("st%d: Tape error while reading.\n", dev);
 959 #endif
 960               SCpnt->request.dev = -1;
 961               if (total)
 962                 return total;
 963               else
 964                 return -EIO;
 965             }
 966           }
 967           else {
 968             transfer = (STp->buffer)->last_result_fatal;
 969             SCpnt->request.dev = -1;  
 970             return transfer;
 971           }
 972         }
 973         else 
 974           (STp->buffer)->buffer_bytes = bytes;
 975 
 976       } 
 977 
 978 
 979       if ((STp->buffer)->buffer_bytes > 0) {
 980 #ifdef DEBUG
 981         if (STp->eof != ST_NOEOF)
 982           printk("st%d: EOF up. Left %d, needed %d.\n", dev,
 983                  (STp->buffer)->buffer_bytes, count - total);
 984 #endif
 985         transfer = (STp->buffer)->buffer_bytes < count - total ?
 986           (STp->buffer)->buffer_bytes : count - total;
 987         memcpy_tofs(buf, (STp->buffer)->b_data +
 988                     (STp->buffer)->read_pointer,transfer);
 989         filp->f_pos += transfer;
 990         buf += transfer;
 991         total += transfer;
 992         (STp->buffer)->buffer_bytes -= transfer;
 993         (STp->buffer)->read_pointer += transfer;
 994       }
 995       else if (STp->eof != ST_NOEOF) {
 996         STp->eof_hit = 1;
 997         SCpnt->request.dev = -1;  
 998         if (total == 0 && STp->eof == ST_FM)
 999           STp->eof = 0;
1000         if (total == 0 && STp->eof == ST_EOM_OK)
1001           return (-EIO);  
1002         return total;
1003       }
1004 
1005       if (STp->block_size == 0)
1006         count = total;  
1007 
1008     } 
1009 
1010     SCpnt->request.dev = -1;  
1011 
1012     return total;
1013 }
1014 
1015 
1016 
1017         static int
1018 st_int_ioctl(struct inode * inode,struct file * file,
     
1019              unsigned int cmd_in, unsigned long arg)
1020 {
1021    int dev = MINOR(inode->i_rdev);
1022    int timeout = ST_LONG_TIMEOUT;
1023    long ltmp;
1024    int ioctl_result;
1025    unsigned char cmd[10];
1026    Scsi_Cmnd * SCpnt;
1027    Scsi_Tape * STp;
1028 
1029    dev = dev & 127;
1030    STp = &(scsi_tapes[dev]);
1031 
1032    memset(cmd, 0, 10);
1033    switch (cmd_in) {
1034      case MTFSF:
1035      case MTFSFM:
1036        cmd[0] = SPACE;
1037        cmd[1] = 0x01; 
1038        cmd[2] = (arg >> 16);
1039        cmd[3] = (arg >> 8);
1040        cmd[4] = arg;
1041 #ifdef DEBUG
1042        printk("st%d: Spacing tape forward over %d filemarks.\n", dev,
1043               cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1044 #endif
1045        break; 
1046      case MTBSF:
1047      case MTBSFM:
1048        cmd[0] = SPACE;
1049        cmd[1] = 0x01; 
1050        ltmp = (-arg);
1051        cmd[2] = (ltmp >> 16);
1052        cmd[3] = (ltmp >> 8);
1053        cmd[4] = ltmp;
1054 #ifdef DEBUG
1055        if (cmd[2] & 0x80)
1056          ltmp = 0xff000000;
1057        ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
1058        printk("st%d: Spacing tape backward over %d filemarks.\n", dev, (-ltmp));
1059 #endif
1060        break; 
1061       case MTFSR:
1062        cmd[0] = SPACE;
1063        cmd[1] = 0x00; 
1064        cmd[2] = (arg >> 16);
1065        cmd[3] = (arg >> 8);
1066        cmd[4] = arg;
1067 #ifdef DEBUG
1068        printk("st%d: Spacing tape forward %d blocks.\n", dev,
1069               cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1070 #endif
1071        break; 
1072      case MTBSR:
1073        cmd[0] = SPACE;
1074        cmd[1] = 0x00; 
1075        ltmp = (-arg);
1076        cmd[2] = (ltmp >> 16);
1077        cmd[3] = (ltmp >> 8);
1078        cmd[4] = ltmp;
1079 #ifdef DEBUG
1080        if (cmd[2] & 0x80)
1081          ltmp = 0xff000000;
1082        ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
1083        printk("st%d: Spacing tape backward %d blocks.\n", dev, (-ltmp));
1084 #endif
1085        break; 
1086      case MTWEOF:
1087        if (STp->write_prot)
1088          return (-EACCES);
1089        cmd[0] = WRITE_FILEMARKS;
1090        cmd[2] = (arg >> 16);
1091        cmd[3] = (arg >> 8);
1092        cmd[4] = arg;
1093        timeout = ST_TIMEOUT;
1094 #ifdef DEBUG
1095        printk("st%d: Writing %d filemarks.\n", dev,
1096               cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1097 #endif
1098        break; 
1099      case MTREW:
1100        cmd[0] = REZERO_UNIT;
1101 #ifdef ST_NOWAIT
1102        cmd[1] = 1;  
1103        timeout = ST_TIMEOUT;
1104 #endif
1105 #ifdef DEBUG
1106        printk("st%d: Rewinding tape.\n", dev);
1107 #endif
1108        break; 
1109      case MTOFFL:
1110        cmd[0] = START_STOP;
1111 #ifdef ST_NOWAIT
1112        cmd[1] = 1;  
1113        timeout = ST_TIMEOUT;
1114 #endif
1115 #ifdef DEBUG
1116        printk("st%d: Unloading tape.\n", dev);
1117 #endif
1118        break; 
1119      case MTNOP:
1120 #ifdef DEBUG
1121        printk("st%d: No op on tape.\n", dev);
1122 #endif
1123        return 0;  
1124        break;
1125      case MTRETEN:
1126        cmd[0] = START_STOP;
1127 #ifdef ST_NOWAIT
1128        cmd[1] = 1;  
1129        timeout = ST_TIMEOUT;
1130 #endif
1131        cmd[4] = 3;
1132 #ifdef DEBUG
1133        printk("st%d: Retensioning tape.\n", dev);
1134 #endif
1135        break; 
1136      case MTEOM:
1137        cmd[0] = SPACE;
1138        cmd[1] = 3;
1139 #ifdef DEBUG
1140        printk("st%d: Spacing to end of recorded medium.\n", dev);
1141 #endif
1142        break; 
1143      case MTERASE:
1144        if (STp->write_prot)
1145          return (-EACCES);
1146        cmd[0] = ERASE;
1147        cmd[1] = 1;  
1148 #ifdef DEBUG
1149        printk("st%d: Erasing tape.\n", dev);
1150 #endif
1151        break;
1152      case MTSEEK:
1153        if ((STp->device)->scsi_level < SCSI_2) {
1154          cmd[0] = QFA_SEEK_BLOCK;
1155          cmd[2] = (arg >> 16);
1156          cmd[3] = (arg >> 8);
1157          cmd[4] = arg;
1158          cmd[5] = 0;
1159        }
1160        else {
1161          cmd[0] = SEEK_10;
1162          cmd[1] = 4;
1163          cmd[3] = (arg >> 24);
1164          cmd[4] = (arg >> 16);
1165          cmd[5] = (arg >> 8);
1166          cmd[6] = arg;
1167        }
1168 #ifdef ST_NOWAIT
1169        cmd[1] |= 1;  
1170        timeout = ST_TIMEOUT;
1171 #endif
1172 #ifdef DEBUG
1173        printk("st%d: Seeking tape to block %d.\n", dev, arg);
1174 #endif
1175        break;
1176      case MTSETBLK:  
1177      case MTSETDENSITY: 
1178      case MTSETDRVBUFFER: 
1179        if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
1180          return (-EIO);   
1181        if (cmd_in == MTSETBLK &&
1182            arg != 0 &&
1183            (arg < STp->min_block || arg > STp->max_block ||
1184             arg > ST_BUFFER_SIZE)) {
1185          printk("st%d: Illegal block size.\n", dev);
1186          return (-EINVAL);
1187        }
1188        cmd[0] = MODE_SELECT;
1189        cmd[4] = 12;
1190 
1191        memset((STp->buffer)->b_data, 0, 12);
1192        if (cmd_in == MTSETDRVBUFFER)
1193          (STp->buffer)->b_data[2] = (arg & 7) << 4;
1194        else
1195          (STp->buffer)->b_data[2] = 
1196            STp->drv_buffer << 4;
1197        (STp->buffer)->b_data[3] = 8;     
1198        if (cmd_in == MTSETDENSITY)
1199          (STp->buffer)->b_data[4] = arg;
1200        else
1201          (STp->buffer)->b_data[4] = STp->density;
1202        if (cmd_in == MTSETBLK)
1203          ltmp = arg;
1204        else
1205          ltmp = STp->block_size;
1206        (STp->buffer)->b_data[9] = (ltmp >> 16);
1207        (STp->buffer)->b_data[10] = (ltmp >> 8);
1208        (STp->buffer)->b_data[11] = ltmp;
1209        timeout = ST_TIMEOUT;
1210 #ifdef DEBUG
1211        if (cmd_in == MTSETBLK)
1212          printk("st%d: Setting block size to %d bytes.\n", dev,
1213                 (STp->buffer)->b_data[9] * 65536 +
1214                 (STp->buffer)->b_data[10] * 256 +
1215                 (STp->buffer)->b_data[11]);
1216        else if (cmd_in == MTSETDENSITY)
1217          printk("st%d: Setting density code to %x.\n", dev,
1218                 (STp->buffer)->b_data[4]);
1219        else
1220          printk("st%d: Setting drive buffer code to %d.\n", dev,
1221                 ((STp->buffer)->b_data[2] >> 4) & 7);
1222 #endif
1223        break;
1224      default:
1225        printk("st%d: Unknown st_ioctl command %x.\n", dev, cmd_in);
1226        return (-ENOSYS);
1227      }
1228 
1229    SCpnt = allocate_device(NULL, (STp->device)->index, 1);
1230    SCpnt->sense_buffer[0] = 0;
1231    SCpnt->request.dev = dev;
1232    scsi_do_cmd(SCpnt,
1233                (void *) cmd, (void *) (STp->buffer)->b_data, ST_BLOCK_SIZE,
1234                st_sleep_done, timeout, MAX_RETRIES);
1235 
1236    if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
1237 
1238    ioctl_result = (STp->buffer)->last_result_fatal;
1239 
1240    SCpnt->request.dev = -1;  
1241 
1242    if (!ioctl_result) {
1243      if (cmd_in == MTBSFM)
1244        ioctl_result = st_int_ioctl(inode, file, MTFSF, 1);
1245      else if (cmd_in == MTFSFM)
1246        ioctl_result = st_int_ioctl(inode, file, MTBSF, 1);
1247      else if (cmd_in == MTSETBLK) {
1248        STp->block_size = arg;
1249        if (arg != 0) {
1250          (STp->buffer)->buffer_blocks =
1251            ST_BUFFER_SIZE / STp->block_size;
1252          (STp->buffer)->buffer_size =
1253            (STp->buffer)->buffer_blocks * STp->block_size;
1254        }
1255        else {
1256          (STp->buffer)->buffer_blocks = 1;
1257          (STp->buffer)->buffer_size = ST_BUFFER_SIZE;
1258        }
1259        (STp->buffer)->buffer_bytes =
1260          (STp->buffer)->read_pointer = 0;
1261      }
1262      else if (cmd_in == MTSETDRVBUFFER)
1263        STp->drv_buffer = arg;
1264      else if (cmd_in == MTSETDENSITY)
1265        STp->density = arg;
1266      if (cmd_in == MTEOM || cmd_in == MTWEOF) {
1267        STp->eof = ST_EOM_OK;
1268        STp->eof_hit = 0;
1269      }
1270      else if (cmd_in != MTSETBLK && cmd_in != MTNOP) {
1271        STp->eof = ST_NOEOF;
1272        STp->eof_hit = 0;
1273      }
1274    }
1275 
1276    return ioctl_result ;
1277 }
1278 
1279 
1280 
1281 
1282         static int
1283 st_ioctl(struct inode * inode,struct file * file,
     
1284          unsigned int cmd_in, unsigned long arg)
1285 {
1286    int dev = MINOR(inode->i_rdev);
1287    int i, cmd, result;
1288    struct mtop mtc;
1289    struct mtpos mt_pos;
1290    unsigned char scmd[10];
1291    Scsi_Cmnd *SCpnt;
1292    Scsi_Tape *STp;
1293 
1294    dev = dev & 127;
1295    STp = &(scsi_tapes[dev]);
1296 #ifdef DEBUG
1297    if (!STp->in_use) {
1298      printk("st%d: Incorrect device.\n", dev);
1299      return (-EIO);
1300    }
1301 #endif
1302 
1303    cmd = cmd_in & IOCCMD_MASK;
1304    if (cmd == (MTIOCTOP & IOCCMD_MASK)) {
1305 
1306      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(mtc))
1307        return (-EINVAL);
1308 
1309      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(mtc));
1310      if (i)
1311         return i;
1312 
1313      memcpy_fromfs((char *) &mtc, (char *)arg, sizeof(struct mtop));
1314 
1315      i = flush_buffer(inode, file, mtc.mt_op == MTSEEK ||
1316                       mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
1317                       mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM);
1318      if (i < 0)
1319        return i;
1320 
1321      return st_int_ioctl(inode, file, mtc.mt_op, mtc.mt_count);
1322    }
1323    else if (cmd == (MTIOCGET & IOCCMD_MASK)) {
1324 
1325      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtget))
1326        return (-EINVAL);
1327      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct mtget));
1328      if (i)
1329        return i;
1330 
1331      memcpy_tofs((char *)arg, (char *)(STp->buffer)->mt_status,
1332                  sizeof(struct mtget));
1333      return 0;
1334    }
1335    else if (cmd == (MTIOCPOS & IOCCMD_MASK)) {
1336 #ifdef DEBUG
1337      printk("st%d: get tape position.\n", dev);
1338 #endif
1339      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtpos))
1340        return (-EINVAL);
1341 
1342      i = flush_buffer(inode, file, 0);
1343      if (i < 0)
1344        return i;
1345 
1346      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct mtpos));
1347      if (i)
1348        return i;
1349 
1350      SCpnt = allocate_device(NULL, (STp->device)->index, 1);
1351 
1352      SCpnt->sense_buffer[0]=0;
1353      memset (scmd, 0, 10);
1354      if ((STp->device)->scsi_level < SCSI_2) {
1355        scmd[0] = QFA_REQUEST_BLOCK;
1356        scmd[4] = 3;
1357      }
1358      else {
1359        scmd[0] = READ_POSITION;
1360        scmd[1] = 1;
1361      }
1362      SCpnt->request.dev = dev;
1363      SCpnt->sense_buffer[0] = 0;
1364      scsi_do_cmd(SCpnt,
1365                  (void *) scmd, (void *) (STp->buffer)->b_data,
1366                  ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
1367 
1368      if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
1369      
1370      if ((STp->buffer)->last_result_fatal != 0) {
1371        mt_pos.mt_blkno = (-1);
1372 #ifdef DEBUG
1373        printk("st%d: Can't read tape position.\n", dev);
1374 #endif
1375        result = (-EIO);
1376      }
1377      else {
1378        result = 0;
1379        if ((STp->device)->scsi_level < SCSI_2)
1380          mt_pos.mt_blkno = ((STp->buffer)->b_data[0] << 16) 
1381            + ((STp->buffer)->b_data[1] << 8) 
1382              + (STp->buffer)->b_data[2];
1383        else
1384          mt_pos.mt_blkno = ((STp->buffer)->b_data[4] << 24)
1385            + ((STp->buffer)->b_data[5] << 16) 
1386              + ((STp->buffer)->b_data[6] << 8) 
1387                + (STp->buffer)->b_data[7];
1388 
1389      }
1390 
1391      SCpnt->request.dev = -1;  
1392 
1393      memcpy_tofs((char *)arg, (char *) (&mt_pos), sizeof(struct mtpos));
1394      return result;
1395    }
1396    else
1397      return scsi_ioctl(STp->device, cmd_in, (void *) arg);
1398 }
1399 
1400 
1401 
1402 static struct file_operations st_fops = {
1403    NULL,            
1404    st_read,         
1405    st_write,        
1406    NULL,            
1407    NULL,            
1408    st_ioctl,        
1409    NULL,            
1410    scsi_tape_open,  
1411    scsi_tape_close, 
1412    NULL             
1413 };
1414 
1415 void st_attach(Scsi_Device * SDp){
     
1416   scsi_tapes[NR_ST++].device = SDp;
1417   if(NR_ST > MAX_ST) panic ("scsi_devices corrupt (st)");
1418 };
1419 
1420 unsigned long st_init1(unsigned long mem_start, unsigned long mem_end){
     
1421   scsi_tapes = (Scsi_Tape *) mem_start;
1422   mem_start += MAX_ST * sizeof(Scsi_Tape);
1423   return mem_start;
1424 };
1425 
1426 
1427 unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
     
1428 {
1429   int i;
1430 
1431   if (register_chrdev(MAJOR_NR,"st",&st_fops)) {
1432     printk("Unable to get major %d for SCSI tapes\n",MAJOR_NR);
1433     return mem_start;
1434   }
1435   if (NR_ST == 0) return mem_start;
1436 
1437 #ifdef DEBUG
1438   printk("st: Init tape.\n");
1439 #endif
1440 
1441   for (i=0; i < NR_ST; ++i) {
1442     scsi_tapes[i].capacity = 0xfffff;
1443     scsi_tapes[i].dirty = 0;
1444     scsi_tapes[i].rw = ST_IDLE;
1445     scsi_tapes[i].eof = ST_NOEOF;
1446     scsi_tapes[i].waiting = NULL;
1447     scsi_tapes[i].in_use = 0;
1448     scsi_tapes[i].drv_buffer = 1;  
1449     scsi_tapes[i].density = 0;
1450   }
1451 
1452 
1453   
1454   if (NR_ST == 1)
1455     st_nbr_buffers = 1;
1456   else
1457     st_nbr_buffers = 2;
1458   for (i=0; i < st_nbr_buffers; i++) {
1459     st_buffers[i] = (ST_buffer *) mem_start;
1460 #ifdef DEBUG
1461     printk("st: Buffer address: %p\n", st_buffers[i]);
1462 #endif
1463     mem_start += sizeof(ST_buffer) - 1 + ST_BUFFER_BLOCKS * ST_BLOCK_SIZE;
1464     st_buffers[i]->mt_status = (struct mtget *) mem_start;
1465     mem_start += sizeof(struct mtget);
1466     st_buffers[i]->in_use = 0;
1467     st_buffers[i]->writing = 0;
1468 
1469     
1470     memset((void *) st_buffers[i]->mt_status, 0, sizeof(struct mtget));
1471     st_buffers[i]->mt_status->mt_type = MT_ISSCSI1;
1472   }
1473 
1474   return mem_start;
1475 }