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