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