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 + ST_EXTRA_DEVS)
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 = !((STp->buffer)->writing ==
898 (STp->buffer)->buffer_bytes);
899
900 if (STp->block_size == 0)
901 blks = (STp->buffer)->writing;
902 else
903 blks = (STp->buffer)->writing / STp->block_size;
904 cmd[2] = blks >> 16;
905 cmd[3] = blks >> 8;
906 cmd[4] = blks;
907 SCpnt->result = (STp->buffer)->last_result = -1;
908 SCpnt->sense_buffer[0] = 0;
909 SCpnt->request.dev = dev;
910 scsi_do_cmd (SCpnt,
911 (void *) cmd, (STp->buffer)->b_data,
912 (STp->buffer)->writing,
913 st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
914 }
915 else
916 SCpnt->request.dev = -1;
917
918 STp->at_sm &= (total != 0);
919 return( total);
920 }
921
922
923
924 static int
925 st_read(struct inode * inode, struct file * filp, char * buf, int count)
926 {
927 int dev;
928 int total;
929 int transfer, blks, bytes;
930 static unsigned char cmd[10];
931 Scsi_Cmnd * SCpnt;
932 Scsi_Tape * STp;
933
934 dev = MINOR(inode->i_rdev) & 127;
935 STp = &(scsi_tapes[dev]);
936 if (STp->ready != ST_READY)
937 return (-EIO);
938 #ifdef DEBUG
939 if (!STp->in_use) {
940 printk("st%d: Incorrect device.\n", dev);
941 return (-EIO);
942 }
943 #endif
944
945 if (STp->block_size == 0 && count > st_buffer_size)
946 return (-EOVERFLOW);
947
948 if (!(STp->do_read_ahead) && STp->block_size != 0 &&
949 (count % STp->block_size) != 0)
950 return (-EIO);
951
952 if (STp->rw == ST_WRITING) {
953 transfer = flush_buffer(inode, filp, 0);
954 if (transfer)
955 return transfer;
956 STp->rw = ST_READING;
957 }
958 if (STp->moves_after_eof < 255)
959 STp->moves_after_eof++;
960
961 #ifdef DEBUG
962 if (debugging && STp->eof != ST_NOEOF)
963 printk("st%d: EOF flag up. Bytes %d\n", dev,
964 (STp->buffer)->buffer_bytes);
965 #endif
966 if (((STp->buffer)->buffer_bytes == 0) &&
967 (STp->eof == ST_EOM_OK || STp->eof == ST_EOD))
968 return (-EIO);
969
970 STp->rw = ST_READING;
971
972 SCpnt = allocate_device(NULL, STp->device, 1);
973
974 for (total = 0; total < count; ) {
975
976 if ((STp->buffer)->buffer_bytes == 0 &&
977 STp->eof == ST_NOEOF) {
978
979 memset(cmd, 0, 10);
980 cmd[0] = READ_6;
981 cmd[1] = (STp->block_size != 0);
982 if (STp->block_size == 0)
983 blks = bytes = count;
984 else {
985 if (STp->do_read_ahead) {
986 blks = (STp->buffer)->buffer_blocks;
987 bytes = blks * STp->block_size;
988 }
989 else {
990 bytes = count;
991 if (bytes > st_buffer_size)
992 bytes = st_buffer_size;
993 blks = bytes / STp->block_size;
994 bytes = blks * STp->block_size;
995 }
996 }
997 cmd[2] = blks >> 16;
998 cmd[3] = blks >> 8;
999 cmd[4] = blks;
1000
1001 SCpnt->sense_buffer[0] = 0;
1002 SCpnt->request.dev = dev;
1003 scsi_do_cmd (SCpnt,
1004 (void *) cmd, (STp->buffer)->b_data,
1005 (STp->buffer)->buffer_size,
1006 st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
1007
1008 if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
1009
1010 (STp->buffer)->read_pointer = 0;
1011 STp->eof_hit = 0;
1012 STp->at_sm = 0;
1013
1014 if ((STp->buffer)->last_result_fatal) {
1015 #ifdef DEBUG
1016 if (debugging)
1017 printk("st%d: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", dev,
1018 SCpnt->sense_buffer[0], SCpnt->sense_buffer[1],
1019 SCpnt->sense_buffer[2], SCpnt->sense_buffer[3],
1020 SCpnt->sense_buffer[4], SCpnt->sense_buffer[5],
1021 SCpnt->sense_buffer[6], SCpnt->sense_buffer[7]);
1022 #endif
1023 if ((SCpnt->sense_buffer[0] & 0x70) == 0x70) {
1024
1025 if ((SCpnt->sense_buffer[2] & 0xe0) != 0) {
1026
1027 if ((SCpnt->sense_buffer[0] & 0x80) != 0)
1028 transfer = (SCpnt->sense_buffer[3] << 24) |
1029 (SCpnt->sense_buffer[4] << 16) |
1030 (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];
1031 else
1032 transfer = 0;
1033 if (STp->block_size == 0 &&
1034 (SCpnt->sense_buffer[2] & 0x0f) == MEDIUM_ERROR)
1035 transfer = bytes;
1036
1037 if (SCpnt->sense_buffer[2] & 0x20) {
1038 if (STp->block_size == 0) {
1039 if (transfer <= 0)
1040 transfer = 0;
1041 (STp->buffer)->buffer_bytes = bytes - transfer;
1042 }
1043 else {
1044 printk("st%d: Incorrect block size.\n", dev);
1045 SCpnt->request.dev = -1;
1046 return (-EIO);
1047 }
1048 }
1049 else if (SCpnt->sense_buffer[2] & 0x40) {
1050 STp->eof = ST_EOM_OK;
1051 if (STp->block_size == 0)
1052 (STp->buffer)->buffer_bytes = bytes - transfer;
1053 else
1054 (STp->buffer)->buffer_bytes =
1055 bytes - transfer * STp->block_size;
1056 #ifdef DEBUG
1057 if (debugging)
1058 printk("st%d: EOM detected (%d bytes read).\n", dev,
1059 (STp->buffer)->buffer_bytes);
1060 #endif
1061 }
1062 else if (SCpnt->sense_buffer[2] & 0x80) {
1063 STp->eof = ST_FM;
1064 if (STp->block_size == 0)
1065 (STp->buffer)->buffer_bytes = 0;
1066 else
1067 (STp->buffer)->buffer_bytes =
1068 bytes - transfer * STp->block_size;
1069 #ifdef DEBUG
1070 if (debugging)
1071 printk(
1072 "st%d: EOF detected (%d bytes read, transferred %d bytes).\n",
1073 dev, (STp->buffer)->buffer_bytes, total);
1074 #endif
1075 }
1076 }
1077 else {
1078 #ifdef DEBUG
1079 if (debugging)
1080 printk("st%d: Tape error while reading.\n", dev);
1081 #endif
1082 SCpnt->request.dev = -1;
1083 STp->drv_block = (-1);
1084 if (total)
1085 return total;
1086 else if (STp->moves_after_eof == 1 &&
1087 (SCpnt->sense_buffer[2] & 0x0f) == BLANK_CHECK) {
1088 #ifdef DEBUG
1089 if (debugging)
1090 printk("st%d: Zero returned for first BLANK CHECK after EOF.\n",
1091 dev);
1092 #endif
1093 STp->eof = ST_EOD;
1094 return 0;
1095 }
1096 else
1097 return -EIO;
1098 }
1099 }
1100 else {
1101 transfer = (STp->buffer)->last_result_fatal;
1102 SCpnt->request.dev = -1;
1103 return transfer;
1104 }
1105 }
1106 else
1107 (STp->buffer)->buffer_bytes = bytes;
1108
1109 if (STp->drv_block >= 0) {
1110 if (STp->block_size == 0)
1111 STp->drv_block++;
1112 else
1113 STp->drv_block += (STp->buffer)->buffer_bytes / STp->block_size;
1114 }
1115
1116 }
1117
1118
1119 if ((STp->buffer)->buffer_bytes > 0) {
1120 #ifdef DEBUG
1121 if (debugging && STp->eof != ST_NOEOF)
1122 printk("st%d: EOF up. Left %d, needed %d.\n", dev,
1123 (STp->buffer)->buffer_bytes, count - total);
1124 #endif
1125 transfer = (STp->buffer)->buffer_bytes < count - total ?
1126 (STp->buffer)->buffer_bytes : count - total;
1127 memcpy_tofs(buf, (STp->buffer)->b_data +
1128 (STp->buffer)->read_pointer,transfer);
1129 filp->f_pos += transfer;
1130 buf += transfer;
1131 total += transfer;
1132 (STp->buffer)->buffer_bytes -= transfer;
1133 (STp->buffer)->read_pointer += transfer;
1134 }
1135 else if (STp->eof != ST_NOEOF) {
1136 STp->eof_hit = 1;
1137 SCpnt->request.dev = -1;
1138 if (total == 0 && STp->eof == ST_FM) {
1139 STp->eof = ST_NOEOF;
1140 STp->drv_block = 0;
1141 if (STp->moves_after_eof > 1)
1142 STp->moves_after_eof = 0;
1143 if ((STp->mt_status)->mt_fileno >= 0)
1144 (STp->mt_status)->mt_fileno++;
1145 }
1146 if (total == 0 && STp->eof == ST_EOM_OK)
1147 return (-EIO);
1148 return total;
1149 }
1150
1151 if (STp->block_size == 0)
1152 count = total;
1153
1154 }
1155
1156 SCpnt->request.dev = -1;
1157
1158 return total;
1159 }
1160
1161
1162
1163
1164 static int
1165 st_set_options(struct inode * inode, long options)
1166 {
1167 int dev, value;
1168 Scsi_Tape *STp;
1169
1170 dev = MINOR(inode->i_rdev) & 127;
1171 STp = &(scsi_tapes[dev]);
1172 if ((options & MT_ST_OPTIONS) == MT_ST_BOOLEANS) {
1173 STp->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
1174 STp->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
1175 STp->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
1176 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
1177 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
1178 #ifdef DEBUG
1179 debugging = (options & MT_ST_DEBUGGING) != 0;
1180 printk(
1181 "st%d: options: buffer writes: %d, async writes: %d, read ahead: %d\n",
1182 dev, STp->do_buffer_writes, STp->do_async_writes,
1183 STp->do_read_ahead);
1184 printk(" two FMs: %d, fast mteom: %d debugging: %d\n",
1185 STp->two_fm, STp->fast_mteom, debugging);
1186 #endif
1187 }
1188 else if ((options & MT_ST_OPTIONS) == MT_ST_WRITE_THRESHOLD) {
1189 value = (options & ~MT_ST_OPTIONS) * ST_BLOCK_SIZE;
1190 if (value < 1 || value > st_buffer_size) {
1191 printk("st: Write threshold %d too small or too large.\n",
1192 value);
1193 return (-EIO);
1194 }
1195 STp->write_threshold = value;
1196 #ifdef DEBUG
1197 printk("st%d: Write threshold set to %d bytes.\n", dev,
1198 STp->write_threshold);
1199 #endif
1200 }
1201 else
1202 return (-EIO);
1203
1204 return 0;
1205 }
1206
1207
1208
1209 static int
1210 st_int_ioctl(struct inode * inode,struct file * file,
1211 unsigned int cmd_in, unsigned long arg)
1212 {
1213 int dev = MINOR(inode->i_rdev);
1214 int timeout = ST_LONG_TIMEOUT;
1215 long ltmp;
1216 int ioctl_result;
1217 unsigned char cmd[10];
1218 Scsi_Cmnd * SCpnt;
1219 Scsi_Tape * STp;
1220 int fileno, blkno, at_sm, undone, datalen;
1221
1222 dev = dev & 127;
1223 STp = &(scsi_tapes[dev]);
1224 if (STp->ready != ST_READY)
1225 return (-EIO);
1226 fileno = (STp->mt_status)->mt_fileno ;
1227 blkno = STp->drv_block;
1228 at_sm = STp->at_sm;
1229
1230 memset(cmd, 0, 10);
1231 datalen = 0;
1232 switch (cmd_in) {
1233 case MTFSF:
1234 case MTFSFM:
1235 cmd[0] = SPACE;
1236 cmd[1] = 0x01;
1237 cmd[2] = (arg >> 16);
1238 cmd[3] = (arg >> 8);
1239 cmd[4] = arg;
1240 #ifdef DEBUG
1241 if (debugging)
1242 printk("st%d: Spacing tape forward over %d filemarks.\n", dev,
1243 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1244 #endif
1245 if (fileno >= 0)
1246 fileno += arg;
1247 blkno = 0;
1248 at_sm &= (arg != 0);
1249 break;
1250 case MTBSF:
1251 case MTBSFM:
1252 cmd[0] = SPACE;
1253 cmd[1] = 0x01;
1254 ltmp = (-arg);
1255 cmd[2] = (ltmp >> 16);
1256 cmd[3] = (ltmp >> 8);
1257 cmd[4] = ltmp;
1258 #ifdef DEBUG
1259 if (debugging) {
1260 if (cmd[2] & 0x80)
1261 ltmp = 0xff000000;
1262 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
1263 printk("st%d: Spacing tape backward over %ld filemarks.\n", dev, (-ltmp));
1264 }
1265 #endif
1266 if (fileno >= 0)
1267 fileno -= arg;
1268 blkno = (-1);
1269 at_sm &= (arg != 0);
1270 break;
1271 case MTFSR:
1272 cmd[0] = SPACE;
1273 cmd[1] = 0x00;
1274 cmd[2] = (arg >> 16);
1275 cmd[3] = (arg >> 8);
1276 cmd[4] = arg;
1277 #ifdef DEBUG
1278 if (debugging)
1279 printk("st%d: Spacing tape forward %d blocks.\n", dev,
1280 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1281 #endif
1282 if (blkno >= 0)
1283 blkno += arg;
1284 at_sm &= (arg != 0);
1285 break;
1286 case MTBSR:
1287 cmd[0] = SPACE;
1288 cmd[1] = 0x00;
1289 ltmp = (-arg);
1290 cmd[2] = (ltmp >> 16);
1291 cmd[3] = (ltmp >> 8);
1292 cmd[4] = ltmp;
1293 #ifdef DEBUG
1294 if (debugging) {
1295 if (cmd[2] & 0x80)
1296 ltmp = 0xff000000;
1297 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
1298 printk("st%d: Spacing tape backward %ld blocks.\n", dev, (-ltmp));
1299 }
1300 #endif
1301 if (blkno >= 0)
1302 blkno -= arg;
1303 at_sm &= (arg != 0);
1304 break;
1305 case MTFSS:
1306 cmd[0] = SPACE;
1307 cmd[1] = 0x04;
1308 cmd[2] = (arg >> 16);
1309 cmd[3] = (arg >> 8);
1310 cmd[4] = arg;
1311 #ifdef DEBUG
1312 if (debugging)
1313 printk("st%d: Spacing tape forward %d setmarks.\n", dev,
1314 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1315 #endif
1316 if (arg != 0) {
1317 blkno = fileno = (-1);
1318 at_sm = 1;
1319 }
1320 break;
1321 case MTBSS:
1322 cmd[0] = SPACE;
1323 cmd[1] = 0x04;
1324 ltmp = (-arg);
1325 cmd[2] = (ltmp >> 16);
1326 cmd[3] = (ltmp >> 8);
1327 cmd[4] = ltmp;
1328 #ifdef DEBUG
1329 if (debugging) {
1330 if (cmd[2] & 0x80)
1331 ltmp = 0xff000000;
1332 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
1333 printk("st%d: Spacing tape backward %ld setmarks.\n", dev, (-ltmp));
1334 }
1335 #endif
1336 if (arg != 0) {
1337 blkno = fileno = (-1);
1338 at_sm = 1;
1339 }
1340 break;
1341 case MTWEOF:
1342 case MTWSM:
1343 if (STp->write_prot)
1344 return (-EACCES);
1345 cmd[0] = WRITE_FILEMARKS;
1346 if (cmd_in == MTWSM)
1347 cmd[1] = 2;
1348 cmd[2] = (arg >> 16);
1349 cmd[3] = (arg >> 8);
1350 cmd[4] = arg;
1351 timeout = ST_TIMEOUT;
1352 #ifdef DEBUG
1353 if (debugging) {
1354 if (cmd_in == MTWEOF)
1355 printk("st%d: Writing %d filemarks.\n", dev,
1356 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1357 else
1358 printk("st%d: Writing %d setmarks.\n", dev,
1359 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
1360 }
1361 #endif
1362 if (fileno >= 0)
1363 fileno += arg;
1364 blkno = 0;
1365 at_sm = (cmd_in == MTWSM);
1366 break;
1367 case MTREW:
1368 cmd[0] = REZERO_UNIT;
1369 #ifdef ST_NOWAIT
1370 cmd[1] = 1;
1371 timeout = ST_TIMEOUT;
1372 #endif
1373 #ifdef DEBUG
1374 if (debugging)
1375 printk("st%d: Rewinding tape.\n", dev);
1376 #endif
1377 fileno = blkno = at_sm = 0 ;
1378 break;
1379 case MTOFFL:
1380 cmd[0] = START_STOP;
1381 #ifdef ST_NOWAIT
1382 cmd[1] = 1;
1383 timeout = ST_TIMEOUT;
1384 #endif
1385 #ifdef DEBUG
1386 if (debugging)
1387 printk("st%d: Unloading tape.\n", dev);
1388 #endif
1389 fileno = blkno = at_sm = 0 ;
1390 break;
1391 case MTNOP:
1392 #ifdef DEBUG
1393 if (debugging)
1394 printk("st%d: No op on tape.\n", dev);
1395 #endif
1396 return 0;
1397 break;
1398 case MTRETEN:
1399 cmd[0] = START_STOP;
1400 #ifdef ST_NOWAIT
1401 cmd[1] = 1;
1402 timeout = ST_TIMEOUT;
1403 #endif
1404 cmd[4] = 3;
1405 #ifdef DEBUG
1406 if (debugging)
1407 printk("st%d: Retensioning tape.\n", dev);
1408 #endif
1409 fileno = blkno = at_sm = 0;
1410 break;
1411 case MTEOM:
1412 if (!STp->fast_mteom) {
1413
1414 ioctl_result = st_int_ioctl(inode, file, MTFSF, 0x3fff);
1415 fileno = (STp->mt_status)->mt_fileno ;
1416 if (STp->eof == ST_EOD || STp->eof == ST_EOM_OK)
1417 return 0;
1418
1419
1420
1421
1422 }
1423 else
1424 fileno = (-1);
1425 cmd[0] = SPACE;
1426 cmd[1] = 3;
1427 #ifdef DEBUG
1428 if (debugging)
1429 printk("st%d: Spacing to end of recorded medium.\n", dev);
1430 #endif
1431 blkno = 0;
1432 at_sm = 0;
1433 break;
1434 case MTERASE:
1435 if (STp->write_prot)
1436 return (-EACCES);
1437 cmd[0] = ERASE;
1438 cmd[1] = 1;
1439 #ifdef ST_NOWAIT
1440 cmd[1] |= 2;
1441 timeout = ST_TIMEOUT;
1442 #else
1443 timeout = ST_LONG_TIMEOUT * 8;
1444 #endif
1445 #ifdef DEBUG
1446 if (debugging)
1447 printk("st%d: Erasing tape.\n", dev);
1448 #endif
1449 fileno = blkno = at_sm = 0 ;
1450 break;
1451 case MTSEEK:
1452 if ((STp->device)->scsi_level < SCSI_2) {
1453 cmd[0] = QFA_SEEK_BLOCK;
1454 cmd[2] = (arg >> 16);
1455 cmd[3] = (arg >> 8);
1456 cmd[4] = arg;
1457 cmd[5] = 0;
1458 }
1459 else {
1460 cmd[0] = SEEK_10;
1461 cmd[1] = 4;
1462 cmd[3] = (arg >> 24);
1463 cmd[4] = (arg >> 16);
1464 cmd[5] = (arg >> 8);
1465 cmd[6] = arg;
1466 }
1467 #ifdef ST_NOWAIT
1468 cmd[1] |= 1;
1469 timeout = ST_TIMEOUT;
1470 #endif
1471 #ifdef DEBUG
1472 if (debugging)
1473 printk("st%d: Seeking tape to block %ld.\n", dev, arg);
1474 #endif
1475 fileno = blkno = (-1);
1476 at_sm = 0;
1477 break;
1478 case MTSETBLK:
1479 case MTSETDENSITY:
1480 case MTSETDRVBUFFER:
1481 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
1482 return (-EIO);
1483 if (cmd_in == MTSETBLK &&
1484 arg != 0 &&
1485 (arg < STp->min_block || arg > STp->max_block ||
1486 arg > st_buffer_size)) {
1487 printk("st%d: Illegal block size.\n", dev);
1488 return (-EINVAL);
1489 }
1490 cmd[0] = MODE_SELECT;
1491 cmd[4] = datalen = 12;
1492
1493 memset((STp->buffer)->b_data, 0, 12);
1494 if (cmd_in == MTSETDRVBUFFER)
1495 (STp->buffer)->b_data[2] = (arg & 7) << 4;
1496 else
1497 (STp->buffer)->b_data[2] =
1498 STp->drv_buffer << 4;
1499 (STp->buffer)->b_data[3] = 8;
1500 if (cmd_in == MTSETDENSITY)
1501 (STp->buffer)->b_data[4] = arg;
1502 else
1503 (STp->buffer)->b_data[4] = STp->density;
1504 if (cmd_in == MTSETBLK)
1505 ltmp = arg;
1506 else
1507 ltmp = STp->block_size;
1508 (STp->buffer)->b_data[9] = (ltmp >> 16);
1509 (STp->buffer)->b_data[10] = (ltmp >> 8);
1510 (STp->buffer)->b_data[11] = ltmp;
1511 timeout = ST_TIMEOUT;
1512 #ifdef DEBUG
1513 if (debugging) {
1514 if (cmd_in == MTSETBLK)
1515 printk("st%d: Setting block size to %d bytes.\n", dev,
1516 (STp->buffer)->b_data[9] * 65536 +
1517 (STp->buffer)->b_data[10] * 256 +
1518 (STp->buffer)->b_data[11]);
1519 else if (cmd_in == MTSETDENSITY)
1520 printk("st%d: Setting density code to %x.\n", dev,
1521 (STp->buffer)->b_data[4]);
1522 else
1523 printk("st%d: Setting drive buffer code to %d.\n", dev,
1524 ((STp->buffer)->b_data[2] >> 4) & 7);
1525 }
1526 #endif
1527 break;
1528 default:
1529 printk("st%d: Unknown st_ioctl command %x.\n", dev, cmd_in);
1530 return (-ENOSYS);
1531 }
1532
1533 SCpnt = allocate_device(NULL, STp->device, 1);
1534 SCpnt->sense_buffer[0] = 0;
1535 SCpnt->request.dev = dev;
1536 scsi_do_cmd(SCpnt,
1537 (void *) cmd, (void *) (STp->buffer)->b_data, datalen,
1538 st_sleep_done, timeout, MAX_RETRIES);
1539
1540 if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
1541
1542 ioctl_result = (STp->buffer)->last_result_fatal;
1543
1544 SCpnt->request.dev = -1;
1545
1546 if (cmd_in == MTFSF)
1547 STp->moves_after_eof = 0;
1548 else
1549 STp->moves_after_eof = 1;
1550 if (!ioctl_result) {
1551 if (cmd_in != MTSEEK) {
1552 STp->drv_block = blkno;
1553 (STp->mt_status)->mt_fileno = fileno;
1554 STp->at_sm = at_sm;
1555 }
1556 else {
1557 STp->drv_block = (STp->mt_status)->mt_fileno = (-1);
1558 STp->at_sm = 0;
1559 }
1560 if (cmd_in == MTBSFM)
1561 ioctl_result = st_int_ioctl(inode, file, MTFSF, 1);
1562 else if (cmd_in == MTFSFM)
1563 ioctl_result = st_int_ioctl(inode, file, MTBSF, 1);
1564 else if (cmd_in == MTSETBLK) {
1565 STp->block_size = arg;
1566 if (arg != 0) {
1567 (STp->buffer)->buffer_blocks =
1568 st_buffer_size / STp->block_size;
1569 (STp->buffer)->buffer_size =
1570 (STp->buffer)->buffer_blocks * STp->block_size;
1571 }
1572 else {
1573 (STp->buffer)->buffer_blocks = 1;
1574 (STp->buffer)->buffer_size = st_buffer_size;
1575 }
1576 (STp->buffer)->buffer_bytes =
1577 (STp->buffer)->read_pointer = 0;
1578 }
1579 else if (cmd_in == MTSETDRVBUFFER)
1580 STp->drv_buffer = (arg & 7);
1581 else if (cmd_in == MTSETDENSITY)
1582 STp->density = arg;
1583 else if (cmd_in == MTEOM) {
1584 STp->eof = ST_EOD;
1585 STp->eof_hit = 0;
1586 }
1587 else if (cmd_in != MTSETBLK && cmd_in != MTNOP) {
1588 STp->eof = ST_NOEOF;
1589 STp->eof_hit = 0;
1590 }
1591 } else {
1592 if (SCpnt->sense_buffer[2] & 0x40) {
1593 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
1594 cmd_in != MTBSR && cmd_in != MTBSS)
1595 STp->eof = ST_EOM_OK;
1596 STp->eof_hit = 0;
1597 STp->drv_block = 0;
1598 }
1599 undone = (
1600 (SCpnt->sense_buffer[3] << 24) +
1601 (SCpnt->sense_buffer[4] << 16) +
1602 (SCpnt->sense_buffer[5] << 8) +
1603 SCpnt->sense_buffer[6] );
1604 if ( (cmd_in == MTFSF) || (cmd_in == MTFSFM) ) {
1605 if (fileno >= 0)
1606 (STp->mt_status)->mt_fileno = fileno - undone ;
1607 else
1608 (STp->mt_status)->mt_fileno = fileno;
1609 STp->drv_block = 0;
1610 }
1611 else if ( (cmd_in == MTBSF) || (cmd_in == MTBSFM) ) {
1612 (STp->mt_status)->mt_fileno = fileno + undone ;
1613 STp->drv_block = 0;
1614 }
1615 else if (cmd_in == MTFSR) {
1616 if (SCpnt->sense_buffer[2] & 0x80) {
1617 (STp->mt_status)->mt_fileno++;
1618 STp->drv_block = 0;
1619 }
1620 else {
1621 if (blkno >= undone)
1622 STp->drv_block = blkno - undone;
1623 else
1624 STp->drv_block = (-1);
1625 }
1626 }
1627 else if (cmd_in == MTBSR) {
1628 if (SCpnt->sense_buffer[2] & 0x80) {
1629 (STp->mt_status)->mt_fileno--;
1630 STp->drv_block = (-1);
1631 }
1632 else {
1633 if (blkno >= 0)
1634 STp->drv_block = blkno + undone;
1635 else
1636 STp->drv_block = (-1);
1637 }
1638 }
1639 else if (cmd_in == MTEOM || cmd_in == MTSEEK) {
1640 (STp->mt_status)->mt_fileno = (-1);
1641 STp->drv_block = (-1);
1642 }
1643 if (STp->eof == ST_NOEOF &&
1644 (SCpnt->sense_buffer[2] & 0x0f) == BLANK_CHECK)
1645 STp->eof = ST_EOD;
1646 }
1647
1648 return ioctl_result;
1649 }
1650
1651
1652
1653
1654 static int
1655 st_ioctl(struct inode * inode,struct file * file,
1656 unsigned int cmd_in, unsigned long arg)
1657 {
1658 int dev = MINOR(inode->i_rdev);
1659 int i, cmd, result;
1660 struct mtop mtc;
1661 struct mtpos mt_pos;
1662 unsigned char scmd[10];
1663 Scsi_Cmnd *SCpnt;
1664 Scsi_Tape *STp;
1665
1666 dev = dev & 127;
1667 STp = &(scsi_tapes[dev]);
1668 #ifdef DEBUG
1669 if (debugging && !STp->in_use) {
1670 printk("st%d: Incorrect device.\n", dev);
1671 return (-EIO);
1672 }
1673 #endif
1674
1675 cmd = cmd_in & IOCCMD_MASK;
1676 if (cmd == (MTIOCTOP & IOCCMD_MASK)) {
1677
1678 if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(mtc))
1679 return (-EINVAL);
1680
1681 i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(mtc));
1682 if (i)
1683 return i;
1684
1685 memcpy_fromfs((char *) &mtc, (char *)arg, sizeof(struct mtop));
1686
1687 i = flush_buffer(inode, file, mtc.mt_op == MTSEEK ||
1688 mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
1689 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM);
1690 if (i < 0)
1691 return i;
1692 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
1693 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
1694 mtc.mt_op != MTSETDRVBUFFER)
1695 STp->rw = ST_IDLE;
1696
1697 if (mtc.mt_op == MTSETDRVBUFFER &&
1698 (mtc.mt_count & MT_ST_OPTIONS) != 0)
1699 return st_set_options(inode, mtc.mt_count);
1700 else
1701 return st_int_ioctl(inode, file, mtc.mt_op, mtc.mt_count);
1702 }
1703 else if (cmd == (MTIOCGET & IOCCMD_MASK)) {
1704
1705 if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtget))
1706 return (-EINVAL);
1707 i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct mtget));
1708 if (i)
1709 return i;
1710
1711 (STp->mt_status)->mt_dsreg =
1712 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
1713 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
1714 (STp->mt_status)->mt_blkno = STp->drv_block;
1715 if (STp->block_size != 0) {
1716 if (STp->rw == ST_WRITING)
1717 (STp->mt_status)->mt_blkno +=
1718 (STp->buffer)->buffer_bytes / STp->block_size;
1719 else if (STp->rw == ST_READING)
1720 (STp->mt_status)->mt_blkno -= ((STp->buffer)->buffer_bytes +
1721 STp->block_size - 1) / STp->block_size;
1722 }
1723
1724 (STp->mt_status)->mt_gstat = 0;
1725 if (STp->drv_write_prot)
1726 (STp->mt_status)->mt_gstat |= GMT_WR_PROT(0xffffffff);
1727 if ((STp->mt_status)->mt_blkno == 0) {
1728 if ((STp->mt_status)->mt_fileno == 0)
1729 (STp->mt_status)->mt_gstat |= GMT_BOT(0xffffffff);
1730 else
1731 (STp->mt_status)->mt_gstat |= GMT_EOF(0xffffffff);
1732 }
1733 if (STp->eof == ST_EOM_OK || STp->eof == ST_EOM_ERROR)
1734 (STp->mt_status)->mt_gstat |= GMT_EOT(0xffffffff);
1735 else if (STp->eof == ST_EOD)
1736 (STp->mt_status)->mt_gstat |= GMT_EOD(0xffffffff);
1737 if (STp->density == 1)
1738 (STp->mt_status)->mt_gstat |= GMT_D_800(0xffffffff);
1739 else if (STp->density == 2)
1740 (STp->mt_status)->mt_gstat |= GMT_D_1600(0xffffffff);
1741 else if (STp->density == 3)
1742 (STp->mt_status)->mt_gstat |= GMT_D_6250(0xffffffff);
1743 if (STp->ready == ST_READY)
1744 (STp->mt_status)->mt_gstat |= GMT_ONLINE(0xffffffff);
1745 if (STp->ready == ST_NO_TAPE)
1746 (STp->mt_status)->mt_gstat |= GMT_DR_OPEN(0xffffffff);
1747 if (STp->at_sm)
1748 (STp->mt_status)->mt_gstat |= GMT_SM(0xffffffff);
1749
1750 memcpy_tofs((char *)arg, (char *)(STp->mt_status),
1751 sizeof(struct mtget));
1752
1753 (STp->mt_status)->mt_erreg = 0;
1754 return 0;
1755 }
1756 else if (cmd == (MTIOCPOS & IOCCMD_MASK)) {
1757 if (STp->ready != ST_READY)
1758 return (-EIO);
1759 #ifdef DEBUG
1760 if (debugging)
1761 printk("st%d: get tape position.\n", dev);
1762 #endif
1763 if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtpos))
1764 return (-EINVAL);
1765
1766 i = flush_buffer(inode, file, 0);
1767 if (i < 0)
1768 return i;
1769
1770 i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct mtpos));
1771 if (i)
1772 return i;
1773
1774 SCpnt = allocate_device(NULL, STp->device, 1);
1775
1776 SCpnt->sense_buffer[0]=0;
1777 memset (scmd, 0, 10);
1778 if ((STp->device)->scsi_level < SCSI_2) {
1779 scmd[0] = QFA_REQUEST_BLOCK;
1780 scmd[4] = 3;
1781 }
1782 else {
1783 scmd[0] = READ_POSITION;
1784 scmd[1] = 1;
1785 }
1786 SCpnt->request.dev = dev;
1787 SCpnt->sense_buffer[0] = 0;
1788 scsi_do_cmd(SCpnt,
1789 (void *) scmd, (void *) (STp->buffer)->b_data,
1790 20, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
1791
1792 if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
1793
1794 if ((STp->buffer)->last_result_fatal != 0) {
1795 mt_pos.mt_blkno = (-1);
1796 #ifdef DEBUG
1797 if (debugging)
1798 printk("st%d: Can't read tape position.\n", dev);
1799 #endif
1800 result = (-EIO);
1801 }
1802 else {
1803 result = 0;
1804 if ((STp->device)->scsi_level < SCSI_2)
1805 mt_pos.mt_blkno = ((STp->buffer)->b_data[0] << 16)
1806 + ((STp->buffer)->b_data[1] << 8)
1807 + (STp->buffer)->b_data[2];
1808 else
1809 mt_pos.mt_blkno = ((STp->buffer)->b_data[4] << 24)
1810 + ((STp->buffer)->b_data[5] << 16)
1811 + ((STp->buffer)->b_data[6] << 8)
1812 + (STp->buffer)->b_data[7];
1813
1814 }
1815
1816 SCpnt->request.dev = -1;
1817
1818 memcpy_tofs((char *)arg, (char *) (&mt_pos), sizeof(struct mtpos));
1819 return result;
1820 }
1821 else if (STp->ready == ST_READY)
1822 return scsi_ioctl(STp->device, cmd_in, (void *) arg);
1823 else
1824 return (-EIO);
1825 }
1826
1827
1828
1829
1830
1831 void
1832 st_setup(char *str, int *ints)
1833 {
1834 if (ints[0] > 0 && ints[1] > 0)
1835 st_buffer_size = ints[1] * ST_BLOCK_SIZE;
1836 if (ints[0] > 1 && ints[2] > 0) {
1837 st_write_threshold = ints[2] * ST_BLOCK_SIZE;
1838 if (st_write_threshold > st_buffer_size)
1839 st_write_threshold = st_buffer_size;
1840 }
1841 if (ints[0] > 2 && ints[3] > 0)
1842 st_max_buffers = ints[3];
1843 }
1844
1845
1846 static struct file_operations st_fops = {
1847 NULL,
1848 st_read,
1849 st_write,
1850 NULL,
1851 NULL,
1852 st_ioctl,
1853 NULL,
1854 scsi_tape_open,
1855 scsi_tape_close,
1856 NULL
1857 };
1858
1859 static int st_attach(Scsi_Device * SDp){
1860 Scsi_Tape * tpnt;
1861 int i;
1862
1863 if(SDp->type != TYPE_TAPE) return 1;
1864
1865 if(st_template.nr_dev >= st_template.dev_max)
1866 {
1867 SDp->attached--;
1868 return 1;
1869 }
1870
1871 for(tpnt = scsi_tapes, i=0; i<st_template.dev_max; i++, tpnt++)
1872 if(!tpnt->device) break;
1873
1874 if(i >= st_template.dev_max) panic ("scsi_devices corrupt (st)");
1875
1876 scsi_tapes[i].device = SDp;
1877 if (SDp->scsi_level <= 2)
1878 scsi_tapes[i].mt_status->mt_type = MT_ISSCSI1;
1879 else
1880 scsi_tapes[i].mt_status->mt_type = MT_ISSCSI2;
1881
1882 st_template.nr_dev++;
1883 return 0;
1884 };
1885
1886 static int st_detect(Scsi_Device * SDp)
1887 {
1888 if(SDp->type != TYPE_TAPE) return 0;
1889
1890 printk("Detected scsi tape st%d at scsi%d, id %d, lun %d\n",
1891 st_template.dev_noticed++,
1892 SDp->host->host_no , SDp->id, SDp->lun);
1893
1894 return 1;
1895 }
1896
1897
1898 static void st_init()
1899 {
1900 int i;
1901 Scsi_Tape * STp;
1902 static int st_registered = 0;
1903
1904 if (st_template.dev_noticed == 0) return;
1905
1906 if(!st_registered) {
1907 if (register_chrdev(MAJOR_NR,"st",&st_fops)) {
1908 printk("Unable to get major %d for SCSI tapes\n",MAJOR_NR);
1909 return;
1910 }
1911 st_registered++;
1912 }
1913
1914 if (scsi_tapes) return;
1915 scsi_tapes = (Scsi_Tape *) scsi_init_malloc(
1916 (st_template.dev_noticed + ST_EXTRA_DEVS) *
1917 sizeof(Scsi_Tape), GFP_ATOMIC);
1918 st_template.dev_max = st_template.dev_noticed + ST_EXTRA_DEVS;
1919
1920 #ifdef DEBUG
1921 printk("st: Buffer size %d bytes, write threshold %d bytes.\n",
1922 st_buffer_size, st_write_threshold);
1923 #endif
1924
1925 for (i=0; i < st_template.dev_max; ++i) {
1926 STp = &(scsi_tapes[i]);
1927 STp->device = NULL;
1928 STp->capacity = 0xfffff;
1929 STp->dirty = 0;
1930 STp->rw = ST_IDLE;
1931 STp->eof = ST_NOEOF;
1932 STp->waiting = NULL;
1933 STp->in_use = 0;
1934 STp->drv_buffer = 1;
1935 STp->density = 0;
1936 STp->do_buffer_writes = ST_BUFFER_WRITES;
1937 STp->do_async_writes = ST_ASYNC_WRITES;
1938 STp->do_read_ahead = ST_READ_AHEAD;
1939 STp->two_fm = ST_TWO_FM;
1940 STp->fast_mteom = ST_FAST_MTEOM;
1941 STp->write_threshold = st_write_threshold;
1942 STp->drv_block = 0;
1943 STp->moves_after_eof = 1;
1944 STp->at_sm = 0;
1945 STp->mt_status = (struct mtget *) scsi_init_malloc(sizeof(struct mtget), GFP_ATOMIC);
1946
1947 memset((void *) scsi_tapes[i].mt_status, 0, sizeof(struct mtget));
1948 }
1949
1950
1951 st_nbr_buffers = st_template.dev_noticed + ST_EXTRA_DEVS;
1952 if (st_nbr_buffers > st_max_buffers)
1953 st_nbr_buffers = st_max_buffers;
1954 st_buffers = (ST_buffer **) scsi_init_malloc(st_nbr_buffers *
1955 sizeof(ST_buffer *), GFP_ATOMIC);
1956
1957
1958
1959
1960
1961 for (i=0; i < st_nbr_buffers; i++) {
1962 st_buffers[i] = (ST_buffer *) scsi_init_malloc(sizeof(ST_buffer) -
1963 1 + st_buffer_size, GFP_ATOMIC | GFP_DMA);
1964 #ifdef DEBUG
1965
1966 #endif
1967 st_buffers[i]->in_use = 0;
1968 st_buffers[i]->writing = 0;
1969 }
1970 return;
1971 }
1972
1973 static void st_detach(Scsi_Device * SDp)
1974 {
1975 Scsi_Tape * tpnt;
1976 int i;
1977
1978 for(tpnt = scsi_tapes, i=0; i<st_template.dev_max; i++, tpnt++)
1979 if(tpnt->device == SDp) {
1980 tpnt->device = NULL;
1981 SDp->attached--;
1982 st_template.nr_dev--;
1983 st_template.dev_noticed--;
1984 return;
1985 }
1986 return;
1987 }