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