2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying 3 file README.st for more information. 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 11 Copyright 1992, 1993, 1994 Kai Makisara 12 email makisara@vtinsx.ins.vtt.fi or Kai.Makisara@vtt.fi 14 Last modified: Wed May 4 20:29:42 1994 by root@kai.home 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> 28 #define MAJOR_NR SCSI_TAPE_MAJOR 29 #include"../block/blk.h" 31 #include"scsi_ioctl.h" 37 /* #define ST_NOWAIT */ 39 /* #define ST_IN_FILE_POS */ 41 /* #define ST_RECOVERED_WRITE_FATAL */ 43 #define ST_BUFFER_WRITES 1 45 #define ST_ASYNC_WRITES 1 47 #define ST_READ_AHEAD 1 49 #define ST_BLOCK_SIZE 1024 51 #define ST_MAX_BUFFERS 2 53 #define ST_BUFFER_BLOCKS 32 55 #define ST_WRITE_THRESHOLD_BLOCKS 30 57 #define ST_BUFFER_SIZE (ST_BUFFER_BLOCKS * ST_BLOCK_SIZE) 58 #define ST_WRITE_THRESHOLD (ST_WRITE_THRESHOLD_BLOCKS * ST_BLOCK_SIZE) 60 /* The buffer size should fit into the 24 bits for length in the 61 6-byte SCSI read and write commands. */ 62 #if ST_BUFFER_SIZE >= (2 << 24 - 1) 63 #error"Buffer size should not exceed (2 << 24 - 1) bytes!" 67 static int debugging
=1; 71 #define MAX_READY_RETRIES 5 72 #define NO_TAPE NOT_READY 74 #define ST_TIMEOUT 9000 75 #define ST_LONG_TIMEOUT 200000 77 static int st_nbr_buffers
; 78 static ST_buffer
**st_buffers
; 79 static int st_buffer_size
= ST_BUFFER_SIZE
; 80 static int st_write_threshold
= ST_WRITE_THRESHOLD
; 81 static int st_max_buffers
= ST_MAX_BUFFERS
; 83 static Scsi_Tape
* scsi_tapes
; 87 static intst_int_ioctl(struct inode
* inode
,struct file
* file
, 88 unsigned int cmd_in
,unsigned long arg
); 93 /* Convert the result to success code */ 95 st_chk_result(Scsi_Cmnd
* SCpnt
) 97 int dev
= SCpnt
->request
.dev
; 98 int result
= SCpnt
->result
; 99 unsigned char* sense
= SCpnt
->sense_buffer
; 102 if(!result
&& SCpnt
->sense_buffer
[0] ==0) 106 printk("st%d: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n", dev
, result
, 107 SCpnt
->cmnd
[0], SCpnt
->cmnd
[1], SCpnt
->cmnd
[2], 108 SCpnt
->cmnd
[3], SCpnt
->cmnd
[4], SCpnt
->cmnd
[5], 109 SCpnt
->request_bufflen
); 110 if(driver_byte(result
) & DRIVER_SENSE
) 111 print_sense("st", SCpnt
); 114 /* if ((sense[0] & 0x70) == 0x70 && 115 ((sense[2] & 0x80) )) 117 if((sense
[0] &0x70) ==0x70&& 118 sense
[2] == RECOVERED_ERROR
119 #ifdef ST_RECOVERED_WRITE_FATAL 120 && SCpnt
->cmnd
[0] != WRITE_6
121 && SCpnt
->cmnd
[0] != WRITE_FILEMARKS
124 scsi_tapes
[dev
].recover_count
++; 125 scsi_tapes
[dev
].mt_status
->mt_erreg
+= (1<< MT_ST_SOFTERR_SHIFT
); 126 if(SCpnt
->cmnd
[0] == READ_6
) 128 else if(SCpnt
->cmnd
[0] == WRITE_6
) 132 printk("st%d: Recovered %s error (%d).\n", dev
, stp
, 133 scsi_tapes
[dev
].recover_count
); 140 /* Wakeup from interrupt */ 142 st_sleep_done(Scsi_Cmnd
* SCpnt
) 144 int st_nbr
, remainder
; 147 if((st_nbr
= SCpnt
->request
.dev
) < NR_ST
&& st_nbr
>=0) { 148 STp
= &(scsi_tapes
[st_nbr
]); 149 if((STp
->buffer
)->writing
&& 150 (SCpnt
->sense_buffer
[0] &0x70) ==0x70&& 151 (SCpnt
->sense_buffer
[2] &0x40)) { 152 /* EOM at write-behind, has all been written? */ 153 if((SCpnt
->sense_buffer
[0] &0x80) !=0) 154 remainder
= (SCpnt
->sense_buffer
[3] <<24) | 155 (SCpnt
->sense_buffer
[4] <<16) | 156 (SCpnt
->sense_buffer
[5] <<8) | SCpnt
->sense_buffer
[6]; 159 if((SCpnt
->sense_buffer
[2] &0x0f) == VOLUME_OVERFLOW
|| 161 (STp
->buffer
)->last_result
= SCpnt
->result
;/* Error */ 163 (STp
->buffer
)->last_result
= INT_MAX
;/* OK */ 166 (STp
->buffer
)->last_result
= SCpnt
->result
; 167 (STp
->buffer
)->last_result_fatal
=st_chk_result(SCpnt
); 168 if((STp
->buffer
)->writing
) 169 SCpnt
->request
.dev
= -1; 171 SCpnt
->request
.dev
=0xffff; 172 if((STp
->buffer
)->writing
<=0) 173 wake_up( &(STp
->waiting
) ); 177 printk("st?: Illegal interrupt device %x\n", st_nbr
); 182 /* Handle the write-behind checking */ 184 write_behind_check(int dev
) 187 ST_buffer
* STbuffer
; 189 STp
= &(scsi_tapes
[dev
]); 190 STbuffer
= STp
->buffer
; 193 if(STbuffer
->last_result
<0) { 194 STbuffer
->writing
= (- STbuffer
->writing
); 195 sleep_on( &(STp
->waiting
) ); 196 STbuffer
->writing
= (- STbuffer
->writing
); 200 if(STbuffer
->writing
< STbuffer
->buffer_bytes
) 201 memcpy(STbuffer
->b_data
, 202 STbuffer
->b_data
+ STbuffer
->writing
, 203 STbuffer
->buffer_bytes
- STbuffer
->writing
); 204 STbuffer
->buffer_bytes
-= STbuffer
->writing
; 205 if(STp
->drv_block
>=0) { 206 if(STp
->block_size
==0) 209 STp
->drv_block
+= STbuffer
->writing
/ STp
->block_size
; 211 STbuffer
->writing
=0; 217 /* Back over EOF if it has been inadvertently crossed (ioctl not used because 218 it messes up the block number). */ 220 back_over_eof(int dev
) 223 Scsi_Tape
*STp
= &(scsi_tapes
[dev
]); 224 unsigned char cmd
[10]; 227 cmd
[1] =0x01;/* Space FileMarks */ 228 cmd
[2] = cmd
[3] = cmd
[4] =0xff;/* -1 filemarks */ 231 SCpnt
=allocate_device(NULL
, (STp
->device
)->index
,1); 232 SCpnt
->sense_buffer
[0] =0; 233 SCpnt
->request
.dev
= dev
; 235 (void*) cmd
, (void*) (STp
->buffer
)->b_data
,0, 236 st_sleep_done
, ST_TIMEOUT
, MAX_RETRIES
); 238 if(SCpnt
->request
.dev
== dev
)sleep_on( &(STp
->waiting
) ); 239 SCpnt
->request
.dev
= -1; 241 return(STp
->buffer
)->last_result_fatal
; 245 /* Flush the write buffer (never need to write if variable blocksize). */ 247 flush_write_buffer(int dev
) 249 int offset
, transfer
, blks
; 251 unsigned char cmd
[10]; 253 Scsi_Tape
*STp
= &(scsi_tapes
[dev
]); 255 if((STp
->buffer
)->writing
) { 256 write_behind_check(dev
); 257 if((STp
->buffer
)->last_result_fatal
) { 260 printk("st%d: Async write error (flush) %x.\n", dev
, 261 (STp
->buffer
)->last_result
); 263 if((STp
->buffer
)->last_result
== INT_MAX
) 271 SCpnt
=allocate_device(NULL
, (STp
->device
)->index
,1); 273 offset
= (STp
->buffer
)->buffer_bytes
; 274 transfer
= ((offset
+ STp
->block_size
-1) / 275 STp
->block_size
) * STp
->block_size
; 278 printk("st%d: Flushing %d bytes.\n", dev
, transfer
); 280 memset((STp
->buffer
)->b_data
+ offset
,0, transfer
- offset
); 282 SCpnt
->sense_buffer
[0] =0; 286 blks
= transfer
/ STp
->block_size
; 290 SCpnt
->request
.dev
= dev
; 292 (void*) cmd
, (STp
->buffer
)->b_data
, transfer
, 293 st_sleep_done
, ST_TIMEOUT
, MAX_RETRIES
); 295 if(SCpnt
->request
.dev
== dev
)sleep_on( &(STp
->waiting
) ); 297 if((STp
->buffer
)->last_result_fatal
!=0) { 298 printk("st%d: Error on flush.\n", dev
); 299 if((SCpnt
->sense_buffer
[0] &0x70) ==0x70&& 300 (SCpnt
->sense_buffer
[2] &0x40) && 301 (SCpnt
->sense_buffer
[2] &0x0f) != VOLUME_OVERFLOW
) { 303 (STp
->buffer
)->buffer_bytes
=0; 308 STp
->drv_block
= (-1); 311 if(STp
->drv_block
>=0) 312 STp
->drv_block
+= blks
; 314 (STp
->buffer
)->buffer_bytes
=0; 316 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 322 /* Flush the tape buffer. The tape will be positioned correctly unless 323 seek_next is true. */ 325 flush_buffer(struct inode
* inode
,struct file
* filp
,int seek_next
) 328 int backspace
, result
; 330 ST_buffer
* STbuffer
; 332 dev
=MINOR(inode
->i_rdev
) &127; 333 STp
= &(scsi_tapes
[dev
]); 334 STbuffer
= STp
->buffer
; 336 if(STp
->rw
== ST_WRITING
)/* Writing */ 337 returnflush_write_buffer(dev
); 339 if(STp
->block_size
==0) 342 backspace
= ((STp
->buffer
)->buffer_bytes
+ 343 (STp
->buffer
)->read_pointer
) / STp
->block_size
- 344 ((STp
->buffer
)->read_pointer
+ STp
->block_size
-1) / 346 (STp
->buffer
)->buffer_bytes
=0; 347 (STp
->buffer
)->read_pointer
=0; 350 if((STp
->eof
== ST_FM
) && !STp
->eof_hit
) { 351 result
=back_over_eof(dev
);/* Back over the EOF hit */ 357 if(!result
&& backspace
>0) 358 result
=st_int_ioctl(inode
, filp
, MTBSR
, backspace
); 365 /* Open the device */ 367 scsi_tape_open(struct inode
* inode
,struct file
* filp
) 370 unsigned short flags
; 372 unsigned char cmd
[10]; 376 dev
=MINOR(inode
->i_rdev
) &127; 379 STp
= &(scsi_tapes
[dev
]); 381 printk("st%d: Device already in use.\n", dev
); 385 /* Allocate buffer for this user */ 386 for(i
=0; i
< st_nbr_buffers
; i
++) 387 if(!st_buffers
[i
]->in_use
) 389 if(i
>= st_nbr_buffers
) { 390 printk("st%d: No free buffers.\n", dev
); 393 STp
->buffer
= st_buffers
[i
]; 394 (STp
->buffer
)->in_use
=1; 395 (STp
->buffer
)->writing
=0; 398 flags
= filp
->f_flags
; 399 STp
->write_prot
= ((flags
& O_ACCMODE
) == O_RDONLY
); 405 STp
->recover_count
=0; 407 SCpnt
=allocate_device(NULL
, (STp
->device
)->index
,1); 409 printk("st%d: Tape request not allocated", dev
); 413 SCpnt
->sense_buffer
[0]=0; 414 memset((void*) &cmd
[0],0,10); 415 cmd
[0] = TEST_UNIT_READY
; 416 SCpnt
->request
.dev
= dev
; 418 (void*) cmd
, (void*) (STp
->buffer
)->b_data
, 419 0, st_sleep_done
, ST_LONG_TIMEOUT
, 422 if(SCpnt
->request
.dev
== dev
)sleep_on( &(STp
->waiting
) ); 424 if((SCpnt
->sense_buffer
[0] &0x70) ==0x70&& 425 (SCpnt
->sense_buffer
[2] &0x0f) == UNIT_ATTENTION
) {/* New media? */ 426 (STp
->mt_status
)->mt_fileno
=0; 427 SCpnt
->sense_buffer
[0]=0; 428 memset((void*) &cmd
[0],0,10); 429 cmd
[0] = TEST_UNIT_READY
; 430 SCpnt
->request
.dev
= dev
; 432 (void*) cmd
, (void*) (STp
->buffer
)->b_data
, 433 0, st_sleep_done
, ST_LONG_TIMEOUT
, 436 if(SCpnt
->request
.dev
== dev
)sleep_on( &(STp
->waiting
) ); 437 (STp
->mt_status
)->mt_fileno
= STp
->drv_block
=0; 440 if((STp
->buffer
)->last_result_fatal
!=0) { 441 if((SCpnt
->sense_buffer
[0] &0x70) ==0x70&& 442 (SCpnt
->sense_buffer
[2] &0x0f) == NO_TAPE
) { 443 (STp
->mt_status
)->mt_fileno
= STp
->drv_block
=0; 444 printk("st%d: No tape.\n", dev
); 446 printk("st%d: Error %x.\n", dev
, SCpnt
->result
); 447 (STp
->mt_status
)->mt_fileno
= STp
->drv_block
= (-1); 449 (STp
->buffer
)->in_use
=0; 451 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 455 SCpnt
->sense_buffer
[0]=0; 456 memset((void*) &cmd
[0],0,10); 457 cmd
[0] = READ_BLOCK_LIMITS
; 458 SCpnt
->request
.dev
= dev
; 460 (void*) cmd
, (void*) (STp
->buffer
)->b_data
, 461 6, st_sleep_done
, ST_TIMEOUT
, MAX_READY_RETRIES
); 463 if(SCpnt
->request
.dev
== dev
)sleep_on( &(STp
->waiting
) ); 465 if(!SCpnt
->result
&& !SCpnt
->sense_buffer
[0]) { 466 STp
->max_block
= ((STp
->buffer
)->b_data
[1] <<16) | 467 ((STp
->buffer
)->b_data
[2] <<8) | (STp
->buffer
)->b_data
[3]; 468 STp
->min_block
= ((STp
->buffer
)->b_data
[4] <<8) | 469 (STp
->buffer
)->b_data
[5]; 472 printk("st%d: Block limits %d - %d bytes.\n", dev
, STp
->min_block
, 477 STp
->min_block
= STp
->max_block
= (-1); 480 printk("st%d: Can't read block limits.\n", dev
); 484 SCpnt
->sense_buffer
[0]=0; 485 memset((void*) &cmd
[0],0,10); 488 SCpnt
->request
.dev
= dev
; 490 (void*) cmd
, (void*) (STp
->buffer
)->b_data
, 491 12, st_sleep_done
, ST_TIMEOUT
, MAX_READY_RETRIES
); 493 if(SCpnt
->request
.dev
== dev
)sleep_on( &(STp
->waiting
) ); 495 if((STp
->buffer
)->last_result_fatal
!=0) { 498 printk("st%d: No Mode Sense.\n", dev
); 500 (STp
->buffer
)->b_data
[2] = 501 (STp
->buffer
)->b_data
[3] =0; 503 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 507 printk("st%d: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n", dev
, 508 (STp
->buffer
)->b_data
[0], (STp
->buffer
)->b_data
[1], 509 (STp
->buffer
)->b_data
[2], (STp
->buffer
)->b_data
[3]); 512 if((STp
->buffer
)->b_data
[3] >=8) { 513 STp
->drv_buffer
= ((STp
->buffer
)->b_data
[2] >>4) &7; 514 STp
->density
= (STp
->buffer
)->b_data
[4]; 515 STp
->block_size
= (STp
->buffer
)->b_data
[9] *65536+ 516 (STp
->buffer
)->b_data
[10] *256+ (STp
->buffer
)->b_data
[11]; 519 printk("st%d: Density %x, tape length: %x, blocksize: %d, drv buffer: %d\n", 520 dev
, STp
->density
, (STp
->buffer
)->b_data
[5] *65536+ 521 (STp
->buffer
)->b_data
[6] *256+ (STp
->buffer
)->b_data
[7], 522 STp
->block_size
, STp
->drv_buffer
); 524 if(STp
->block_size
> st_buffer_size
) { 525 printk("st%d: Blocksize %d too large for buffer.\n", dev
, 527 (STp
->buffer
)->in_use
=0; 534 STp
->block_size
=512;/* "Educated Guess" (?) */ 536 if(STp
->block_size
>0) { 537 (STp
->buffer
)->buffer_blocks
= st_buffer_size
/ STp
->block_size
; 538 (STp
->buffer
)->buffer_size
= 539 (STp
->buffer
)->buffer_blocks
* STp
->block_size
; 542 (STp
->buffer
)->buffer_blocks
=1; 543 (STp
->buffer
)->buffer_size
= st_buffer_size
; 545 (STp
->buffer
)->buffer_bytes
= (STp
->buffer
)->read_pointer
=0; 549 printk("st%d: Block size: %d, buffer size: %d (%d blocks).\n", dev
, 550 STp
->block_size
, (STp
->buffer
)->buffer_size
, 551 (STp
->buffer
)->buffer_blocks
); 554 if((STp
->buffer
)->b_data
[2] &0x80) { 558 printk("st%d: Write protected\n", dev
); 566 /* Close the device*/ 568 scsi_tape_close(struct inode
* inode
,struct file
* filp
) 573 static unsigned char cmd
[10]; 577 dev
=MINOR(inode
->i_rdev
); 578 rewind
= (dev
&0x80) ==0; 580 STp
= &(scsi_tapes
[dev
]); 582 if( STp
->rw
== ST_WRITING
) { 584 result
=flush_write_buffer(dev
); 588 printk("st%d: File length %ld bytes.\n", dev
, filp
->f_pos
); 591 if(result
==0|| result
== (-ENOSPC
)) { 592 SCpnt
=allocate_device(NULL
, (STp
->device
)->index
,1); 594 SCpnt
->sense_buffer
[0] =0; 596 cmd
[0] = WRITE_FILEMARKS
; 598 SCpnt
->request
.dev
= dev
; 600 (void*) cmd
, (void*) (STp
->buffer
)->b_data
, 601 0, st_sleep_done
, ST_TIMEOUT
, MAX_RETRIES
); 603 if(SCpnt
->request
.dev
== dev
)sleep_on( &(STp
->waiting
) ); 605 if((STp
->buffer
)->last_result_fatal
!=0) 606 printk("st%d: Error on write filemark.\n", dev
); 608 (STp
->mt_status
)->mt_fileno
++ ; 612 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 617 printk("st%d: Buffer flushed, EOF written\n", dev
); 621 #ifndef ST_IN_FILE_POS 622 if((STp
->eof
== ST_FM
) && !STp
->eof_hit
) 625 flush_buffer(inode
, filp
,0); 630 st_int_ioctl(inode
, filp
, MTREW
,1); 632 (STp
->buffer
)->in_use
=0; 641 st_write(struct inode
* inode
,struct file
* filp
,char* buf
,int count
) 644 int total
, do_count
, blks
, retval
, transfer
; 646 static unsigned char cmd
[10]; 651 dev
=MINOR(inode
->i_rdev
) &127; 652 STp
= &(scsi_tapes
[dev
]); 655 printk("st%d: Incorrect device.\n", dev
); 663 if(STp
->block_size
==0&& count
> st_buffer_size
) 666 if(STp
->rw
== ST_READING
) { 667 retval
=flush_buffer(inode
, filp
,0); 670 STp
->rw
= ST_WRITING
; 673 if((STp
->buffer
)->writing
) { 674 write_behind_check(dev
); 675 if((STp
->buffer
)->last_result_fatal
) { 678 printk("st%d: Async write error (write) %x.\n", dev
, 679 (STp
->buffer
)->last_result
); 681 if((STp
->buffer
)->last_result
== INT_MAX
) { 682 retval
= (-ENOSPC
);/* All has been written */ 683 STp
->eof
= ST_EOM_OK
; 691 if(STp
->eof
== ST_EOM_OK
) 693 else if(STp
->eof
== ST_EOM_ERROR
) 696 if(!STp
->do_buffer_writes
) { 697 if(STp
->block_size
!=0&& (count
% STp
->block_size
) !=0) 698 return(-EIO
);/* Write must be integral number of blocks */ 702 write_threshold
= (STp
->buffer
)->buffer_size
; 703 if(!STp
->do_async_writes
) 706 SCpnt
=allocate_device(NULL
, (STp
->device
)->index
,1); 712 cmd
[1] = (STp
->block_size
!=0); 714 STp
->rw
= ST_WRITING
; 717 while((STp
->block_size
==0&& !STp
->do_async_writes
&& count
>0) || 718 (STp
->block_size
!=0&& 719 (STp
->buffer
)->buffer_bytes
+ count
> write_threshold
)) 721 if(STp
->block_size
==0) 724 do_count
= (STp
->buffer
)->buffer_size
- (STp
->buffer
)->buffer_bytes
; 728 memcpy_fromfs((STp
->buffer
)->b_data
+ 729 (STp
->buffer
)->buffer_bytes
, b_point
, do_count
); 731 if(STp
->block_size
==0) 732 blks
= transfer
= do_count
; 734 blks
= ((STp
->buffer
)->buffer_bytes
+ do_count
) / 736 transfer
= blks
* STp
->block_size
; 741 SCpnt
->sense_buffer
[0] =0; 742 SCpnt
->request
.dev
= dev
; 744 (void*) cmd
, (STp
->buffer
)->b_data
, transfer
, 745 st_sleep_done
, ST_TIMEOUT
, MAX_RETRIES
); 747 if(SCpnt
->request
.dev
== dev
)sleep_on( &(STp
->waiting
) ); 749 if((STp
->buffer
)->last_result_fatal
!=0) { 752 printk("st%d: Error on write:\n", dev
); 754 if((SCpnt
->sense_buffer
[0] &0x70) ==0x70&& 755 (SCpnt
->sense_buffer
[2] &0x40)) { 756 if(STp
->block_size
!=0&& (SCpnt
->sense_buffer
[0] &0x80) !=0) 757 transfer
= (SCpnt
->sense_buffer
[3] <<24) | 758 (SCpnt
->sense_buffer
[4] <<16) | 759 (SCpnt
->sense_buffer
[5] <<8) | SCpnt
->sense_buffer
[6]; 760 else if(STp
->block_size
==0&& 761 (SCpnt
->sense_buffer
[2] &0x0f) == VOLUME_OVERFLOW
) 765 if(STp
->block_size
!=0) 766 transfer
*= STp
->block_size
; 767 if(transfer
<= do_count
) { 768 filp
->f_pos
+= do_count
- transfer
; 769 count
-= do_count
- transfer
; 770 if(STp
->drv_block
>=0) { 771 if(STp
->block_size
==0&& transfer
< do_count
) 773 else if(STp
->block_size
!=0) 774 STp
->drv_block
+= (do_count
- transfer
) / STp
->block_size
; 776 STp
->eof
= ST_EOM_OK
; 777 retval
= (-ENOSPC
);/* EOM within current request */ 780 printk("st%d: EOM with %d bytes unwritten.\n", 785 STp
->eof
= ST_EOM_ERROR
; 786 STp
->drv_block
= (-1);/* Too cautious? */ 787 retval
= (-EIO
);/* EOM for old data */ 790 printk("st%d: EOM with lost data.\n", dev
); 795 STp
->drv_block
= (-1);/* Too cautious? */ 799 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 800 (STp
->buffer
)->buffer_bytes
=0; 803 return total
- count
; 807 filp
->f_pos
+= do_count
; 810 if(STp
->drv_block
>=0) { 811 if(STp
->block_size
==0) 814 STp
->drv_block
+= blks
; 816 (STp
->buffer
)->buffer_bytes
=0; 821 memcpy_fromfs((STp
->buffer
)->b_data
+ 822 (STp
->buffer
)->buffer_bytes
,b_point
,count
); 823 filp
->f_pos
+= count
; 824 (STp
->buffer
)->buffer_bytes
+= count
; 828 if((STp
->buffer
)->last_result_fatal
!=0) { 829 SCpnt
->request
.dev
= -1; 830 return(STp
->buffer
)->last_result_fatal
; 833 if(STp
->do_async_writes
&& 834 ((STp
->buffer
)->buffer_bytes
>= STp
->write_threshold
|| 835 STp
->block_size
==0) ) { 836 /* Schedule an asynchronous write */ 837 if(STp
->block_size
==0) 838 (STp
->buffer
)->writing
= (STp
->buffer
)->buffer_bytes
; 840 (STp
->buffer
)->writing
= ((STp
->buffer
)->buffer_bytes
/ 841 STp
->block_size
) * STp
->block_size
; 844 if(STp
->block_size
==0) 845 blks
= (STp
->buffer
)->writing
; 847 blks
= (STp
->buffer
)->writing
/ STp
->block_size
; 851 SCpnt
->result
= (STp
->buffer
)->last_result
= -1; 852 SCpnt
->sense_buffer
[0] =0; 853 SCpnt
->request
.dev
= dev
; 855 (void*) cmd
, (STp
->buffer
)->b_data
, 856 (STp
->buffer
)->writing
, 857 st_sleep_done
, ST_TIMEOUT
, MAX_RETRIES
); 860 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 868 st_read(struct inode
* inode
,struct file
* filp
,char* buf
,int count
) 872 int transfer
, blks
, bytes
; 873 static unsigned char cmd
[10]; 877 dev
=MINOR(inode
->i_rdev
) &127; 878 STp
= &(scsi_tapes
[dev
]); 881 printk("st%d: Incorrect device.\n", dev
); 886 if(STp
->block_size
==0&& count
> st_buffer_size
) 889 if(!(STp
->do_read_ahead
) && STp
->block_size
!=0&& 890 (count
% STp
->block_size
) !=0) 891 return(-EIO
);/* Read must be integral number of blocks */ 893 if(STp
->rw
== ST_WRITING
) { 894 transfer
=flush_buffer(inode
, filp
,0); 897 STp
->rw
= ST_READING
; 901 if(debugging
&& STp
->eof
!= ST_NOEOF
) 902 printk("st%d: EOF flag up. Bytes %d\n", dev
, 903 (STp
->buffer
)->buffer_bytes
); 905 if(((STp
->buffer
)->buffer_bytes
==0) && 906 STp
->eof
== ST_EOM_OK
)/* EOM or Blank Check */ 909 STp
->rw
= ST_READING
; 911 SCpnt
=allocate_device(NULL
, (STp
->device
)->index
,1); 913 for(total
=0; total
< count
; ) { 915 if((STp
->buffer
)->buffer_bytes
==0&& 916 STp
->eof
== ST_NOEOF
) { 920 cmd
[1] = (STp
->block_size
!=0); 921 if(STp
->block_size
==0) 922 blks
= bytes
= count
; 924 if(STp
->do_read_ahead
) { 925 blks
= (STp
->buffer
)->buffer_blocks
; 926 bytes
= blks
* STp
->block_size
; 930 if(bytes
> st_buffer_size
) 931 bytes
= st_buffer_size
; 932 blks
= bytes
/ STp
->block_size
; 933 bytes
= blks
* STp
->block_size
; 940 SCpnt
->sense_buffer
[0] =0; 941 SCpnt
->request
.dev
= dev
; 943 (void*) cmd
, (STp
->buffer
)->b_data
, 944 (STp
->buffer
)->buffer_size
, 945 st_sleep_done
, ST_TIMEOUT
, MAX_RETRIES
); 947 if(SCpnt
->request
.dev
== dev
)sleep_on( &(STp
->waiting
) ); 949 (STp
->buffer
)->read_pointer
=0; 952 if((STp
->buffer
)->last_result_fatal
) { 955 printk("st%d: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", dev
, 956 SCpnt
->sense_buffer
[0], SCpnt
->sense_buffer
[1], 957 SCpnt
->sense_buffer
[2], SCpnt
->sense_buffer
[3], 958 SCpnt
->sense_buffer
[4], SCpnt
->sense_buffer
[5], 959 SCpnt
->sense_buffer
[6], SCpnt
->sense_buffer
[7]); 961 if((SCpnt
->sense_buffer
[0] &0x70) ==0x70) {/* extended sense */ 963 if((SCpnt
->sense_buffer
[2] &0xe0) !=0) {/* EOF, EOM, or ILI */ 965 if((SCpnt
->sense_buffer
[0] &0x80) !=0) 966 transfer
= (SCpnt
->sense_buffer
[3] <<24) | 967 (SCpnt
->sense_buffer
[4] <<16) | 968 (SCpnt
->sense_buffer
[5] <<8) | SCpnt
->sense_buffer
[6]; 971 if(STp
->block_size
==0&& 972 (SCpnt
->sense_buffer
[2] &0x0f) == MEDIUM_ERROR
) 975 if(SCpnt
->sense_buffer
[2] &0x20) { 976 if(STp
->block_size
==0) { 979 (STp
->buffer
)->buffer_bytes
= bytes
- transfer
; 982 printk("st%d: Incorrect block size.\n", dev
); 983 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 987 else if(SCpnt
->sense_buffer
[2] &0x40) { 988 STp
->eof
= ST_EOM_OK
; 989 if(STp
->block_size
==0) 990 (STp
->buffer
)->buffer_bytes
= bytes
- transfer
; 992 (STp
->buffer
)->buffer_bytes
= 993 bytes
- transfer
* STp
->block_size
; 996 printk("st%d: EOM detected (%d bytes read).\n", dev
, 997 (STp
->buffer
)->buffer_bytes
); 1000 else if(SCpnt
->sense_buffer
[2] &0x80) { 1002 if(STp
->block_size
==0) 1003 (STp
->buffer
)->buffer_bytes
=0; 1005 (STp
->buffer
)->buffer_bytes
= 1006 bytes
- transfer
* STp
->block_size
; 1010 "st%d: EOF detected (%d bytes read, transferred %d bytes).\n", 1011 dev
, (STp
->buffer
)->buffer_bytes
, total
); 1013 }/* end of EOF, EOM, ILI test */ 1015 else{/* nonzero sense key */ 1018 printk("st%d: Tape error while reading.\n", dev
); 1020 SCpnt
->request
.dev
= -1; 1021 STp
->drv_block
= (-1); 1029 transfer
= (STp
->buffer
)->last_result_fatal
; 1030 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 1034 else/* Read successful */ 1035 (STp
->buffer
)->buffer_bytes
= bytes
; 1037 if(STp
->drv_block
>=0) { 1038 if(STp
->block_size
==0) 1041 STp
->drv_block
+= (STp
->buffer
)->buffer_bytes
/ STp
->block_size
; 1044 }/* if ((STp->buffer)->buffer_bytes == 0 && 1045 STp->eof == ST_NOEOF) */ 1047 if((STp
->buffer
)->buffer_bytes
>0) { 1049 if(debugging
&& STp
->eof
!= ST_NOEOF
) 1050 printk("st%d: EOF up. Left %d, needed %d.\n", dev
, 1051 (STp
->buffer
)->buffer_bytes
, count
- total
); 1053 transfer
= (STp
->buffer
)->buffer_bytes
< count
- total
? 1054 (STp
->buffer
)->buffer_bytes
: count
- total
; 1055 memcpy_tofs(buf
, (STp
->buffer
)->b_data
+ 1056 (STp
->buffer
)->read_pointer
,transfer
); 1057 filp
->f_pos
+= transfer
; 1060 (STp
->buffer
)->buffer_bytes
-= transfer
; 1061 (STp
->buffer
)->read_pointer
+= transfer
; 1063 else if(STp
->eof
!= ST_NOEOF
) { 1065 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 1066 if(total
==0&& STp
->eof
== ST_FM
) { 1069 (STp
->mt_status
)->mt_fileno
++; 1071 if(total
==0&& STp
->eof
== ST_EOM_OK
) 1072 return(-EIO
);/* ST_EOM_ERROR not used in read */ 1076 if(STp
->block_size
==0) 1077 count
= total
;/* Read only one variable length block */ 1079 }/* for (total = 0; total < count; ) */ 1081 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 1088 /* Set the driver options */ 1090 st_set_options(struct inode
* inode
,long options
) 1095 dev
=MINOR(inode
->i_rdev
) &127; 1096 STp
= &(scsi_tapes
[dev
]); 1097 if((options
& MT_ST_OPTIONS
) == MT_ST_BOOLEANS
) { 1098 STp
->do_buffer_writes
= (options
& MT_ST_BUFFER_WRITES
) !=0; 1099 STp
->do_async_writes
= (options
& MT_ST_ASYNC_WRITES
) !=0; 1100 STp
->do_read_ahead
= (options
& MT_ST_READ_AHEAD
) !=0; 1102 debugging
= (options
& MT_ST_DEBUGGING
) !=0; 1104 "st%d: options: buffer writes: %d, async writes: %d, read ahead: %d\n", 1105 dev
, STp
->do_buffer_writes
, STp
->do_async_writes
, 1106 STp
->do_read_ahead
); 1107 printk(" debugging: %d\n", debugging
); 1110 else if((options
& MT_ST_OPTIONS
) == MT_ST_WRITE_THRESHOLD
) { 1111 value
= (options
& ~MT_ST_OPTIONS
) * ST_BLOCK_SIZE
; 1112 if(value
<1|| value
> st_buffer_size
) { 1113 printk("st: Write threshold %d too small or too large.\n", 1117 STp
->write_threshold
= value
; 1119 printk("st%d: Write threshold set to %d bytes.\n", dev
, 1120 STp
->write_threshold
); 1130 /* Internal ioctl function */ 1132 st_int_ioctl(struct inode
* inode
,struct file
* file
, 1133 unsigned int cmd_in
,unsigned long arg
) 1135 int dev
=MINOR(inode
->i_rdev
); 1136 int timeout
= ST_LONG_TIMEOUT
; 1139 unsigned char cmd
[10]; 1142 int fileno
, blkno
, undone
, datalen
; 1145 STp
= &(scsi_tapes
[dev
]); 1146 fileno
= (STp
->mt_status
)->mt_fileno
; 1147 blkno
= STp
->drv_block
; 1155 cmd
[1] =0x01;/* Space FileMarks */ 1156 cmd
[2] = (arg
>>16); 1161 printk("st%d: Spacing tape forward over %d filemarks.\n", dev
, 1162 cmd
[2] *65536+ cmd
[3] *256+ cmd
[4]); 1170 cmd
[1] =0x01;/* Space FileMarks */ 1172 cmd
[2] = (ltmp
>>16); 1173 cmd
[3] = (ltmp
>>8); 1179 ltmp
= ltmp
| (cmd
[2] <<16) | (cmd
[3] <<8) | cmd
[4]; 1180 printk("st%d: Spacing tape backward over %ld filemarks.\n", dev
, (-ltmp
)); 1184 blkno
= (-1);/* We can't know the block number */ 1188 cmd
[1] =0x00;/* Space Blocks */ 1189 cmd
[2] = (arg
>>16); 1194 printk("st%d: Spacing tape forward %d blocks.\n", dev
, 1195 cmd
[2] *65536+ cmd
[3] *256+ cmd
[4]); 1202 cmd
[1] =0x00;/* Space Blocks */ 1204 cmd
[2] = (ltmp
>>16); 1205 cmd
[3] = (ltmp
>>8); 1211 ltmp
= ltmp
| (cmd
[2] <<16) | (cmd
[3] <<8) | cmd
[4]; 1212 printk("st%d: Spacing tape backward %ld blocks.\n", dev
, (-ltmp
)); 1221 cmd
[0] = WRITE_FILEMARKS
; 1222 cmd
[2] = (arg
>>16); 1225 timeout
= ST_TIMEOUT
; 1228 printk("st%d: Writing %d filemarks.\n", dev
, 1229 cmd
[2] *65536+ cmd
[3] *256+ cmd
[4]); 1235 cmd
[0] = REZERO_UNIT
; 1237 cmd
[1] =1;/* Don't wait for completion */ 1238 timeout
= ST_TIMEOUT
; 1242 printk("st%d: Rewinding tape.\n", dev
); 1247 cmd
[0] = START_STOP
; 1249 cmd
[1] =1;/* Don't wait for completion */ 1250 timeout
= ST_TIMEOUT
; 1254 printk("st%d: Unloading tape.\n", dev
); 1261 printk("st%d: No op on tape.\n", dev
); 1263 return0;/* Should do something ? */ 1266 cmd
[0] = START_STOP
; 1268 cmd
[1] =1;/* Don't wait for completion */ 1269 timeout
= ST_TIMEOUT
; 1274 printk("st%d: Retensioning tape.\n", dev
); 1279 /* space to the end of tape */ 1280 ioctl_result
=st_int_ioctl(inode
, file
, MTFSF
,0x3fff); 1281 fileno
= (STp
->mt_status
)->mt_fileno
; 1282 /* The next lines would hide the number of spaced FileMarks 1283 That's why I inserted the previous lines. I had no luck 1284 with detecting EOM with FSF, so we go now to EOM. 1290 printk("st%d: Spacing to end of recorded medium.\n", dev
); 1298 cmd
[1] =1;/* To the end of tape */ 1301 printk("st%d: Erasing tape.\n", dev
); 1306 if((STp
->device
)->scsi_level
< SCSI_2
) { 1307 cmd
[0] = QFA_SEEK_BLOCK
; 1308 cmd
[2] = (arg
>>16); 1316 cmd
[3] = (arg
>>24); 1317 cmd
[4] = (arg
>>16); 1322 cmd
[1] |=1;/* Don't wait for completion */ 1323 timeout
= ST_TIMEOUT
; 1327 printk("st%d: Seeking tape to block %ld.\n", dev
, arg
); 1329 fileno
= blkno
= (-1); 1331 case MTSETBLK
:/* Set block length */ 1332 case MTSETDENSITY
:/* Set tape density */ 1333 case MTSETDRVBUFFER
:/* Set drive buffering */ 1334 if(STp
->dirty
|| (STp
->buffer
)->buffer_bytes
!=0) 1335 return(-EIO
);/* Not allowed if data in buffer */ 1336 if(cmd_in
== MTSETBLK
&& 1338 (arg
< STp
->min_block
|| arg
> STp
->max_block
|| 1339 arg
> st_buffer_size
)) { 1340 printk("st%d: Illegal block size.\n", dev
); 1343 cmd
[0] = MODE_SELECT
; 1344 cmd
[4] = datalen
=12; 1346 memset((STp
->buffer
)->b_data
,0,12); 1347 if(cmd_in
== MTSETDRVBUFFER
) 1348 (STp
->buffer
)->b_data
[2] = (arg
&7) <<4; 1350 (STp
->buffer
)->b_data
[2] = 1351 STp
->drv_buffer
<<4; 1352 (STp
->buffer
)->b_data
[3] =8;/* block descriptor length */ 1353 if(cmd_in
== MTSETDENSITY
) 1354 (STp
->buffer
)->b_data
[4] = arg
; 1356 (STp
->buffer
)->b_data
[4] = STp
->density
; 1357 if(cmd_in
== MTSETBLK
) 1360 ltmp
= STp
->block_size
; 1361 (STp
->buffer
)->b_data
[9] = (ltmp
>>16); 1362 (STp
->buffer
)->b_data
[10] = (ltmp
>>8); 1363 (STp
->buffer
)->b_data
[11] = ltmp
; 1364 timeout
= ST_TIMEOUT
; 1367 if(cmd_in
== MTSETBLK
) 1368 printk("st%d: Setting block size to %d bytes.\n", dev
, 1369 (STp
->buffer
)->b_data
[9] *65536+ 1370 (STp
->buffer
)->b_data
[10] *256+ 1371 (STp
->buffer
)->b_data
[11]); 1372 else if(cmd_in
== MTSETDENSITY
) 1373 printk("st%d: Setting density code to %x.\n", dev
, 1374 (STp
->buffer
)->b_data
[4]); 1376 printk("st%d: Setting drive buffer code to %d.\n", dev
, 1377 ((STp
->buffer
)->b_data
[2] >>4) &7); 1382 printk("st%d: Unknown st_ioctl command %x.\n", dev
, cmd_in
); 1386 SCpnt
=allocate_device(NULL
, (STp
->device
)->index
,1); 1387 SCpnt
->sense_buffer
[0] =0; 1388 SCpnt
->request
.dev
= dev
; 1390 (void*) cmd
, (void*) (STp
->buffer
)->b_data
, datalen
, 1391 st_sleep_done
, timeout
, MAX_RETRIES
); 1393 if(SCpnt
->request
.dev
== dev
)sleep_on( &(STp
->waiting
) ); 1395 ioctl_result
= (STp
->buffer
)->last_result_fatal
; 1397 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 1400 STp
->drv_block
= blkno
; 1401 (STp
->mt_status
)->mt_fileno
= fileno
; 1402 if(cmd_in
== MTBSFM
) 1403 ioctl_result
=st_int_ioctl(inode
, file
, MTFSF
,1); 1404 else if(cmd_in
== MTFSFM
) 1405 ioctl_result
=st_int_ioctl(inode
, file
, MTBSF
,1); 1406 else if(cmd_in
== MTSETBLK
) { 1407 STp
->block_size
= arg
; 1409 (STp
->buffer
)->buffer_blocks
= 1410 st_buffer_size
/ STp
->block_size
; 1411 (STp
->buffer
)->buffer_size
= 1412 (STp
->buffer
)->buffer_blocks
* STp
->block_size
; 1415 (STp
->buffer
)->buffer_blocks
=1; 1416 (STp
->buffer
)->buffer_size
= st_buffer_size
; 1418 (STp
->buffer
)->buffer_bytes
= 1419 (STp
->buffer
)->read_pointer
=0; 1421 else if(cmd_in
== MTSETDRVBUFFER
) 1422 STp
->drv_buffer
= arg
; 1423 else if(cmd_in
== MTSETDENSITY
) 1425 else if(cmd_in
== MTEOM
|| cmd_in
== MTWEOF
) { 1426 STp
->eof
= ST_EOM_OK
; 1429 else if(cmd_in
!= MTSETBLK
&& cmd_in
!= MTNOP
) { 1430 STp
->eof
= ST_NOEOF
; 1434 if(SCpnt
->sense_buffer
[2] &0x40) { 1435 STp
->eof
= ST_EOM_OK
; 1440 (SCpnt
->sense_buffer
[3] <<24) + 1441 (SCpnt
->sense_buffer
[4] <<16) + 1442 (SCpnt
->sense_buffer
[5] <<8) + 1443 SCpnt
->sense_buffer
[6] ); 1444 if( (cmd_in
== MTFSF
) || (cmd_in
== MTFSFM
) ) 1445 (STp
->mt_status
)->mt_fileno
= fileno
- undone
; 1446 else if( (cmd_in
== MTBSF
) || (cmd_in
== MTBSFM
) ) 1447 (STp
->mt_status
)->mt_fileno
= fileno
+ undone
; 1448 else if(cmd_in
== MTFSR
) { 1450 STp
->drv_block
= blkno
- undone
; 1452 STp
->drv_block
= (-1); 1454 else if(cmd_in
== MTBSR
&& blkno
>=0) { 1456 STp
->drv_block
= blkno
+ undone
; 1458 STp
->drv_block
= (-1); 1462 return ioctl_result
; 1467 /* The ioctl command */ 1469 st_ioctl(struct inode
* inode
,struct file
* file
, 1470 unsigned int cmd_in
,unsigned long arg
) 1472 int dev
=MINOR(inode
->i_rdev
); 1475 struct mtpos mt_pos
; 1476 unsigned char scmd
[10]; 1481 STp
= &(scsi_tapes
[dev
]); 1483 if(debugging
&& !STp
->in_use
) { 1484 printk("st%d: Incorrect device.\n", dev
); 1489 cmd
= cmd_in
& IOCCMD_MASK
; 1490 if(cmd
== (MTIOCTOP
& IOCCMD_MASK
)) { 1492 if(((cmd_in
& IOCSIZE_MASK
) >> IOCSIZE_SHIFT
) !=sizeof(mtc
)) 1495 i
=verify_area(VERIFY_WRITE
, (void*)arg
,sizeof(mtc
)); 1499 memcpy_fromfs((char*) &mtc
, (char*)arg
,sizeof(struct mtop
)); 1501 i
=flush_buffer(inode
, file
, mtc
.mt_op
== MTSEEK
|| 1502 mtc
.mt_op
== MTREW
|| mtc
.mt_op
== MTOFFL
|| 1503 mtc
.mt_op
== MTRETEN
|| mtc
.mt_op
== MTEOM
); 1507 if(mtc
.mt_op
== MTSETDRVBUFFER
&& 1508 (mtc
.mt_count
& MT_ST_OPTIONS
) !=0) 1509 returnst_set_options(inode
, mtc
.mt_count
); 1511 returnst_int_ioctl(inode
, file
, mtc
.mt_op
, mtc
.mt_count
); 1513 else if(cmd
== (MTIOCGET
& IOCCMD_MASK
)) { 1515 if(((cmd_in
& IOCSIZE_MASK
) >> IOCSIZE_SHIFT
) !=sizeof(struct mtget
)) 1517 i
=verify_area(VERIFY_WRITE
, (void*)arg
,sizeof(struct mtget
)); 1521 (STp
->mt_status
)->mt_dsreg
= 1522 ((STp
->block_size
<< MT_ST_BLKSIZE_SHIFT
) & MT_ST_BLKSIZE_MASK
) | 1523 ((STp
->density
<< MT_ST_DENSITY_SHIFT
) & MT_ST_DENSITY_MASK
); 1524 (STp
->mt_status
)->mt_blkno
= STp
->drv_block
; 1525 if(STp
->block_size
!=0) { 1526 if(STp
->rw
== ST_WRITING
) 1527 (STp
->mt_status
)->mt_blkno
+= 1528 (STp
->buffer
)->buffer_bytes
/ STp
->block_size
; 1529 else if(STp
->rw
== ST_READING
) 1530 (STp
->mt_status
)->mt_blkno
-= ((STp
->buffer
)->buffer_bytes
+ 1531 STp
->block_size
-1) / STp
->block_size
; 1534 memcpy_tofs((char*)arg
, (char*)(STp
->mt_status
), 1535 sizeof(struct mtget
)); 1537 (STp
->mt_status
)->mt_erreg
=0;/* Clear after read */ 1540 else if(cmd
== (MTIOCPOS
& IOCCMD_MASK
)) { 1543 printk("st%d: get tape position.\n", dev
); 1545 if(((cmd_in
& IOCSIZE_MASK
) >> IOCSIZE_SHIFT
) !=sizeof(struct mtpos
)) 1548 i
=flush_buffer(inode
, file
,0); 1552 i
=verify_area(VERIFY_WRITE
, (void*)arg
,sizeof(struct mtpos
)); 1556 SCpnt
=allocate_device(NULL
, (STp
->device
)->index
,1); 1558 SCpnt
->sense_buffer
[0]=0; 1560 if((STp
->device
)->scsi_level
< SCSI_2
) { 1561 scmd
[0] = QFA_REQUEST_BLOCK
; 1565 scmd
[0] = READ_POSITION
; 1568 SCpnt
->request
.dev
= dev
; 1569 SCpnt
->sense_buffer
[0] =0; 1571 (void*) scmd
, (void*) (STp
->buffer
)->b_data
, 1572 20, st_sleep_done
, ST_TIMEOUT
, MAX_READY_RETRIES
); 1574 if(SCpnt
->request
.dev
== dev
)sleep_on( &(STp
->waiting
) ); 1576 if((STp
->buffer
)->last_result_fatal
!=0) { 1577 mt_pos
.mt_blkno
= (-1); 1580 printk("st%d: Can't read tape position.\n", dev
); 1586 if((STp
->device
)->scsi_level
< SCSI_2
) 1587 mt_pos
.mt_blkno
= ((STp
->buffer
)->b_data
[0] <<16) 1588 + ((STp
->buffer
)->b_data
[1] <<8) 1589 + (STp
->buffer
)->b_data
[2]; 1591 mt_pos
.mt_blkno
= ((STp
->buffer
)->b_data
[4] <<24) 1592 + ((STp
->buffer
)->b_data
[5] <<16) 1593 + ((STp
->buffer
)->b_data
[6] <<8) 1594 + (STp
->buffer
)->b_data
[7]; 1598 SCpnt
->request
.dev
= -1;/* Mark as not busy */ 1600 memcpy_tofs((char*)arg
, (char*) (&mt_pos
),sizeof(struct mtpos
)); 1604 returnscsi_ioctl(STp
->device
, cmd_in
, (void*) arg
); 1608 /* Set the boot options. Syntax: st=xxx,yyy 1609 where xxx is buffer size in 512 byte blocks and yyy is write threshold 1610 in 512 byte blocks. */ 1612 st_setup(char*str
,int*ints
) 1614 if(ints
[0] >0&& ints
[1] >0) 1615 st_buffer_size
= ints
[1] * ST_BLOCK_SIZE
; 1616 if(ints
[0] >1&& ints
[2] >0) { 1617 st_write_threshold
= ints
[2] * ST_BLOCK_SIZE
; 1618 if(st_write_threshold
> st_buffer_size
) 1619 st_write_threshold
= st_buffer_size
; 1621 if(ints
[0] >2&& ints
[3] >0) 1622 st_max_buffers
= ints
[3]; 1626 static struct file_operations st_fops
= { 1627 NULL
,/* lseek - default */ 1628 st_read
,/* read - general block-dev read */ 1629 st_write
,/* write - general block-dev write */ 1630 NULL
,/* readdir - bad */ 1632 st_ioctl
,/* ioctl */ 1634 scsi_tape_open
,/* open */ 1635 scsi_tape_close
,/* release */ 1639 voidst_attach(Scsi_Device
* SDp
){ 1640 scsi_tapes
[NR_ST
++].device
= SDp
; 1641 if(NR_ST
> MAX_ST
)panic("scsi_devices corrupt (st)"); 1644 unsigned longst_init1(unsigned long mem_start
,unsigned long mem_end
){ 1645 scsi_tapes
= (Scsi_Tape
*) mem_start
; 1646 mem_start
+= MAX_ST
*sizeof(Scsi_Tape
); 1650 /* Driver initialization */ 1651 unsigned longst_init(unsigned long mem_start
,unsigned long mem_end
) 1656 if(register_chrdev(MAJOR_NR
,"st",&st_fops
)) { 1657 printk("Unable to get major %d for SCSI tapes\n",MAJOR_NR
); 1660 if(NR_ST
==0)return mem_start
; 1663 printk("st: Buffer size %d bytes, write threshold %d bytes.\n", 1664 st_buffer_size
, st_write_threshold
); 1667 for(i
=0, dev_nbr
=(-1); i
< NR_ST
; ++i
) { 1668 STp
= &(scsi_tapes
[i
]); 1669 STp
->capacity
=0xfffff; 1672 STp
->eof
= ST_NOEOF
; 1673 STp
->waiting
= NULL
; 1675 STp
->drv_buffer
=1;/* Try buffering if no mode sense */ 1677 STp
->do_buffer_writes
= ST_BUFFER_WRITES
; 1678 STp
->do_async_writes
= ST_ASYNC_WRITES
; 1679 STp
->do_read_ahead
= ST_READ_AHEAD
; 1680 STp
->write_threshold
= st_write_threshold
; 1682 STp
->mt_status
= (struct mtget
*) mem_start
; 1683 mem_start
+=sizeof(struct mtget
); 1684 /* Initialize status */ 1685 memset((void*) scsi_tapes
[i
].mt_status
,0,sizeof(struct mtget
)); 1686 for(dev_nbr
++; dev_nbr
< NR_SCSI_DEVICES
; dev_nbr
++) 1687 if(scsi_devices
[dev_nbr
].type
== TYPE_TAPE
) 1689 if(dev_nbr
>= NR_SCSI_DEVICES
) 1690 printk("st%d: ERROR: Not found in scsi chain.\n", i
); 1692 if(scsi_devices
[dev_nbr
].scsi_level
<=2) 1693 STp
->mt_status
->mt_type
= MT_ISSCSI1
; 1695 STp
->mt_status
->mt_type
= MT_ISSCSI2
; 1699 /* Allocate the buffers */ 1700 st_nbr_buffers
= NR_ST
; 1701 if(st_nbr_buffers
> st_max_buffers
) 1702 st_nbr_buffers
= st_max_buffers
; 1703 st_buffers
= (ST_buffer
**)mem_start
; 1704 mem_start
+= st_nbr_buffers
*sizeof(ST_buffer
*); 1705 for(i
=0; i
< st_nbr_buffers
; i
++) { 1706 st_buffers
[i
] = (ST_buffer
*) mem_start
; 1708 /* printk("st: Buffer address: %p\n", st_buffers[i]); */ 1710 mem_start
+=sizeof(ST_buffer
) -1+ st_buffer_size
; 1711 st_buffers
[i
]->in_use
=0; 1712 st_buffers
[i
]->writing
=0;