Import 1.1.12
[davej-history.git] / drivers / scsi / st.c
blobfaf4cdd96c36d31e6e5d732064e2a1b8c9d69d3d
1 /*
2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
3 file README.st for more information.
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.
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
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>
28 #define MAJOR_NR SCSI_TAPE_MAJOR
29 #include"../block/blk.h"
30 #include"scsi.h"
31 #include"scsi_ioctl.h"
32 #include"st.h"
33 #include"constants.h"
35 /* #define DEBUG */
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!"
64 #endif
66 #ifdef DEBUG
67 static int debugging =1;
68 #endif
70 #define MAX_RETRIES 0
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;
84 int NR_ST=0;
85 int MAX_ST=0;
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 */
94 static int
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;
100 char*stp;
102 if(!result && SCpnt->sense_buffer[0] ==0)
103 return0;
104 #ifdef DEBUG
105 if(debugging) {
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);
113 #endif
114 /* if ((sense[0] & 0x70) == 0x70 &&
115 ((sense[2] & 0x80) ))
116 return 0; */
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
122 #endif
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)
127 stp ="read";
128 else if(SCpnt->cmnd[0] == WRITE_6)
129 stp ="write";
130 else
131 stp ="ioctl";
132 printk("st%d: Recovered %s error (%d).\n", dev, stp,
133 scsi_tapes[dev].recover_count);
134 return0;
136 return(-EIO);
140 /* Wakeup from interrupt */
141 static void
142 st_sleep_done(Scsi_Cmnd * SCpnt)
144 int st_nbr, remainder;
145 Scsi_Tape * STp;
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];
157 else
158 remainder =0;
159 if((SCpnt->sense_buffer[2] &0x0f) == VOLUME_OVERFLOW ||
160 remainder >0)
161 (STp->buffer)->last_result = SCpnt->result;/* Error */
162 else
163 (STp->buffer)->last_result = INT_MAX;/* OK */
165 else
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;
170 else
171 SCpnt->request.dev =0xffff;
172 if((STp->buffer)->writing <=0)
173 wake_up( &(STp->waiting) );
175 #ifdef DEBUG
176 else if(debugging)
177 printk("st?: Illegal interrupt device %x\n", st_nbr);
178 #endif
182 /* Handle the write-behind checking */
183 static void
184 write_behind_check(int dev)
186 Scsi_Tape * STp;
187 ST_buffer * STbuffer;
189 STp = &(scsi_tapes[dev]);
190 STbuffer = STp->buffer;
192 cli();
193 if(STbuffer->last_result <0) {
194 STbuffer->writing = (- STbuffer->writing);
195 sleep_on( &(STp->waiting) );
196 STbuffer->writing = (- STbuffer->writing);
198 sti();
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)
207 STp->drv_block++;
208 else
209 STp->drv_block += STbuffer->writing / STp->block_size;
211 STbuffer->writing =0;
213 return;
217 /* Back over EOF if it has been inadvertently crossed (ioctl not used because
218 it messes up the block number). */
219 static int
220 back_over_eof(int dev)
222 Scsi_Cmnd *SCpnt;
223 Scsi_Tape *STp = &(scsi_tapes[dev]);
224 unsigned char cmd[10];
226 cmd[0] = SPACE;
227 cmd[1] =0x01;/* Space FileMarks */
228 cmd[2] = cmd[3] = cmd[4] =0xff;/* -1 filemarks */
229 cmd[5] =0;
231 SCpnt =allocate_device(NULL, (STp->device)->index,1);
232 SCpnt->sense_buffer[0] =0;
233 SCpnt->request.dev = dev;
234 scsi_do_cmd(SCpnt,
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). */
246 static int
247 flush_write_buffer(int dev)
249 int offset, transfer, blks;
250 int result;
251 unsigned char cmd[10];
252 Scsi_Cmnd *SCpnt;
253 Scsi_Tape *STp = &(scsi_tapes[dev]);
255 if((STp->buffer)->writing) {
256 write_behind_check(dev);
257 if((STp->buffer)->last_result_fatal) {
258 #ifdef DEBUG
259 if(debugging)
260 printk("st%d: Async write error (flush) %x.\n", dev,
261 (STp->buffer)->last_result);
262 #endif
263 if((STp->buffer)->last_result == INT_MAX)
264 return(-ENOSPC);
265 return(-EIO);
269 result =0;
270 if(STp->dirty ==1) {
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;
276 #ifdef DEBUG
277 if(debugging)
278 printk("st%d: Flushing %d bytes.\n", dev, transfer);
279 #endif
280 memset((STp->buffer)->b_data + offset,0, transfer - offset);
282 SCpnt->sense_buffer[0] =0;
283 memset(cmd,0,10);
284 cmd[0] = WRITE_6;
285 cmd[1] =1;
286 blks = transfer / STp->block_size;
287 cmd[2] = blks >>16;
288 cmd[3] = blks >>8;
289 cmd[4] = blks;
290 SCpnt->request.dev = dev;
291 scsi_do_cmd(SCpnt,
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) {
302 STp->dirty =0;
303 (STp->buffer)->buffer_bytes =0;
304 result = (-ENOSPC);
306 else
307 result = (-EIO);
308 STp->drv_block = (-1);
310 else{
311 if(STp->drv_block >=0)
312 STp->drv_block += blks;
313 STp->dirty =0;
314 (STp->buffer)->buffer_bytes =0;
316 SCpnt->request.dev = -1;/* Mark as not busy */
318 return result;
322 /* Flush the tape buffer. The tape will be positioned correctly unless
323 seek_next is true. */
324 static int
325 flush_buffer(struct inode * inode,struct file * filp,int seek_next)
327 int dev;
328 int backspace, result;
329 Scsi_Tape * STp;
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)
340 return0;
342 backspace = ((STp->buffer)->buffer_bytes +
343 (STp->buffer)->read_pointer) / STp->block_size -
344 ((STp->buffer)->read_pointer + STp->block_size -1) /
345 STp->block_size;
346 (STp->buffer)->buffer_bytes =0;
347 (STp->buffer)->read_pointer =0;
348 result =0;
349 if(!seek_next) {
350 if((STp->eof == ST_FM) && !STp->eof_hit) {
351 result =back_over_eof(dev);/* Back over the EOF hit */
352 if(!result) {
353 STp->eof = ST_NOEOF;
354 STp->eof_hit =0;
357 if(!result && backspace >0)
358 result =st_int_ioctl(inode, filp, MTBSR, backspace);
360 return result;
365 /* Open the device */
366 static int
367 scsi_tape_open(struct inode * inode,struct file * filp)
369 int dev;
370 unsigned short flags;
371 int i;
372 unsigned char cmd[10];
373 Scsi_Cmnd * SCpnt;
374 Scsi_Tape * STp;
376 dev =MINOR(inode->i_rdev) &127;
377 if(dev >= NR_ST)
378 return(-ENXIO);
379 STp = &(scsi_tapes[dev]);
380 if(STp->in_use) {
381 printk("st%d: Device already in use.\n", dev);
382 return(-EBUSY);
385 /* Allocate buffer for this user */
386 for(i=0; i < st_nbr_buffers; i++)
387 if(!st_buffers[i]->in_use)
388 break;
389 if(i >= st_nbr_buffers) {
390 printk("st%d: No free buffers.\n", dev);
391 return(-EBUSY);
393 STp->buffer = st_buffers[i];
394 (STp->buffer)->in_use =1;
395 (STp->buffer)->writing =0;
396 STp->in_use =1;
398 flags = filp->f_flags;
399 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
401 STp->dirty =0;
402 STp->rw = ST_IDLE;
403 STp->eof = ST_NOEOF;
404 STp->eof_hit =0;
405 STp->recover_count =0;
407 SCpnt =allocate_device(NULL, (STp->device)->index,1);
408 if(!SCpnt) {
409 printk("st%d: Tape request not allocated", dev);
410 return(-EBUSY);
413 SCpnt->sense_buffer[0]=0;
414 memset((void*) &cmd[0],0,10);
415 cmd[0] = TEST_UNIT_READY;
416 SCpnt->request.dev = dev;
417 scsi_do_cmd(SCpnt,
418 (void*) cmd, (void*) (STp->buffer)->b_data,
419 0, st_sleep_done, ST_LONG_TIMEOUT,
420 MAX_READY_RETRIES);
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;
431 scsi_do_cmd(SCpnt,
432 (void*) cmd, (void*) (STp->buffer)->b_data,
433 0, st_sleep_done, ST_LONG_TIMEOUT,
434 MAX_READY_RETRIES);
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);
445 }else{
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;
450 STp->in_use =0;
451 SCpnt->request.dev = -1;/* Mark as not busy */
452 return(-EIO);
455 SCpnt->sense_buffer[0]=0;
456 memset((void*) &cmd[0],0,10);
457 cmd[0] = READ_BLOCK_LIMITS;
458 SCpnt->request.dev = dev;
459 scsi_do_cmd(SCpnt,
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];
470 #ifdef DEBUG
471 if(debugging)
472 printk("st%d: Block limits %d - %d bytes.\n", dev, STp->min_block,
473 STp->max_block);
474 #endif
476 else{
477 STp->min_block = STp->max_block = (-1);
478 #ifdef DEBUG
479 if(debugging)
480 printk("st%d: Can't read block limits.\n", dev);
481 #endif
484 SCpnt->sense_buffer[0]=0;
485 memset((void*) &cmd[0],0,10);
486 cmd[0] = MODE_SENSE;
487 cmd[4] =12;
488 SCpnt->request.dev = dev;
489 scsi_do_cmd(SCpnt,
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) {
496 #ifdef DEBUG
497 if(debugging)
498 printk("st%d: No Mode Sense.\n", dev);
499 #endif
500 (STp->buffer)->b_data[2] =
501 (STp->buffer)->b_data[3] =0;
503 SCpnt->request.dev = -1;/* Mark as not busy */
505 #ifdef DEBUG
506 if(debugging)
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]);
510 #endif
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];
517 #ifdef DEBUG
518 if(debugging)
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);
523 #endif
524 if(STp->block_size > st_buffer_size) {
525 printk("st%d: Blocksize %d too large for buffer.\n", dev,
526 STp->block_size);
527 (STp->buffer)->in_use =0;
528 STp->in_use =0;
529 return(-EIO);
533 else
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;
541 else{
542 (STp->buffer)->buffer_blocks =1;
543 (STp->buffer)->buffer_size = st_buffer_size;
545 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer =0;
547 #ifdef DEBUG
548 if(debugging)
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);
552 #endif
554 if((STp->buffer)->b_data[2] &0x80) {
555 STp->write_prot =1;
556 #ifdef DEBUG
557 if(debugging)
558 printk("st%d: Write protected\n", dev);
559 #endif
562 return0;
566 /* Close the device*/
567 static void
568 scsi_tape_close(struct inode * inode,struct file * filp)
570 int dev;
571 int result;
572 int rewind;
573 static unsigned char cmd[10];
574 Scsi_Cmnd * SCpnt;
575 Scsi_Tape * STp;
577 dev =MINOR(inode->i_rdev);
578 rewind = (dev &0x80) ==0;
579 dev = dev &127;
580 STp = &(scsi_tapes[dev]);
582 if( STp->rw == ST_WRITING) {
584 result =flush_write_buffer(dev);
586 #ifdef DEBUG
587 if(debugging)
588 printk("st%d: File length %ld bytes.\n", dev, filp->f_pos);
589 #endif
591 if(result ==0|| result == (-ENOSPC)) {
592 SCpnt =allocate_device(NULL, (STp->device)->index,1);
594 SCpnt->sense_buffer[0] =0;
595 memset(cmd,0,10);
596 cmd[0] = WRITE_FILEMARKS;
597 cmd[4] =1;
598 SCpnt->request.dev = dev;
599 scsi_do_cmd( SCpnt,
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);
607 else{
608 (STp->mt_status)->mt_fileno++ ;
609 STp->drv_block =0;
612 SCpnt->request.dev = -1;/* Mark as not busy */
615 #ifdef DEBUG
616 if(debugging)
617 printk("st%d: Buffer flushed, EOF written\n", dev);
618 #endif
620 else if(!rewind) {
621 #ifndef ST_IN_FILE_POS
622 if((STp->eof == ST_FM) && !STp->eof_hit)
623 back_over_eof(dev);
624 #else
625 flush_buffer(inode, filp,0);
626 #endif
629 if(rewind)
630 st_int_ioctl(inode, filp, MTREW,1);
632 (STp->buffer)->in_use =0;
633 STp->in_use =0;
635 return;
639 /* Write command */
640 static int
641 st_write(struct inode * inode,struct file * filp,char* buf,int count)
643 int dev;
644 int total, do_count, blks, retval, transfer;
645 int write_threshold;
646 static unsigned char cmd[10];
647 char*b_point;
648 Scsi_Cmnd * SCpnt;
649 Scsi_Tape * STp;
651 dev =MINOR(inode->i_rdev) &127;
652 STp = &(scsi_tapes[dev]);
653 #ifdef DEBUG
654 if(!STp->in_use) {
655 printk("st%d: Incorrect device.\n", dev);
656 return(-EIO);
658 #endif
660 if(STp->write_prot)
661 return(-EACCES);
663 if(STp->block_size ==0&& count > st_buffer_size)
664 return(-EOVERFLOW);
666 if(STp->rw == ST_READING) {
667 retval =flush_buffer(inode, filp,0);
668 if(retval)
669 return retval;
670 STp->rw = ST_WRITING;
673 if((STp->buffer)->writing) {
674 write_behind_check(dev);
675 if((STp->buffer)->last_result_fatal) {
676 #ifdef DEBUG
677 if(debugging)
678 printk("st%d: Async write error (write) %x.\n", dev,
679 (STp->buffer)->last_result);
680 #endif
681 if((STp->buffer)->last_result == INT_MAX) {
682 retval = (-ENOSPC);/* All has been written */
683 STp->eof = ST_EOM_OK;
685 else
686 retval = (-EIO);
687 return retval;
691 if(STp->eof == ST_EOM_OK)
692 return(-ENOSPC);
693 else if(STp->eof == ST_EOM_ERROR)
694 return(-EIO);
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 */
699 write_threshold =1;
701 else
702 write_threshold = (STp->buffer)->buffer_size;
703 if(!STp->do_async_writes)
704 write_threshold--;
706 SCpnt =allocate_device(NULL, (STp->device)->index,1);
708 total = count;
710 memset(cmd,0,10);
711 cmd[0] = WRITE_6;
712 cmd[1] = (STp->block_size !=0);
714 STp->rw = ST_WRITING;
716 b_point = buf;
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)
722 do_count = count;
723 else{
724 do_count = (STp->buffer)->buffer_size - (STp->buffer)->buffer_bytes;
725 if(do_count > count)
726 do_count = count;
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;
733 else{
734 blks = ((STp->buffer)->buffer_bytes + do_count) /
735 STp->block_size;
736 transfer = blks * STp->block_size;
738 cmd[2] = blks >>16;
739 cmd[3] = blks >>8;
740 cmd[4] = blks;
741 SCpnt->sense_buffer[0] =0;
742 SCpnt->request.dev = dev;
743 scsi_do_cmd(SCpnt,
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) {
750 #ifdef DEBUG
751 if(debugging)
752 printk("st%d: Error on write:\n", dev);
753 #endif
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)
762 transfer = do_count;
763 else
764 transfer =0;
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)
772 STp->drv_block++;
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 */
778 #ifdef DEBUG
779 if(debugging)
780 printk("st%d: EOM with %d bytes unwritten.\n",
781 dev, transfer);
782 #endif
784 else{
785 STp->eof = ST_EOM_ERROR;
786 STp->drv_block = (-1);/* Too cautious? */
787 retval = (-EIO);/* EOM for old data */
788 #ifdef DEBUG
789 if(debugging)
790 printk("st%d: EOM with lost data.\n", dev);
791 #endif
794 else{
795 STp->drv_block = (-1);/* Too cautious? */
796 retval = (-EIO);
799 SCpnt->request.dev = -1;/* Mark as not busy */
800 (STp->buffer)->buffer_bytes =0;
801 STp->dirty =0;
802 if(count < total)
803 return total - count;
804 else
805 return retval;
807 filp->f_pos += do_count;
808 b_point += do_count;
809 count -= do_count;
810 if(STp->drv_block >=0) {
811 if(STp->block_size ==0)
812 STp->drv_block++;
813 else
814 STp->drv_block += blks;
816 (STp->buffer)->buffer_bytes =0;
817 STp->dirty =0;
819 if(count !=0) {
820 STp->dirty =1;
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;
825 count =0;
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;
839 else
840 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
841 STp->block_size) * STp->block_size;
842 STp->dirty =0;
844 if(STp->block_size ==0)
845 blks = (STp->buffer)->writing;
846 else
847 blks = (STp->buffer)->writing / STp->block_size;
848 cmd[2] = blks >>16;
849 cmd[3] = blks >>8;
850 cmd[4] = blks;
851 SCpnt->result = (STp->buffer)->last_result = -1;
852 SCpnt->sense_buffer[0] =0;
853 SCpnt->request.dev = dev;
854 scsi_do_cmd(SCpnt,
855 (void*) cmd, (STp->buffer)->b_data,
856 (STp->buffer)->writing,
857 st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
859 else
860 SCpnt->request.dev = -1;/* Mark as not busy */
862 return( total);
866 /* Read command */
867 static int
868 st_read(struct inode * inode,struct file * filp,char* buf,int count)
870 int dev;
871 int total;
872 int transfer, blks, bytes;
873 static unsigned char cmd[10];
874 Scsi_Cmnd * SCpnt;
875 Scsi_Tape * STp;
877 dev =MINOR(inode->i_rdev) &127;
878 STp = &(scsi_tapes[dev]);
879 #ifdef DEBUG
880 if(!STp->in_use) {
881 printk("st%d: Incorrect device.\n", dev);
882 return(-EIO);
884 #endif
886 if(STp->block_size ==0&& count > st_buffer_size)
887 return(-EOVERFLOW);
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);
895 if(transfer)
896 return transfer;
897 STp->rw = ST_READING;
900 #ifdef DEBUG
901 if(debugging && STp->eof != ST_NOEOF)
902 printk("st%d: EOF flag up. Bytes %d\n", dev,
903 (STp->buffer)->buffer_bytes);
904 #endif
905 if(((STp->buffer)->buffer_bytes ==0) &&
906 STp->eof == ST_EOM_OK)/* EOM or Blank Check */
907 return(-EIO);
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) {
918 memset(cmd,0,10);
919 cmd[0] = READ_6;
920 cmd[1] = (STp->block_size !=0);
921 if(STp->block_size ==0)
922 blks = bytes = count;
923 else{
924 if(STp->do_read_ahead) {
925 blks = (STp->buffer)->buffer_blocks;
926 bytes = blks * STp->block_size;
928 else{
929 bytes = count;
930 if(bytes > st_buffer_size)
931 bytes = st_buffer_size;
932 blks = bytes / STp->block_size;
933 bytes = blks * STp->block_size;
936 cmd[2] = blks >>16;
937 cmd[3] = blks >>8;
938 cmd[4] = blks;
940 SCpnt->sense_buffer[0] =0;
941 SCpnt->request.dev = dev;
942 scsi_do_cmd(SCpnt,
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;
950 STp->eof_hit =0;
952 if((STp->buffer)->last_result_fatal) {
953 #ifdef DEBUG
954 if(debugging)
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]);
960 #endif
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];
969 else
970 transfer =0;
971 if(STp->block_size ==0&&
972 (SCpnt->sense_buffer[2] &0x0f) == MEDIUM_ERROR)
973 transfer = bytes;
975 if(SCpnt->sense_buffer[2] &0x20) {
976 if(STp->block_size ==0) {
977 if(transfer <=0)
978 transfer =0;
979 (STp->buffer)->buffer_bytes = bytes - transfer;
981 else{
982 printk("st%d: Incorrect block size.\n", dev);
983 SCpnt->request.dev = -1;/* Mark as not busy */
984 return(-EIO);
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;
991 else
992 (STp->buffer)->buffer_bytes =
993 bytes - transfer * STp->block_size;
994 #ifdef DEBUG
995 if(debugging)
996 printk("st%d: EOM detected (%d bytes read).\n", dev,
997 (STp->buffer)->buffer_bytes);
998 #endif
1000 else if(SCpnt->sense_buffer[2] &0x80) {
1001 STp->eof = ST_FM;
1002 if(STp->block_size ==0)
1003 (STp->buffer)->buffer_bytes =0;
1004 else
1005 (STp->buffer)->buffer_bytes =
1006 bytes - transfer * STp->block_size;
1007 #ifdef DEBUG
1008 if(debugging)
1009 printk(
1010 "st%d: EOF detected (%d bytes read, transferred %d bytes).\n",
1011 dev, (STp->buffer)->buffer_bytes, total);
1012 #endif
1013 }/* end of EOF, EOM, ILI test */
1015 else{/* nonzero sense key */
1016 #ifdef DEBUG
1017 if(debugging)
1018 printk("st%d: Tape error while reading.\n", dev);
1019 #endif
1020 SCpnt->request.dev = -1;
1021 STp->drv_block = (-1);
1022 if(total)
1023 return total;
1024 else
1025 return-EIO;
1028 else{
1029 transfer = (STp->buffer)->last_result_fatal;
1030 SCpnt->request.dev = -1;/* Mark as not busy */
1031 return transfer;
1034 else/* Read successful */
1035 (STp->buffer)->buffer_bytes = bytes;
1037 if(STp->drv_block >=0) {
1038 if(STp->block_size ==0)
1039 STp->drv_block++;
1040 else
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) {
1048 #ifdef DEBUG
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);
1052 #endif
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;
1058 buf += transfer;
1059 total += transfer;
1060 (STp->buffer)->buffer_bytes -= transfer;
1061 (STp->buffer)->read_pointer += transfer;
1063 else if(STp->eof != ST_NOEOF) {
1064 STp->eof_hit =1;
1065 SCpnt->request.dev = -1;/* Mark as not busy */
1066 if(total ==0&& STp->eof == ST_FM) {
1067 STp->eof =0;
1068 STp->drv_block =0;
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 */
1073 return total;
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 */
1083 return total;
1088 /* Set the driver options */
1089 static int
1090 st_set_options(struct inode * inode,long options)
1092 int dev, value;
1093 Scsi_Tape *STp;
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;
1101 #ifdef DEBUG
1102 debugging = (options & MT_ST_DEBUGGING) !=0;
1103 printk(
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);
1108 #endif
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",
1114 value);
1115 return(-EIO);
1117 STp->write_threshold = value;
1118 #ifdef DEBUG
1119 printk("st%d: Write threshold set to %d bytes.\n", dev,
1120 STp->write_threshold);
1121 #endif
1123 else
1124 return(-EIO);
1126 return0;
1130 /* Internal ioctl function */
1131 static int
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;
1137 long ltmp;
1138 int ioctl_result;
1139 unsigned char cmd[10];
1140 Scsi_Cmnd * SCpnt;
1141 Scsi_Tape * STp;
1142 int fileno, blkno, undone, datalen;
1144 dev = dev &127;
1145 STp = &(scsi_tapes[dev]);
1146 fileno = (STp->mt_status)->mt_fileno ;
1147 blkno = STp->drv_block;
1149 memset(cmd,0,10);
1150 datalen =0;
1151 switch(cmd_in) {
1152 case MTFSF:
1153 case MTFSFM:
1154 cmd[0] = SPACE;
1155 cmd[1] =0x01;/* Space FileMarks */
1156 cmd[2] = (arg >>16);
1157 cmd[3] = (arg >>8);
1158 cmd[4] = arg;
1159 #ifdef DEBUG
1160 if(debugging)
1161 printk("st%d: Spacing tape forward over %d filemarks.\n", dev,
1162 cmd[2] *65536+ cmd[3] *256+ cmd[4]);
1163 #endif
1164 fileno += arg;
1165 blkno =0;
1166 break;
1167 case MTBSF:
1168 case MTBSFM:
1169 cmd[0] = SPACE;
1170 cmd[1] =0x01;/* Space FileMarks */
1171 ltmp = (-arg);
1172 cmd[2] = (ltmp >>16);
1173 cmd[3] = (ltmp >>8);
1174 cmd[4] = ltmp;
1175 #ifdef DEBUG
1176 if(debugging) {
1177 if(cmd[2] &0x80)
1178 ltmp =0xff000000;
1179 ltmp = ltmp | (cmd[2] <<16) | (cmd[3] <<8) | cmd[4];
1180 printk("st%d: Spacing tape backward over %ld filemarks.\n", dev, (-ltmp));
1182 #endif
1183 fileno -= arg;
1184 blkno = (-1);/* We can't know the block number */
1185 break;
1186 case MTFSR:
1187 cmd[0] = SPACE;
1188 cmd[1] =0x00;/* Space Blocks */
1189 cmd[2] = (arg >>16);
1190 cmd[3] = (arg >>8);
1191 cmd[4] = arg;
1192 #ifdef DEBUG
1193 if(debugging)
1194 printk("st%d: Spacing tape forward %d blocks.\n", dev,
1195 cmd[2] *65536+ cmd[3] *256+ cmd[4]);
1196 #endif
1197 if(blkno >=0)
1198 blkno += arg;
1199 break;
1200 case MTBSR:
1201 cmd[0] = SPACE;
1202 cmd[1] =0x00;/* Space Blocks */
1203 ltmp = (-arg);
1204 cmd[2] = (ltmp >>16);
1205 cmd[3] = (ltmp >>8);
1206 cmd[4] = ltmp;
1207 #ifdef DEBUG
1208 if(debugging) {
1209 if(cmd[2] &0x80)
1210 ltmp =0xff000000;
1211 ltmp = ltmp | (cmd[2] <<16) | (cmd[3] <<8) | cmd[4];
1212 printk("st%d: Spacing tape backward %ld blocks.\n", dev, (-ltmp));
1214 #endif
1215 if(blkno >=0)
1216 blkno -= arg;
1217 break;
1218 case MTWEOF:
1219 if(STp->write_prot)
1220 return(-EACCES);
1221 cmd[0] = WRITE_FILEMARKS;
1222 cmd[2] = (arg >>16);
1223 cmd[3] = (arg >>8);
1224 cmd[4] = arg;
1225 timeout = ST_TIMEOUT;
1226 #ifdef DEBUG
1227 if(debugging)
1228 printk("st%d: Writing %d filemarks.\n", dev,
1229 cmd[2] *65536+ cmd[3] *256+ cmd[4]);
1230 #endif
1231 fileno += arg;
1232 blkno =0;
1233 break;
1234 case MTREW:
1235 cmd[0] = REZERO_UNIT;
1236 #ifdef ST_NOWAIT
1237 cmd[1] =1;/* Don't wait for completion */
1238 timeout = ST_TIMEOUT;
1239 #endif
1240 #ifdef DEBUG
1241 if(debugging)
1242 printk("st%d: Rewinding tape.\n", dev);
1243 #endif
1244 fileno = blkno =0;
1245 break;
1246 case MTOFFL:
1247 cmd[0] = START_STOP;
1248 #ifdef ST_NOWAIT
1249 cmd[1] =1;/* Don't wait for completion */
1250 timeout = ST_TIMEOUT;
1251 #endif
1252 #ifdef DEBUG
1253 if(debugging)
1254 printk("st%d: Unloading tape.\n", dev);
1255 #endif
1256 fileno = blkno =0;
1257 break;
1258 case MTNOP:
1259 #ifdef DEBUG
1260 if(debugging)
1261 printk("st%d: No op on tape.\n", dev);
1262 #endif
1263 return0;/* Should do something ? */
1264 break;
1265 case MTRETEN:
1266 cmd[0] = START_STOP;
1267 #ifdef ST_NOWAIT
1268 cmd[1] =1;/* Don't wait for completion */
1269 timeout = ST_TIMEOUT;
1270 #endif
1271 cmd[4] =3;
1272 #ifdef DEBUG
1273 if(debugging)
1274 printk("st%d: Retensioning tape.\n", dev);
1275 #endif
1276 fileno = blkno =0;
1277 break;
1278 case MTEOM:
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.
1285 Joerg Weule */
1286 cmd[0] = SPACE;
1287 cmd[1] =3;
1288 #ifdef DEBUG
1289 if(debugging)
1290 printk("st%d: Spacing to end of recorded medium.\n", dev);
1291 #endif
1292 blkno = (-1);
1293 break;
1294 case MTERASE:
1295 if(STp->write_prot)
1296 return(-EACCES);
1297 cmd[0] = ERASE;
1298 cmd[1] =1;/* To the end of tape */
1299 #ifdef DEBUG
1300 if(debugging)
1301 printk("st%d: Erasing tape.\n", dev);
1302 #endif
1303 fileno = blkno =0;
1304 break;
1305 case MTSEEK:
1306 if((STp->device)->scsi_level < SCSI_2) {
1307 cmd[0] = QFA_SEEK_BLOCK;
1308 cmd[2] = (arg >>16);
1309 cmd[3] = (arg >>8);
1310 cmd[4] = arg;
1311 cmd[5] =0;
1313 else{
1314 cmd[0] = SEEK_10;
1315 cmd[1] =4;
1316 cmd[3] = (arg >>24);
1317 cmd[4] = (arg >>16);
1318 cmd[5] = (arg >>8);
1319 cmd[6] = arg;
1321 #ifdef ST_NOWAIT
1322 cmd[1] |=1;/* Don't wait for completion */
1323 timeout = ST_TIMEOUT;
1324 #endif
1325 #ifdef DEBUG
1326 if(debugging)
1327 printk("st%d: Seeking tape to block %ld.\n", dev, arg);
1328 #endif
1329 fileno = blkno = (-1);
1330 break;
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 &&
1337 arg !=0&&
1338 (arg < STp->min_block || arg > STp->max_block ||
1339 arg > st_buffer_size)) {
1340 printk("st%d: Illegal block size.\n", dev);
1341 return(-EINVAL);
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;
1349 else
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;
1355 else
1356 (STp->buffer)->b_data[4] = STp->density;
1357 if(cmd_in == MTSETBLK)
1358 ltmp = arg;
1359 else
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;
1365 #ifdef DEBUG
1366 if(debugging) {
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]);
1375 else
1376 printk("st%d: Setting drive buffer code to %d.\n", dev,
1377 ((STp->buffer)->b_data[2] >>4) &7);
1379 #endif
1380 break;
1381 default:
1382 printk("st%d: Unknown st_ioctl command %x.\n", dev, cmd_in);
1383 return(-ENOSYS);
1386 SCpnt =allocate_device(NULL, (STp->device)->index,1);
1387 SCpnt->sense_buffer[0] =0;
1388 SCpnt->request.dev = dev;
1389 scsi_do_cmd(SCpnt,
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 */
1399 if(!ioctl_result) {
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;
1408 if(arg !=0) {
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;
1414 else{
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)
1424 STp->density = arg;
1425 else if(cmd_in == MTEOM || cmd_in == MTWEOF) {
1426 STp->eof = ST_EOM_OK;
1427 STp->eof_hit =0;
1429 else if(cmd_in != MTSETBLK && cmd_in != MTNOP) {
1430 STp->eof = ST_NOEOF;
1431 STp->eof_hit =0;
1433 }else{
1434 if(SCpnt->sense_buffer[2] &0x40) {
1435 STp->eof = ST_EOM_OK;
1436 STp->eof_hit =0;
1437 STp->drv_block =0;
1439 undone = (
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) {
1449 if(blkno >= undone)
1450 STp->drv_block = blkno - undone;
1451 else
1452 STp->drv_block = (-1);
1454 else if(cmd_in == MTBSR && blkno >=0) {
1455 if(blkno >=0)
1456 STp->drv_block = blkno + undone;
1457 else
1458 STp->drv_block = (-1);
1462 return ioctl_result ;
1467 /* The ioctl command */
1468 static int
1469 st_ioctl(struct inode * inode,struct file * file,
1470 unsigned int cmd_in,unsigned long arg)
1472 int dev =MINOR(inode->i_rdev);
1473 int i, cmd, result;
1474 struct mtop mtc;
1475 struct mtpos mt_pos;
1476 unsigned char scmd[10];
1477 Scsi_Cmnd *SCpnt;
1478 Scsi_Tape *STp;
1480 dev = dev &127;
1481 STp = &(scsi_tapes[dev]);
1482 #ifdef DEBUG
1483 if(debugging && !STp->in_use) {
1484 printk("st%d: Incorrect device.\n", dev);
1485 return(-EIO);
1487 #endif
1489 cmd = cmd_in & IOCCMD_MASK;
1490 if(cmd == (MTIOCTOP & IOCCMD_MASK)) {
1492 if(((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) !=sizeof(mtc))
1493 return(-EINVAL);
1495 i =verify_area(VERIFY_WRITE, (void*)arg,sizeof(mtc));
1496 if(i)
1497 return i;
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);
1504 if(i <0)
1505 return i;
1507 if(mtc.mt_op == MTSETDRVBUFFER &&
1508 (mtc.mt_count & MT_ST_OPTIONS) !=0)
1509 returnst_set_options(inode, mtc.mt_count);
1510 else
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))
1516 return(-EINVAL);
1517 i =verify_area(VERIFY_WRITE, (void*)arg,sizeof(struct mtget));
1518 if(i)
1519 return i;
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 */
1538 return0;
1540 else if(cmd == (MTIOCPOS & IOCCMD_MASK)) {
1541 #ifdef DEBUG
1542 if(debugging)
1543 printk("st%d: get tape position.\n", dev);
1544 #endif
1545 if(((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) !=sizeof(struct mtpos))
1546 return(-EINVAL);
1548 i =flush_buffer(inode, file,0);
1549 if(i <0)
1550 return i;
1552 i =verify_area(VERIFY_WRITE, (void*)arg,sizeof(struct mtpos));
1553 if(i)
1554 return i;
1556 SCpnt =allocate_device(NULL, (STp->device)->index,1);
1558 SCpnt->sense_buffer[0]=0;
1559 memset(scmd,0,10);
1560 if((STp->device)->scsi_level < SCSI_2) {
1561 scmd[0] = QFA_REQUEST_BLOCK;
1562 scmd[4] =3;
1564 else{
1565 scmd[0] = READ_POSITION;
1566 scmd[1] =1;
1568 SCpnt->request.dev = dev;
1569 SCpnt->sense_buffer[0] =0;
1570 scsi_do_cmd(SCpnt,
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);
1578 #ifdef DEBUG
1579 if(debugging)
1580 printk("st%d: Can't read tape position.\n", dev);
1581 #endif
1582 result = (-EIO);
1584 else{
1585 result =0;
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];
1590 else
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));
1601 return result;
1603 else
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. */
1611 void
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 */
1631 NULL,/* select */
1632 st_ioctl,/* ioctl */
1633 NULL,/* mmap */
1634 scsi_tape_open,/* open */
1635 scsi_tape_close,/* release */
1636 NULL /* fsync */
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);
1647 return mem_start;
1650 /* Driver initialization */
1651 unsigned longst_init(unsigned long mem_start,unsigned long mem_end)
1653 int i, dev_nbr;
1654 Scsi_Tape * STp;
1656 if(register_chrdev(MAJOR_NR,"st",&st_fops)) {
1657 printk("Unable to get major %d for SCSI tapes\n",MAJOR_NR);
1658 return mem_start;
1660 if(NR_ST ==0)return mem_start;
1662 #ifdef DEBUG
1663 printk("st: Buffer size %d bytes, write threshold %d bytes.\n",
1664 st_buffer_size, st_write_threshold);
1665 #endif
1667 for(i=0, dev_nbr=(-1); i < NR_ST; ++i) {
1668 STp = &(scsi_tapes[i]);
1669 STp->capacity =0xfffff;
1670 STp->dirty =0;
1671 STp->rw = ST_IDLE;
1672 STp->eof = ST_NOEOF;
1673 STp->waiting = NULL;
1674 STp->in_use =0;
1675 STp->drv_buffer =1;/* Try buffering if no mode sense */
1676 STp->density =0;
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;
1681 STp->drv_block =0;
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)
1688 break;
1689 if(dev_nbr >= NR_SCSI_DEVICES)
1690 printk("st%d: ERROR: Not found in scsi chain.\n", i);
1691 else{
1692 if(scsi_devices[dev_nbr].scsi_level <=2)
1693 STp->mt_status->mt_type = MT_ISSCSI1;
1694 else
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;
1707 #ifdef DEBUG
1708 /* printk("st: Buffer address: %p\n", st_buffers[i]); */
1709 #endif
1710 mem_start +=sizeof(ST_buffer) -1+ st_buffer_size;
1711 st_buffers[i]->in_use =0;
1712 st_buffers[i]->writing =0;
1715 return mem_start;
close