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