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