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