1 /* $Id: tpqic02.c,v 0.2.1.21 1993/06/18 19:04:33 root Exp root $ 2 * 3 * Driver for tape drive support for Linux-i386 0.99.12. 4 * 5 * Copyright (c) 1993 by H. H. Bergman. All rights reserved. 6 * Current e-mail address: csg279@wing.rug.nl 7 * [If you are unable to reach me directly, try the TAPE mailing list 8 * channel on linux-activists@niksula.hut.fi using "X-Mn-Key: TAPE" as 9 * the first line in your message.] 10 * 11 * Distribution of this program in executable form is only allowed if 12 * all of the corresponding source files are made available through the same 13 * medium at no extra cost. 14 * 15 * I will not accept any responsibility for damage caused directly or 16 * indirectly by this program, or code derived from this program. 17 * 18 * Use this code at your own risk. Don't blame me if it destroys your data! 19 * Make sure you have a backup before you try this code. 20 * 21 * This driver was partially inspired by the 'wt' driver in the 386BSD 22 * source distribution, which carries the following copyright notice: 23 * 24 * Copyright (c) 1991 The Regents of the University of California. 25 * All rights reserved. 26 * 27 * You are not allowed to change this line nor the text above. 28 * 29 * $Log: tpqic02.c,v $ 30 * Revision 0.2.1.21 1993/06/18 19:04:33 root 31 * minor fixes for 0.99.10. 32 * 33 * Revision 0.2.1.20 1993/06/11 21:38:51 root 34 * Added exception code for status 0x8000 (Cypher weirdness). 35 * 36 * Revision 0.2.1.19 1993/04/19 23:13:59 root 37 * Cleanups. Changed to 0.99.8. 38 * 39 * Revision 0.2.1.18 1993/03/22 17:39:47 root 40 * Moved to 0.99.7. Added Archive MTSEEK and MTTELL support. 41 * 42 * Revision 0.2.1.17 1993/03/08 18:51:59 root 43 * Tried to `fix' write-once bug in previous release. 44 * 45 * Revision 0.2.1.16 1993/03/01 00:06:16 root 46 * Use register_chrdev() for 0.99.6. 47 * 48 * Revision 0.2.1.15 1993/02/25 00:14:25 root 49 * minor cleanups. 50 * 51 * Revision 0.2.1.14 1993/01/25 00:06:14 root 52 * Kernel udelay. Eof fixups. 53 * Removed report_ read/write dummies; have strace(1) now. 54 * 55 * Revision 0.2.1.13 1993/01/10 02:24:43 root 56 * Rewrote wait_for_ready() to use newer schedule() features. 57 * This improves performance for rewinds etc. 58 * 59 * Revision 0.2.1.12 1993/01/05 18:44:09 root 60 * Changes for 0.99.1. Fixed `restartable reads'. 61 * 62 * Revision 0.2.1.11 1992/11/28 01:19:10 root 63 * Changes to exception handling (significant). 64 * Changed returned error codes. Hopefully they're correct now. 65 * Changed declarations to please gcc-2.3.1. 66 * Patch to deal with bogus interrupts for Archive cards. 67 * 68 * Revision 0.2.1.10 1992/10/28 00:50:44 root 69 * underrun/error counter needed byte swapping. 70 * 71 * Revision 0.2.1.9 1992/10/15 17:06:01 root 72 * Removed online() stuff. Changed EOF handling. 73 * 74 * Revision 0.2.1.8 1992/10/02 22:25:48 root 75 * Removed `no_sleep' parameters (got usleep() now), 76 * cleaned up some comments. 77 * 78 * Revision 0.2.1.7 1992/09/27 01:41:55 root 79 * Changed write() to do entire user buffer in one go, rather than just 80 * a kernel-buffer sized portion each time. 81 * 82 * Revision 0.2.1.6 1992/09/21 02:15:30 root 83 * Introduced udelay() function for microsecond-delays. 84 * Trying to use get_dma_residue rather than TC flags. 85 * Patch to fill entire user buffer on reads before 86 * returning. 87 * 88 * Revision 0.2.1.5 1992/09/19 02:31:28 root 89 * Some changes based on patches by Eddy Olk to 90 * support Archive SC402/SC499R controller cards. 91 * 92 * Revision 0.2.1.4 1992/09/07 01:37:37 root 93 * Minor changes 94 * 95 * Revision 0.2.1.3 1992/08/13 00:11:02 root 96 * Added some support for Archive SC402 and SC499 cards. 97 * (Untested.) 98 * 99 * Revision 0.2.1.2 1992/08/10 02:02:36 root 100 * Changed from linux/system.h macros to asm/dma.h inline functions. 101 * 102 * Revision 0.2.1.1 1992/08/08 01:12:39 root 103 * cleaned up a bit. added stuff for selftesting. 104 * preparing for asm/dma.h instead of linux/system.h 105 * 106 * Revision 0.2 1992/08/03 20:11:30 root 107 * Changed to use new IRQ allocation. Padding now done at runtime, pads to 108 * 512 bytes. Because of this the page regs must be re-programmed every 109 * block! Added hooks for selftest commands. 110 * Moved to linux-0.97. 111 * 112 * Revision 0.1.0.5 1992/06/22 22:20:30 root 113 * moved to Linux 0.96b 114 * 115 * Revision 0.1.0.4 1992/06/18 02:00:04 root 116 * Use minor bit-7 to enable/disable printing of extra debugging info 117 * when do tape access. 118 * Added semop stuff for DMA/IRQ allocation checking. Don't think this 119 * is the right way to do it though. 120 * 121 * Revision 0.1.0.3 1992/06/01 01:57:34 root 122 * changed DRQ to DMA. added TDEBUG ifdefs to reduce output. 123 * 124 * Revision 0.1.0.2 1992/05/31 14:02:38 root 125 * changed SET_DMA_PAGE handling slightly. 126 * 127 * Revision 0.1.0.1 1992/05/27 12:12:03 root 128 * Can now use multiple files on tape (sort of). 129 * First release. 130 * 131 * Revision 0.1 1992/05/26 01:16:31 root 132 * Initial version. Copyright H. H. Bergman 1992 133 * 134 */ 135
136 /* After the legalese, now the important bits: 137 * 138 * This is a driver for the Wangtek 5150 tape drive with 139 * a QIC-02 controller for ISA-PC type computers. 140 * Hopefully it will work with other QIC-02 tape drives as well. 141 * 142 * Make sure your setup matches the configuration parameters. 143 * Also, be careful to avoid IO conflicts with other devices! 144 */ 145
146 #include <linux/config.h>
147
148 /* skip this driver if not required for this configuration */ 149 #ifCONFIG_TAPE_QIC02 150
151 /* 152 #define TDEBUG 153 */ 154
155 #defineREALLY_SLOW_IO/* it sure is ... */ 156
157 #include <asm/dma.h>
158 #include <linux/sched.h>
159 #include <linux/timer.h>
160 #include <linux/fs.h>
161 #include <linux/kernel.h>
162 #include <asm/system.h>
163 #include <asm/io.h>
164 #include <asm/segment.h>
165
166 #include <linux/errno.h>
167 #include <linux/mtio.h>
168 #include <linux/fcntl.h>
169 #include <linux/delay.h>
170
171 #include <linux/tpqic02.h>
172
173 /* check existence of required configuration parameters */ 174 #if !defined(TAPE_QIC02_MAJOR) || !defined(TAPE_QIC02_PORT) || \
175 !defined(TAPE_QIC02_IRQ) || !defined(TAPE_QIC02_DMA)
176 #error tape_qic02 configuration error
177 #endif 178
179
180 #defineTPQIC_NAME "tpqic02"
181
182 /* Linux outb() commands have (value,port) as parameters. 183 * One might expect (port,value) instead, so beware! 184 */ 185
186 staticvolatileintctlbits = 0; /* control reg bits for tape interface */ 187
188 staticstructwait_queue *tape_qic02_transfer = NULL; /* sync rw with interrupts */ 189
190 staticvolatilestructmtgetioctl_status; /* current generic status */ 191
192 staticvolatilestructtpstatustperror; /* last drive status */ 193
194 staticcharrcs_revision[] = "$Revision: 0.2.1.21 $";
195 staticcharrcs_date[] = "$Date: 1993/06/18 19:04:33 $";
196
197 /* Flag bits for status and outstanding requests. 198 * (Could all be put in one bit-field-struct.) 199 * Some variables need `volatile' because they may be modified 200 * by an interrupt. 201 */ 202 staticvolatileflagstatus_dead = YES; /* device is legally dead until proven alive */ 203 staticflagstatus_open = NO; /* in use or not */ 204
205 staticvolatileflagstatus_bytes_wr = NO; /* write FM at close or not */ 206 staticvolatileflagstatus_bytes_rd = NO; /* (rd|wr) used for rewinding */ 207
208 staticvolatileunsignedlongstatus_cmd_pending = 0; /* cmd in progress */ 209 staticvolatileflagstatus_expect_int = NO; /* ready for interrupts */ 210 staticvolatileflagstatus_timer_on = NO; /* using time-out */ 211 staticvolatileintstatus_error = 0; /* int handler may detect error */ 212 staticvolatileflagstatus_eof_detected = NO; /* end of file */ 213 staticvolatileflagstatus_eom_detected = NO; /* end of recorded media */ 214 staticvolatileflagstatus_eot_detected = NO; /* end of tape */ 215 staticvolatileflagdoing_read = NO;
216 staticvolatileflagdoing_write = NO;
217
218 staticvolatileunsignedlongdma_bytes_todo;
219 staticvolatileunsignedlongdma_bytes_done;
220 staticvolatileunsigneddma_mode = 0; /* !=0 also means DMA in use */ 221 staticflagneed_rewind = YES;
222
223 staticdev_tcurrent_tape_dev = (TAPE_QIC02_MAJOR)<<8;
224 staticintextra_blocks_left = BLOCKS_BEYOND_EW;
225
226
227 /* return_*_eof: 228 * NO: not at EOF, 229 * YES: tell app EOF was reached (return 0). 230 * 231 * return_*_eof==YES && reported_*_eof==NO ==> 232 * return current buffer, next time(s) return EOF. 233 * 234 * return_*_eof==YES && reported_*_eof==YES ==> 235 * at EOF and application knows it, so we can 236 * move on to the next file. 237 * 238 */ 239 staticflagreturn_read_eof = NO; /* set to signal app EOF was reached */ 240 staticflagreturn_write_eof = NO;
241 staticflagreported_read_eof = NO; /* set when we've done that */ 242 staticflagreported_write_eof = NO;
243
244
245 #ifdefTP_HAVE_SEEK 246 /* This is for doing `mt seek <blocknr>' */ 247 staticcharseek_addr_buf[SEEK_BUF_SIZE];
248 #endif 249
250
251 /* In write mode, we have to write a File Mark after the last block written, 252 * when the tape device is closed. Tape repositioning and reading in write 253 * mode is allowed as long as no actual writing has been done. After writing 254 * the File Mark, repositioning and reading are allowed again. 255 */ 256 staticintmode_access; /* access mode: READ or WRITE */ 257
258
259 /* This is the actual kernel buffer where the interrupt routines read 260 * from/write to. It is needed because the DMA channels 1 and 3 cannot 261 * access the user buffers. [The kernel buffer must reside in the lower 262 * 1MBytes of system memory because of the DMA controller.] 263 * The user must ensure that a large enough buffer is passed to the 264 * kernel, in order to reduce tape repositioning. 265 * 266 * The buffer is 512 bytes larger than expected, because I want to align it 267 * at 512 bytes, to prevent problems with 64k boundaries. 268 */ 269
270 staticvolatilechartape_qic02_buf[TPQBUF_SIZE+TAPE_BLKSIZE];
271 /* A really good compiler would be able to align this at 512 bytes... :-( */ 272
273 staticunsignedlongbuffaddr; /* aligned physical address of buffer */ 274
275
276 /* This translates minor numbers to the corresponding recording format: */ 277 staticchar *format_names[] = { 278 "not set", /* for dumb drives unable to handle format selection */ 279 "11", /* extinct */ 280 "24",
281 "120",
282 "150",
283 "300", /* untested. */ 284 "600" /* untested. */ 285 };
286
287
288 /* `exception_list' is needed for exception status reporting. 289 * Exceptions 1..14 are defined by QIC-02 rev F. 290 * The drive status is matched sequentially to each entry, 291 * ignoring irrelevant bits, until a match is found. If no 292 * match is found, exception number 0 is used. (That should of 293 * course never happen...) The original table was based on the 294 * "Exception Status Summary" in QIC-02 rev F, but some changes 295 * were required to make it work with real-world drives. 296 * 297 * Exception 1 (CNI) is changed to also cover status 0x00e0 (mask USL), 298 * Exception 4 (EOM) is changed to also cover status 0x8288 (mask EOR), 299 * Exception 11 (FIL) is changed to also cover status 0x0089 (mask EOM). 300 * Exception 15 (EOR) is added for seek-to-end-of-data (catch EOR), 301 * Exception 16 (BOM) is added for beginning-of-media (catch BOM). 302 */ 303 staticstructexception_list_type{ 304 shortmask, code;
305 char *msg;
306 }exception_list[] = { 307 {0, 0,
308 "Unknown exception status code", /* extra: 0 */},
309 {~(TP_WRP|TP_USL), TP_ST0|TP_CNI,
310 /* My Wangtek 5150EQ sometimes reports a status code 311 * of 0x00e0, which is not a valid exception code, but 312 * I think it should be recognized as "NO CARTRIDGE". 313 */ 314 "Cartridge not in place" /* 1 */},
315 {-1, TP_ST0|TP_CNI|TP_USL|TP_WRP,
316 "Drive not online" /* 2 */},
317 {~(TP_ST1|TP_BOM), TP_ST0|TP_WRP,
318 "Write protected cartridge" /* 3 */},
319 {~(TP_ST1|TP_EOR), TP_ST0|TP_EOM,
320 "End of media" /* 4 */},
321 {~TP_WRP, TP_ST0|TP_UDA| TP_ST1|TP_BOM,
322 "Read or Write abort. Rewind tape." /* 5 */},
323 {~TP_WRP, TP_ST0|TP_UDA,
324 "Read error. Bad block transferred." /* 6 */},
325 {~TP_WRP, TP_ST0|TP_UDA|TP_BNL,
326 "Read error. Filler block transferred." /* 7 */},
327 {~TP_WRP, TP_ST0|TP_UDA|TP_BNL |TP_ST1|TP_NDT,
328 "Read error. No data detected." /* 8 */},
329 {~TP_WRP, TP_ST0|TP_EOM|TP_UDA|TP_BNL |TP_ST1|TP_NDT,
330 "Read error. No data detected. EOM." /* 9 */},
331 {~(TP_WRP|TP_MBD|TP_PAR|TP_EOR), TP_ST0|TP_UDA|TP_BNL |TP_ST1|TP_NDT|TP_BOM,
332 "Read error. No data detected. BOM." /* 10 */},
333 {~(TP_WRP|TP_EOM), TP_ST0|TP_FIL,
334 /* Status 0x0089 (EOM & FM) is viewed as an FM, 335 * because it can only happen during a read. 336 * EOM is checked separately for an FM condition. 337 */ 338 "File mark detected" /* 11 */},
339 {~(TP_ST0|TP_CNI|TP_USL|TP_WRP|TP_BOM), TP_ST1|TP_ILL,
340 "Illegal command" /* 12 */},
341 {~(TP_ST0|TP_CNI|TP_USL|TP_WRP|TP_BOM), TP_ST1|TP_POR,
342 "Reset occurred" /* 13 */},
343 {~TP_WRP, TP_ST0|TP_FIL|TP_MBD, /* NOTE: ST1 not set! */ 344 "Marginal block detected" /* 14 */},
345 {~(TP_ST0|TP_WRP|TP_EOM|TP_UDA|TP_BNL|TP_FIL |TP_NDT), TP_ST1|TP_EOR,
346 /********** Is the extra TP_NDT really needed Eddy? **********/ 347 "End of recorded media" /* extra: 15 */},
348 /* 15 is returned when SEEKEOD completes successfully */ 349 {~(TP_WRP|TP_ST0), TP_ST1|TP_BOM,
350 "Beginning of media" /* extra: 16 */} 351 #ifdef CYPHER_BUG
352 /* Perhaps the Cypher driver clears the TP_BOM bit after the 353 * status has been read? The QIC-02 specs explicitly state that 354 * the BOM bit should remain set as long as the tape is logically 355 * at the beginning of the tape. 356 */ 357 ,{-1, TP_ST1,
358 "Hmm, this must be Cypher drive... Aaargh" /* extra */} 359 #endif 360 };
361 #defineNR_OF_EXC (sizeof(exception_list)/sizeof(structexception_list_type))
362
363
364
365 staticvoidtpqputs(char *s)
366 { 367 printk(TPQIC_NAME ": %s\n", s);
368 }/* tpqputs */ 369
370
371 /* Perform byte order swapping for a 16-bit word. 372 * 373 * [FIXME] This should probably be in include/asm/ 374 * ([FIXME] i486 can do this faster) 375 */ 376 staticinlinevoidbyte_swap_w(volatileunsignedshort * w)
/* */ 377 { 378 intt = *w;
379
380 *w = (t>>8) | ((t & 0xff)<<8);
381 } 382
383
384
385 /* Init control register bits on interface card. 386 * For Archive, interrupts must be enabled explicitly. 387 * Wangtek interface card requires ONLINE to be set, Archive SC402/SC499R 388 * cards keep it active all the time. 389 */ 390 staticvoidifc_init(void)
/* */ 391 { 392 #ifTAPE_QIC02_IFC == WANGTEK 393 ctlbits = WT_CTL_ONLINE; /* online */ 394 outb_p(ctlbits, QIC_CTL_PORT);
395
396 #elifTAPE_QIC02_IFC == ARCHIVE 397 ctlbits = 0; /* no interrupts yet */ 398 outb_p(ctlbits, QIC_CTL_PORT);
399 outb_p(0, AR_RESET_DMA_PORT); /* dummy write to reset DMA */ 400 #else 401 # error No valid interface card specified
402 #endif 403 }/* ifc_init */ 404
405
406 staticvoidreport_exception(unsignedn)
/* */ 407 { 408 if (n >= NR_OF_EXC) {tpqputs("Oops -- report_exception"); n = 0; } 409 printk(TPQIC_NAME ": sense: %s\n", exception_list[n].msg);
410 }/* report_exception */ 411
412
413 /* Try to map the drive-exception bits `s' to a predefined "exception number", 414 * by comparing the significant exception bits for each entry in the 415 * exception table (`exception_list[]'). 416 * It is assumed that s!=0. 417 */ 418 staticintdecode_exception_nr(shorts) /* s must be short, because of sign-extension *//* */ 419 { 420 inti;
421
422 for (i=1; i<NR_OF_EXC; i++) { 423 if ((s & exception_list[i].mask)==exception_list[i].code)
424 returni;
425 } 426 tpqputs("decode_exception_nr: exception not recognized");
427 return 0;
428 }/* decode_exception_nr */ 429
430
431 #ifdefOBSOLETE 432 /* There are exactly 14 possible exceptions, as defined in QIC-02 rev F. 433 * Some are FATAL, some aren't. Currently all exceptions are treated as fatal. 434 * Especially 6 and 14 should not abort the transfer. RSN... 435 * Should probably let sense() figure out the exception number using the code 436 * below, and just report the error based on the number here, returning a code 437 * for FATAL/CONTINUABLE. 438 */ 439 staticvoid report_error(ints)
/* */ 440 { 441 shortn = -1;
442
443 if (s & TP_ST1) { 444 if (s & TP_ILL) /* 12: Illegal command. FATAL */ 445 n = 12;
446 if (s & TP_POR) /* 13: Reset occurred. FATAL */ 447 n = 13;
448 } 449 elseif (s & TP_ST0) { 450 if (s & TP_EOR) {/* extra: 15: End of Recorded Media. CONTINUABLE */ 451 n = 15;
452 /********** should set flag here **********/ 453 } 454 elseif (s & TP_EOM) /* 4: End Of Media. CONTINUABLE */ 455 n = 4;
456 elseif (s & TP_USL) /* 2: Drive not online. FATAL */ 457 n = 2;
458 elseif (s & TP_CNI) {/* 1: Cartridge not in place. FATAL */ 459 n = 1;
460 need_rewind = YES;
461 status_eof_detected = NO;
462 status_eom_detected = NO;
463 } 464 elseif (s & TP_UDA) { 465 if (s & TP_BNL) { 466 if (s & TP_NDT) { 467 if (s & TP_BOM) /* 9: Read error. No data detected & EOM. CONTINUABLE */ 468 n = 9;
469 elseif (s & TP_EOM) /* 10: Read error. No data detected & BOM. CONTINUABLE */ 470 n = 10;
471 else/* 8: Read error. No data detected. CONTINUABLE */ 472 n = 8;
473 }else{/* 7: Read error. Cannot recover block, filler substituted. CONTINUABLE */ 474 tpqputs("[Bad block -- filler data transferred.]");
475 n = 7;
476 } 477 } 478 else{ 479 if (s & TP_EOM) /* 5: Read or Write error. Rewind tape. FATAL */ 480 n = 5;
481 else{/* 6: Read error. Bad block transferred. CONTINUABLE */ 482 /* block is bad, but transfer may continue. 483 * This is why some people prefer not to 484 * use compression on backups... 485 */ 486 tpqputs("[CRC failed!]");
487 n = 6;
488 } 489 } 490 } 491 elseif (s & TP_FIL) { 492 if (s & TP_MBD) {/* 14: Marginal block detected. CONTINUABLE */ 493 tpqputs("[Marginal block]");
494 n = 14;
495 }else/* 11: File mark detected. CONTINUABLE */ 496 n = 11;
497 } 498 elseif (s & TP_WRP) /* 3: Write protected cartridge. FATAL */ 499 n = 3;
500 } 501 if (n >= 0)
502 sensemsg(n);
503 }/* report_error */ 504 #endif 505
506
507 /* perform appropriate action for certain exceptions */ 508 staticvoidhandle_exception(intexnr, int exbits)
/* */ 509 { 510 if (exnr==EXC_NCART) { 511 /* Cartridge was changed. Redo sense(). 512 * EXC_NCART should be handled in open(). 513 * It is not permitted to remove the tape while 514 * the tape driver has open files. 515 */ 516 need_rewind = YES;
517 status_eof_detected = NO;
518 status_eom_detected = NO;
519 } 520 elseif (exnr==EXC_XFILLER)
521 tpqputs("[Bad block -- filler data transferred.]");
522 elseif (exnr==EXC_XBAD)
523 tpqputs("[CRC failed!]");
524 elseif (exnr==EXC_MARGINAL) { 525 /* A marginal block behaves much like a FM. 526 * User may continue reading, if desired. 527 */ 528 tpqputs("[Marginal block]");
529 doing_read = NO;
530 }elseif (exnr==EXC_FM)
531 doing_read = NO;
532 }/* handle_exception */ 533
534
535 staticinlineintis_exception(void)
/* */ 536 { 537 return (inb(QIC_STAT_PORT) & QIC_STAT_EXCEPTION) == 0;
538 }/* is_exception */ 539
540
541 /* Reset the tape drive and controller. 542 * When reset fails, it marks the drive as dead and all 543 * requests (except reset) are to be ignored (ENXIO). 544 */ 545 staticinttape_reset(intverbose)
/* */ 546 { 547 ifc_init(); /* reset interface card */ 548
549 outb_p(ctlbits | QIC_CTL_RESET, QIC_CTL_PORT); /* assert reset */ 550
551 /* Next, we need to wait >=25 usec. */ 552 udelay(30);
553
554 /* after reset, we will be at BOT (modulo an automatic rewind) */ 555 status_eof_detected = NO;
556 status_eom_detected = NO;
557 status_cmd_pending = 0;
558 need_rewind = YES;
559 doing_read = doing_write = NO;
560 ioctl_status.mt_fileno = ioctl_status.mt_blkno = 0;
561
562 outb_p(ctlbits & ~QIC_CTL_RESET, QIC_CTL_PORT); /* de-assert reset */ 563 status_dead = ((inb_p(QIC_STAT_PORT) & QIC_STAT_RESETMASK) != QIC_STAT_RESETVAL);
564 /* if successful, inb(STAT) returned RESETVAL */ 565 if (status_dead)
566 printk(TPQIC_NAME ": reset failed!\n");
567 elseif (verbose)
568 printk(TPQIC_NAME ": reset successful\n");
569
570 return (status_dead)? TE_DEAD : TE_OK;
571 }/* tape_reset */ 572
573
574
575 /* Notify tape drive of a new command. It only waits for the 576 * command to be accepted, not for the actual command to complete. 577 * 578 * Before calling this routine, QIC_CMD_PORT must have been loaded 579 * with the command to be executed. 580 * After this routine, the exception bit must be checked. 581 * This routine is also used by rdstatus(), so in that case, any exception 582 * must be ignored (`ignore_ex' flag). 583 */ 584 staticintnotify_cmd(charcmd, shortignore_ex)
/* */ 585 { 586 inti;
587
588 outb_p(cmd, QIC_CMD_PORT); /* output the command */ 589
590 /* wait 1 usec before asserting /REQUEST */ 591 udelay(1);
592
593 if ((!ignore_ex) && is_exception()) { 594 tpqputs("*** exception detected in notify_cmd");
595 /** force a reset here **/ 596 if (tape_reset(1)==TE_DEAD)
597 returnTE_DEAD;
598 if (is_exception()) { 599 tpqputs("exception persists after reset.");
600 tpqputs(" ^ exception ignored.");
601 } 602 } 603
604 outb_p(ctlbits | QIC_CTL_REQUEST, QIC_CTL_PORT); /* set request bit */ 605 i = TAPE_NOTIFY_TIMEOUT;
606 /* The specs say this takes about 500 usec, but there is no upper limit! 607 * If the drive were busy retensioning or something like that, 608 * it could be *much* longer! 609 */ 610 while ((inb_p(QIC_STAT_PORT) & QIC_STAT_READY) && (--i>0))
611 /*skip*/; /* wait for ready */ 612 if (i==0) { 613 tpqputs("timed out waiting for ready in notify_cmd");
614 status_dead = YES;
615 returnTE_TIM;
616 } 617
618 outb_p(ctlbits & ~QIC_CTL_REQUEST, QIC_CTL_PORT); /* reset request bit */ 619 i = TAPE_NOTIFY_TIMEOUT;
620 /* according to the specs this one should never time-out */ 621 while (((inb_p(QIC_STAT_PORT) & QIC_STAT_READY) == 0) && (--i>0))
622 /*skip*/; /* wait for not ready */ 623 if (i==0) { 624 tpqputs("timed out waiting for !ready in notify_cmd");
625 status_dead = YES;
626 returnTE_TIM;
627 } 628 /* command accepted */ 629 returnTE_OK;
630 }/* notify_cmd */ 631
632
633
634 /* Wait for a command to complete, with timeout */ 635 staticintwait_for_ready(time_ttimeout)
/* */ 636 { 637 intstat;
638 time_tspin_t;
639
640 /* Wait for ready or exception, without driving the loadavg up too much. 641 * In most cases, the tape drive already has READY asserted, 642 * so optimize for that case. 643 * 644 * First, busy wait a few usec: 645 */ 646 spin_t = 50;
647 while (((stat = inb_p(QIC_STAT_PORT) & QIC_STAT_MASK) == QIC_STAT_MASK) && (--spin_t>0))
648 /*SKIP*/;
649 if ((stat & QIC_STAT_READY) == 0)
650 returnTE_OK; /* covers 99.99% of all calls */ 651
652 /* Then use schedule() a few times */ 653 spin_t = 3; /* max 0.03 sec busy waiting */ 654 if (spin_t > timeout)
655 spin_t = timeout;
656 timeout -= spin_t;
657 spin_t += jiffies;
658
659 while (((stat = inb_p(QIC_STAT_PORT) & QIC_STAT_MASK) == QIC_STAT_MASK) && (jiffies<spin_t))
660 schedule(); /* don't waste all the CPU time */ 661 if ((stat & QIC_STAT_READY) == 0)
662 returnTE_OK;
663
664 /* If we reach this point, we probably need to wait much longer, or 665 * an exception occurred. Either case is not very time-critical. 666 * Check the status port only a few times every second. 667 * A interval of less than 0.10 sec will not be noticed by the user, 668 * more than 0.40 sec may give noticeable delays. 669 */ 670 spin_t += timeout;
671 TPQDEB({printk("wait_for_ready: additional timeout: %d\n", spin_t);})
672
673 /* not ready and no exception && timeout not expired yet */ 674 while (((stat = inb_p(QIC_STAT_PORT) & QIC_STAT_MASK) == QIC_STAT_MASK) && (jiffies<spin_t)) { 675 /* be `nice` to other processes on long operations... */ 676 current->timeout = jiffies + 30; /* nap 0.30 sec between checks, */ 677 current->state = TASK_INTERRUPTIBLE;
678 schedule(); /* but could be woken up earlier by signals... */ 679 } 680
681 /* don't use jiffies for this test because it may have changed by now */ 682 if ((stat & QIC_STAT_MASK) == QIC_STAT_MASK) { 683 tpqputs("wait_for_ready() timed out");
684 returnTE_TIM;
685 } 686
687 if ((stat & QIC_STAT_EXCEPTION) == 0) { 688 tpqputs("exception detected after waiting_for_ready");
689 returnTE_EX;
690 }else{ 691 returnTE_OK;
692 } 693 }/* wait_for_ready */ 694
695
696 /* Send some data to the drive */ 697 staticintsend_qic02_data(charsb[], unsignedsize, intignore_ex)
/* */ 698 { 699 inti, stat;
700
701 for (i=0; i<size; i++) { 702
703 stat = wait_for_ready(TIM_S);
704 if (stat != TE_OK)
705 returnstat;
706
707 stat = notify_cmd(sb[i], ignore_ex);
708 if (stat != TE_OK)
709 returnstat;
710 } 711 returnTE_OK;
712
713 }/* send_qic02_data */ 714
715
716 /* Send a QIC-02 command (`cmd') to the tape drive, with 717 * a time-out (`timeout'). 718 * This one is also used by tp_sense(), so we must have 719 * a flag to disable exception checking (`ignore_ex'). 720 * 721 * On entry, the controller is supposed to be READY. 722 */ 723 staticintsend_qic02_cmd(intcmd, time_ttimeout, intignore_ex)
/* */ 724 { 725 intstat;
726
727 stat = inb_p(QIC_STAT_PORT);
728 if ((stat & QIC_STAT_EXCEPTION) == 0) {/* if exception */ 729 tpqputs("send_qic02_cmd: Exception!");
730 returnTE_EX;
731 } 732 if (stat & QIC_STAT_READY) {/* if not ready */ 733 tpqputs("send_qic02_cmd: not Ready!");
734 returnTE_ERR;
735 } 736
737 /* assert(ready & !exception) */ 738
739 /* Remember current command for later re-use with dma transfers. 740 * (For reading/writing multiple blocks.) 741 */ 742 status_cmd_pending = cmd;
743
744 stat = notify_cmd(cmd, ignore_ex); /* tell drive new command was loaded, */ 745 /* inherit exception check. */ 746 if (cmd == QCMDV_SEEK_BLK) { 747 /* This one needs to send 3 more bytes, MSB first */ 748 stat = send_qic02_data(seek_addr_buf, sizeof(seek_addr_buf), ignore_ex);
749 } 750 if (stat != TE_OK) { 751 tpqputs("send_qic02_cmd failed");
752 } 753 returnstat;
754 }/* send_qic02_cmd */ 755
756
757
758 /* Get drive status. Assume drive is ready or has exception set. 759 * (or will be in <1000 usec.) 760 * Extra parameters added because of 'Read Extended Status 3' command. 761 */ 762 staticintrdstatus(char *stp, unsignedsize, charqcmd)
/* */ 763 { 764 ints, n;
765 char *q = stp;
766
767 /* Try to busy-wait a few (700) usec, after that de-schedule. 768 * 769 * The problem is, if we don't de-schedule, performance will 770 * drop to zero when the drive is not responding and if we 771 * de-schedule immediately, we waste a lot of time because a 772 * task switch is much longer than we usually have to wait here. 773 */ 774 n = 1000; /* 500 is not enough on a 486/33 */ 775 while ((n>0) && ((inb_p(QIC_STAT_PORT) & QIC_STAT_MASK) == QIC_STAT_MASK))
776 n--; /* wait for ready or exception or timeout */ 777 if (n==0) { 778 /* n (above) should be chosen such that on your machine 779 * you rarely ever see the message below, and it should 780 * be small enough to give reasonable response time.] 781 */ 782 tpqputs("waiting looong in rdstatus() -- drive dead?");
783 while ((inb_p(QIC_STAT_PORT) & QIC_STAT_MASK) == QIC_STAT_MASK)
784 schedule();
785 tpqputs("finished waiting in rdstatus()");
786 } 787
788 (void) notify_cmd(qcmd, 1); /* send read status command */ 789 /* ignore return code -- should always be ok, STAT may contain 790 * exception flag from previous exception which we are trying to clear. 791 */ 792
793 if (TP_DIAGS(current_tape_dev))
794 printk(TPQIC_NAME ": reading status bytes: ");
795
796 for (q=stp; q<stp+size; q++)
797 { 798 dos = inb_p(QIC_STAT_PORT);
799 while ((s & QIC_STAT_MASK) == QIC_STAT_MASK); /* wait for ready or exception */ 800
801 if ((s & QIC_STAT_EXCEPTION) == 0) {/* if exception */ 802 tpqputs("rdstatus: exception error");
803 ioctl_status.mt_erreg = 0; /* dunno... */ 804 returnTE_NS; /* error, shouldn't happen... */ 805 } 806
807 *q = inb_p(QIC_DATA_PORT); /* read status byte */ 808
809 if (TP_DIAGS(current_tape_dev))
810 printk("[%1d]=0x%x ", q-stp, (unsigned) (*q) & 0xff);
811
812 outb_p(ctlbits | QIC_CTL_REQUEST, QIC_CTL_PORT); /* set request */ 813
814 while ((inb_p(QIC_STAT_PORT) & QIC_STAT_READY) == 0); /* wait for not ready */ 815
816 udelay(22); /* delay >20 usec */ 817
818 outb_p(ctlbits & ~QIC_CTL_REQUEST, QIC_CTL_PORT); /* un-set request */ 819
820 } 821
822 /* Specs say we should wait for READY here. 823 * My drive doesn't seem to need it here yet, but others do? 824 */ 825 while (inb_p(QIC_STAT_PORT) & QIC_STAT_READY)
826 /*skip*/; /* wait for ready */ 827
828 if (TP_DIAGS(current_tape_dev))
829 printk("\n");
830
831 returnTE_OK;
832 }/* rdstatus */ 833
834
835
836 /* Get standard status (6 bytes). 837 * The `.dec' and `.urc' fields are in MSB-first byte-order, 838 * so they have to be swapped first. 839 */ 840 staticintget_status(char *stp)
/* */ 841 { 842 intstat = rdstatus(stp, TPSTATSIZE, QCMD_RD_STAT);
843 #ifdefined(i386) || defined(i486)
844 byte_swap_w(&tperror.dec);
845 byte_swap_w(&tperror.urc);
846 #else 847 /* should probably swap status bytes #definition */ 848 #endif 849 returnstat;
850 }/* get_status */ 851
852
853 #if 0
854 /* This fails for my Wangtek drive */ 855 /* get "Extended Status Register 3" (64 bytes) 856 * 857 * If the meaning of the returned bytes were known, the MT_TYPE 858 * identifier could be used to decode them, since they are 859 * "vendor unique". :-( 860 */ 861 staticint get_ext_status3(void)
/* */ 862 { 863 charvus[64]; /* vendor unique status */ 864 intstat, i;
865
866 tpqputs("Attempting to read Extended Status 3...");
867 stat = rdstatus(vus, sizeof(vus), QCMD_RD_STAT_X3);
868 if (stat != TE_OK)
869 returnstat;
870
871 tpqputs("Returned status bytes:");
872 for (i=0; i<sizeof(vus); i++) { 873 if ( i % 8 == 0 )
874 printk("\n" TPQIC_NAME ": %2d:");
875 printk(" %2x", vus[i] & 0xff);
876 } 877 printk("\n");
878
879 returnTE_OK;
880 }/* get_ext_status3 */ 881 #endif 882
883
884 /* Read drive status and set generic status too. 885 * NOTE: Once we do a tp_sense(), read/write transfers are killed. 886 */ 887 staticinttp_sense(intignore)
/* */ 888 { 889 unsignederr = 0, exnr = 0, gs = 0;
890 staticvoidfinish_rw(intcmd);
891
892 printk(TPQIC_NAME ": tp_sense(ignore=0x%x) enter\n", ignore);
893
894 /* sense() is not allowed during a read or write cycle */ 895 if (doing_write == YES)
896 tpqputs("Warning: File Mark inserted because of sense() request");
897 /* The extra test is to avoid calling finish_rw during booting */ 898 if ((doing_read!=NO) || (doing_write!=NO))
899 finish_rw(QCMD_RD_STAT);
900
901 if (get_status((char *) &tperror) != TE_OK) { 902 tpqputs("tp_sense: could not read tape drive status");
903 returnTE_ERR;
904 } 905
906 err = tperror.exs; /* get exception status bits */ 907 if (err & (TP_ST0|TP_ST1))
908 printk(TPQIC_NAME ": tp_sense: status: %x, error count: %d, underruns: %d\n",
909 tperror.exs, tperror.dec, tperror.urc);
910 else 911 printk(TPQIC_NAME ": tp_sense: no errors at all, soft error count: %d, underruns: %d\n",
912 tperror.dec, tperror.urc);
913
914 /* Set generic status. HP-UX defines these, but some extra would 915 * be useful. Problem is to remain compatible. [Do we want to be 916 * compatible??] 917 */ 918 if (err & TP_ST0) { 919 if (err & TP_CNI) /* no cartridge */ 920 gs |= GMT_DR_OPEN(-1);
921 if (status_dead == NO)
922 gs |= GMT_ONLINE(-1); /* always online */ 923 if (err & TP_USL) /* not online */ 924 gs &= ~GMT_ONLINE(-1);
925 if (err & TP_WRP)
926 gs |= GMT_WR_PROT(-1);
927 if (err & TP_EOM) {/* end of media */ 928 gs |= GMT_EOT(-1); /* not sure this is correct for writes */ 929 status_eom_detected = YES;
930 /* I don't know whether drive always reports EOF at or before EOM. */ 931 status_eof_detected = YES;
932 } 933 /** if (err & TP_UDA) "Unrecoverable data error" **/ 934 /** if (err & TP_BNL) "Bad block not located" **/ 935 if (err & TP_FIL) { 936 gs |= GMT_EOF(-1);
937 status_eof_detected = YES;
938 } 939 } 940 if (err & TP_ST1) { 941 /** if (err & TP_ILL) "Illegal command" **/ 942 /** if (err & TP_NDT) "No data detected" **/ 943 /** if (err & TP_MBD) "Marginal block detected" **/ 944 if (err & TP_BOM)
945 gs |= GMT_BOT(-1); /* beginning of tape */ 946 } 947 ioctl_status.mt_gstat = gs;
948 ioctl_status.mt_dsreg = tperror.exs; /* "drive status" */ 949 ioctl_status.mt_erreg = tperror.dec; /* "sense key error" */ 950
951 if (err!=0) { 952 exnr = decode_exception_nr(err);
953 handle_exception(exnr, err); /* update driver state wrt drive status */ 954 report_exception(exnr);
955 } 956 err &= ~ignore; /* mask unwanted errors -- not the correct way, use exception nrs?? */ 957 if (((err & TP_ST0) && (err & REPORT_ERR0)) ||
958 ((err & TP_ST1) && (err & REPORT_ERR1)))
959 returnTE_ERR;
960 returnTE_OK;
961 }/* tp_sense */ 962
963
964
965 /* Wait for a wind or rewind operation to finish or 966 * to time-out. (May take very long). 967 */ 968 staticintwait_for_rewind(time_ttimeout)
/* */ 969 { 970 intstat;
971
972 stat = inb(QIC_STAT_PORT) & QIC_STAT_MASK;
973 printk(TPQIC_NAME ": Waiting for (re-)wind to finish: stat=0x%x\n", stat);
974
975 stat = wait_for_ready(timeout);
976
977 if (stat != TE_OK) { 978 tpqputs("(re-) winding failed\n");
979 } 980 returnstat;
981 }/* wait_for_rewind */ 982
983
984
985 /* Perform a full QIC02 command, and wait for completion, 986 * check status when done. Complain about exceptions. 987 * 988 * This function should return an OS error code when 989 * something goes wrong, 0 otherwise. 990 */ 991 staticintll_do_qic_cmd(intcmd, time_ttimeout)
/* */ 992 { 993 intstat;
994
995 if (status_dead) { 996 tpqputs("Drive is dead. Do a `mt reset`.");
997 return -ENXIO; /* User should do an MTRESET. */ 998 } 999
1000 stat = wait_for_ready(timeout); /* wait for ready or exception */1001 if (stat == TE_EX) {1002 if (tp_sense(TP_WRP|TP_BOM|TP_EOM|TP_FIL)!=TE_OK)
1003 return -EIO;
1004 /* else nothing to worry about, I hope */1005 stat = TE_OK;
1006 }1007 if (stat != TE_OK) {1008 printk(TPQIC_NAME ": ll_do_qic_cmd(%x, %d) failed\n", cmd, timeout);
1009 return -EIO;
1010 }1011
1012
1013 #ifOBSOLETE1014 /* wait for ready since it may not be active immediately after reading status */1015 while ((inb_p(QIC_STAT_PORT) & QIC_STAT_READY) != 0);
1016 #endif1017
1018 stat = send_qic02_cmd(cmd, timeout, 0); /* (checks for exceptions) */1019
1020 if (cmd==QCMD_RD_FM) {1021 status_eof_detected = NO;
1022 ioctl_status.mt_fileno++;
1023 /* Should update block count as well, but can't.1024 * Can do a `read address' for some drives, when MTNOP is done.1025 */1026 }elseif (cmd==QCMD_WRT_FM) {1027 status_eof_detected = NO;
1028 ioctl_status.mt_fileno++;
1029 }elseif ((cmd==QCMD_REWIND) || (cmd==QCMD_ERASE) || (cmd==QCMD_RETEN)) {1030 status_eof_detected = NO;
1031 status_eom_detected = NO;
1032 status_eot_detected = NO;
1033 need_rewind = NO;
1034 ioctl_status.mt_fileno = ioctl_status.mt_blkno = 0;
1035 extra_blocks_left = BLOCKS_BEYOND_EW;
1036 return_write_eof = NO;
1037 return_read_eof = NO;
1038 reported_read_eof = NO;
1039 reported_write_eof = NO;
1040 }1041 /* sense() will set eof/eom as required */1042 if (stat==TE_EX) {1043 if (tp_sense(TP_WRP|TP_BOM|TP_EOM|TP_FIL)!=TE_OK) {1044 printk(TPQIC_NAME ": Exception persist in ll_do_qic_cmd[1](%x, %d)", cmd, timeout);
1045 status_dead = YES;
1046 return -ENXIO;
1047 /* if rdstatus fails too, we're in trouble */1048 }1049 }1050 elseif (stat!=TE_OK) {1051 printk(TPQIC_NAME ": ll_do_qic_cmd: send_qic02_cmd failed, stat = 0x%x\n", stat);
1052 return -EIO; /*** -EIO is probably not always appropriate */1053 }1054
1055
1056 if (timeout == TIM_R)
1057 stat = wait_for_rewind(timeout);
1058 else1059 stat = wait_for_ready(timeout);
1060
1061 if (stat==TE_EX) {1062 if (tp_sense((cmd==QCMD_SEEK_EOD ? /*****************************/1063 TP_EOR|TP_NDT|TP_UDA|TP_BNL|TP_WRP|TP_BOM|TP_EOM|TP_FIL :
1064 TP_WRP|TP_BOM|TP_EOM|TP_FIL))!=TE_OK) {1065 printk(TPQIC_NAME ": Exception persist in ll_do_qic_cmd[2](%x, %d)\n", cmd, timeout);
1066 if (cmd!=QCMD_RD_FM)
1067 status_dead = YES;
1068 return -ENXIO;
1069 /* if rdstatus fails too, we're in trouble */1070 }1071 }1072 elseif (stat!=TE_OK) {1073 printk(TPQIC_NAME ": ll_do_qic_cmd %x: wait failed, stat == 0x%x\n", cmd, stat);
1074 return -EIO;
1075 }1076 return 0;
1077 }/* ll_do_qic_cmd */1078
1079
1080 /* 1081 * Problem: What to do when the user cancels a read/write operation1082 * in-progress?1083 *1084 * "Deactivating ONLINE during a READ also causes the"1085 * "tape to be rewound to BOT." Ditto for WRITEs, except1086 * a FM is written first. "The host may alternatively terminate1087 * the READ/WRITE command by issuing a RFM/WFM command."1088 *1089 * For READs:1090 * Neither option will leave the tape positioned where it was.1091 * Another (better?) solution is to terminate the READ by two1092 * subsequent sense() operations, the first to stop the current1093 * READ cycle, the second to clear the `Illegal command' exception,1094 * because the QIC-02 specs didn't anticipate this. This is1095 * delayed until actually needed, so a tar listing can be aborted1096 * by the user and continued later.1097 * If anybody has a better solution, let me know! [Also, let me1098 * know if your drive (mine is a Wangtek5150EQ) does not accept1099 * this sequence for canceling the read-cycle.]1100 *1101 * For WRITEs it's simple: Just do a WRITE_FM, leaving the tape1102 * positioned after the FM.1103 */1104
1105 staticvoidterminate_read(intcmd)
/* */1106 {1107 if (doing_read == YES) {1108 doing_read = NO;
1109 if (cmd != QCMD_RD_FM) {1110 /* if the command is a RFM, there is no need to do this1111 * because a RFM will legally terminate the read-cycle.1112 */1113 tpqputs("terminating pending read-cycle");
1114 if (tp_sense(TP_FIL|TP_EOM|TP_WRP) != TE_OK) {1115 tpqputs("finish_rw[read1]: ignore the 2 lines above");
1116 if (is_exception()) {1117 if (tp_sense(TP_ILL|TP_FIL|TP_EOM|TP_WRP) != TE_OK)
1118 tpqputs("finish_rw[read2]: read cycle error");
1119 }1120 }1121 }1122 }1123 }/* terminate_read */1124
1125
1126 staticvoidterminate_write(intcmd)
/* */1127 {1128 intstat;
1129
1130 if (doing_write == YES) {1131 doing_write = NO;
1132 /* Finish writing by appending a FileMark at the end. */1133 if (cmd != QCMD_WRT_FM) {1134 /* finish off write cycle */1135 stat = ll_do_qic_cmd(QCMD_WRT_FM, TIM_M);
1136 if (stat != TE_OK)
1137 tpqputs("Couldn't finish write cycle properly");
1138 (void) tp_sense(0);
1139 }1140 /* If there is an EOF token waiting to be returned to1141 * the (writing) application, discard it now.1142 * We could be at EOT, so don't reset return_write_eof.1143 */1144 reported_write_eof=YES;
1145 }1146 }/* terminate_write */1147
1148
1149 /* terminate read or write cycle because of command `cmd' */1150 staticvoidfinish_rw(intcmd)
/* */1151 {1152 if (wait_for_ready(TIM_S) != TE_OK) {1153 tpqputs("error: drive not ready in finish_rw() !");
1154 return;
1155 }1156 terminate_read(cmd);
1157 terminate_write(cmd);
1158 }/* finish_rw */1159
1160
1161 /* Perform a QIC command through ll_do_qic_cmd().1162 * If necessary, rewind the tape first.1163 * Return an OS error code if something goes wrong, 0 if all is well.1164 */1165 staticintdo_qic_cmd(intcmd, time_ttimeout)
/* */1166 {1167 intstat;
1168
1169
1170 finish_rw(cmd);
1171
1172 if (need_rewind) {1173 tpqputs("Rewinding tape...");
1174 stat = ll_do_qic_cmd(QCMD_REWIND, TIM_R);
1175 if (stat != 0) {1176 printk(TPQIC_NAME ": rewind failed in do_qic_cmd(). stat=0x%2x", stat);
1177 returnstat;
1178 }1179 need_rewind = NO;
1180 if (cmd==QCMD_REWIND) /* don't wind beyond BOT ;-) */1181 return 0;
1182 }1183
1184 returnll_do_qic_cmd(cmd, timeout);
1185 }/* do_qic_cmd */1186
1187
1188 /* Not all ioctls are supported for all drives. Some rely on1189 * optional QIC-02 commands. Check tpqic02.h for configuration.1190 * Some of these commands may require ONLINE to be active.1191 */1192 staticintdo_ioctl_cmd(intcmd)
/* */1193 {1194 intstat;
1195
1196 /* It is not permitted to read or wind the tape after bytes have1197 * been written. It is not permitted to write the tape while in1198 * read mode.1199 * We try to be kind and allow reading again after writing a FM...1200 */1201
1202 switch (cmd) {1203 caseMTRESET:
1204 /* reset verbose */1205 return (tape_reset(1)==TE_OK)? 0 : -EIO;
1206
1207 caseMTFSF:
1208 tpqputs("MTFSF forward searching filemark");
1209 if ((mode_access==WRITE) && status_bytes_wr)
1210 return -EACCES;
1211 returndo_qic_cmd(QCMD_RD_FM, TIM_F);
1212
1213 caseMTBSF:
1214 #ifdefTP_HAVE_BSF1215 tpqputs("MTBSF backward searching filemark -- optional command");
1216 if ((mode_access==WRITE) && status_bytes_wr)
1217 return -EACCES;
1218 stat = do_qic_cmd(QCMD_RD_FM_BCK, TIM_F);
1219 #else1220 tpqputs("MTBSF not supported");
1221 stat = -ENXIO;
1222 #endif1223 status_eom_detected = status_eof_detected = NO;
1224 returnstat;
1225
1226 caseMTFSR:
1227 #ifdefTP_HAVE_FSR/* This is an optional QIC-02 command */1228 tpqputs("MTFSR forward space record");
1229 if ((mode_access==WRITE) && status_bytes_wr)
1230 return -EACCES;
1231 stat = do_qic_cmd(QCMD_SPACE_FWD, TIM_F);
1232 #else1233 /**** fake it by doing a read data block command? ******/1234 tpqputs("MTFSR not supported");
1235 stat = -ENXIO;
1236 #endif1237 returnstat;
1238
1239 caseMTBSR:
1240 #ifdefTP_HAVE_BSR/* This is an optional QIC-02 command */1241 /* we need this for appending files with GNU tar!! */1242 tpqputs("MTFSR backward space record");
1243 if ((mode_access==WRITE) && status_bytes_wr)
1244 return -EACCES;
1245 stat = do_qic_cmd(QCMD_SPACE_BCK, TIM_F);
1246 #else1247 tpqputs("MTBSR not supported");
1248 stat = -ENXIO;
1249 #endif1250 status_eom_detected = status_eof_detected = NO;
1251 returnstat;
1252
1253 caseMTWEOF:
1254 tpqputs("MTWEOF write eof mark");
1255 /* Plain GNU mt(1) 2.2 uses read-only mode for writing FM. :-( */1256 if (mode_access==READ)
1257 return -EACCES;
1258
1259 /* allow tape movement after writing FM */1260 status_bytes_rd = status_bytes_wr; /* Kludge-O-Matic */1261 status_bytes_wr = NO;
1262 returndo_qic_cmd(QCMD_WRT_FM, TIM_M);
1263 /* not sure what to do with status_bytes when WFM should fail */1264
1265 caseMTREW:
1266 tpqputs("MTREW rewinding tape");
1267 if ((mode_access==WRITE) && status_bytes_wr)
1268 return -EACCES;
1269 status_eom_detected = status_eof_detected = NO;
1270 returndo_qic_cmd(QCMD_REWIND, TIM_R);
1271
1272 caseMTOFFL:
1273 tpqputs("MTOFFL rewinding & going offline"); /*---*/1274 /******* What exactly are we supposed to do, to take it offline????1275 *****/1276 /* Doing a drive select will clear (unlock) the current drive.1277 * But that requires support for multiple drives and locking.1278 */1279 if ((mode_access==WRITE) && status_bytes_wr)
1280 return -EACCES;
1281 status_eom_detected = status_eof_detected = NO;
1282 /**** do rewind depending on minor bits??? ***/1283 stat = do_qic_cmd(QCMD_REWIND, TIM_R);
1284 returnstat;
1285
1286 caseMTNOP:
1287 tpqputs("MTNOP setting status only");
1288 /********** should do `read position' for drives that support it **********/1289 return (tp_sense(-1)==TE_OK)? 0 : -EIO; /**** check return codes ****/1290
1291 caseMTRETEN:
1292 tpqputs("MTRETEN retension tape");
1293 if ((mode_access==WRITE) && status_bytes_wr)
1294 return -EACCES;
1295 status_eom_detected = status_eof_detected = NO;
1296 returndo_qic_cmd(QCMD_RETEN, TIM_R);
1297
1298 caseMTBSFM:
1299 /* Think think is like MTBSF, except that1300 * we shouldn't skip the FM. Tricky.1301 * Maybe use RD_FM_BCK, then do a SPACE_FWD?1302 */1303 tpqputs("MTBSFM not supported");
1304 if ((mode_access==WRITE) && status_bytes_wr)
1305 return -EACCES;
1306 return -ENXIO;
1307
1308 caseMTFSFM:
1309 /* I think this is like MTFSF, except that1310 * we shouldn't skip the FM. Tricky.1311 * Maybe use QCMD_RD_DATA until we get a TP_FIL exception?1312 * But then the FM will have been skipped...1313 * Maybe use RD_FM, then RD_FM_BCK, but not all1314 * drives will support that!1315 */1316 tpqputs("MTFSFM not supported");
1317 if ((mode_access==WRITE) && status_bytes_wr)
1318 return -EACCES;
1319 return -ENXIO;
1320
1321 caseMTEOM:
1322 /* This should leave the tape ready for appending1323 * another file to the end, such that it would append1324 * after the last FM on tape.1325 */1326 tpqputs("MTEOM search for End Of recorded Media");
1327 if ((mode_access==WRITE) && status_bytes_wr)
1328 return -EACCES;
1329 #ifdefTP_HAVE_EOD1330 /* Use faster seeking when possible.1331 * This requires the absence of data beyond the EOM.1332 */1333 # ifTAPE_QIC02_DRIVE == MT_ISWT51501334 /* It seems that my drive does not always perform the1335 * SEEK_EOD correctly, unless it is preceded by a1336 * rewind command.1337 */1338 # if 0
1339 status_eom_detected = status_eof_detected = NO;
1340 # endif1341 stat = do_qic_cmd(QCMD_REWIND, TIM_R);
1342 if (stat)
1343 returnstat;
1344
1345 # endif1346 stat = do_qic_cmd(QCMD_SEEK_EOD, TIM_F);
1347 /* After a successful seek, TP_EOR should be returned */1348 #else1349 /* else just seek until the drive returns exception "No Data" */1350 stat = 0;
1351 while ((stat==0) && (!status_eom_detected)) {1352 stat = do_qic_cmd(QCMD_RD_FM, TIM_F); /***** should use MTFSFM here???? ******/1353 }1354 if (tperror.exs & TP_NDT)
1355 return 0;
1356 #endif1357 returnstat;
1358
1359 caseMTERASE:
1360 tpqputs("MTERASE -- ERASE TAPE !");
1361 if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP)) {1362 tpqputs("Cartridge is write-protected.");
1363 return -EACCES;
1364 }else{1365 time_tt = jiffies;
1366 /* give user a few seconds to pull out tape */1367 while (jiffies - t < 3*HZ)
1368 schedule();
1369 }1370
1371 /* Plain GNU mt(1) 2.2 erases a tape in O_RDONLY. :-( */1372 if (mode_access==READ)
1373 return -EACCES;
1374
1375 /* don't bother writing filemark */1376 status_eom_detected = status_eof_detected = NO;
1377 returndo_qic_cmd(QCMD_ERASE, TIM_R);
1378
1379
1380 caseMTRAS1:
1381 #ifdefTP_HAVE_RAS11382 tpqputs("MTRAS1: non-destructive self test");
1383 stat = do_qic_cmd(QCMD_SELF_TST1, TIM_R);
1384 if (stat != 0) {1385 tpqputs("RAS1 failed");
1386 returnstat;
1387 }1388 return (tp_sense(0)==TE_OK)? 0 : -EIO; /* get_ext_status3(); */1389 #else1390 tpqputs("RAS1 not supported");
1391 return -ENXIO;
1392 #endif1393
1394 caseMTRAS2:
1395 #ifdefTP_HAVE_RAS21396 tpqputs("MTRAS2: destructive self test");
1397 stat = do_qic_cmd(QCMD_SELF_TST2, TIM_R);
1398 if (stat != 0) {1399 tpqputs("RAS2 failed");
1400 returnstat;
1401 }1402 return (tp_sense(0)==TE_OK)? 0 : -EIO; /* get_ext_status3(); */1403 #else1404 tpqputs("RAS2 not supported");
1405 return -ENXIO;
1406 #endif1407
1408 #ifdefTP_HAVE_SEEK1409 caseMTSEEK:
1410 tpqputs("MTSEEK seeking block");
1411 if ((mode_access==WRITE) && status_bytes_wr)
1412 return -EACCES;
1413 /* NOTE: address (24 bits) is in seek_addr_buf[] */1414 returndo_qic_cmd(QCMDV_SEEK_BLK, TIM_F);
1415 #endif1416
1417 default:
1418 return -ENOTTY;
1419 }1420 }/* do_ioctl_cmd */1421
1422
1423 /* dma_transfer(): This routine is called for every 512 bytes to be read1424 * from/written to the tape controller. Speed is important here!1425 * (There must be enough time left for the hd controller!)1426 * When other devices use DMA they must ensure they use un-interruptible1427 * double byte accesses to the DMA controller. Floppy.c is ok.1428 * Must have interrupts disabled when this function is invoked,1429 * otherwise, the double-byte transfers to the DMA controller will not1430 * be atomic. That could lead to nasty problems when they are interrupted1431 * by other DMA interrupt-routines.1432 *1433 * This routine merely does the least possible to keep1434 * the transfers going:1435 * - set the DMA count register for the next 512 bytes1436 * - adjust the DMA address and page registers1437 * - adjust the timeout1438 * - tell the tape controller to start transferring1439 * We assume the dma address and mode are, and remain, valid.1440 */1441 staticinlinevoiddma_transfer(void)
/* */1442 {1443
1444 #ifTAPE_QIC02_IFC == WANGTEK1445 outb_p(WT_CTL_ONLINE, QIC_CTL_PORT); /* back to normal */1446 #elifTAPE_QIC02_IFC == ARCHIVE1447 outb_p(0, AR_RESET_DMA_PORT);
1448 #endif1449
1450 clear_dma_ff(TAPE_QIC02_DMA);
1451 set_dma_mode(TAPE_QIC02_DMA, dma_mode);
1452 set_dma_addr(TAPE_QIC02_DMA, buffaddr+dma_bytes_done); /* full address */1453 set_dma_count(TAPE_QIC02_DMA, TAPE_BLKSIZE);
1454
1455 /* start tape DMA controller */1456 #ifTAPE_QIC02_IFC == WANGTEK1457 outb_p(WT_CTL_DMA | WT_CTL_ONLINE, QIC_CTL_PORT); /* trigger DMA transfer */1458 #elifTAPE_QIC02_IFC == ARCHIVE1459 outb_p(AR_CTL_IEN | AR_CTL_DNIEN, QIC_CTL_PORT); /* enable interrupts again */1460 outb_p(0, AR_START_DMA_PORT); /* start DMA transfer */1461 /* In dma_end() AR_RESET_DMA_PORT is written too. */1462 #endif1463
1464 /* start computer DMA controller */1465 enable_dma(TAPE_QIC02_DMA);
1466 /* block transfer should start now, jumping to the 1467 * interrupt routine when done or an exception was detected.1468 */1469 }/* dma_transfer */1470
1471
1472 /* start_dma() sets a DMA transfer up between the tape controller and1473 * the kernel tape_qic02_buf buffer.1474 * Normally bytes_todo==dma_bytes_done at the end of a DMA transfer. If not,1475 * a filemark was read, or an attempt to write beyond the End Of Tape 1476 * was made. [Or some other bad thing happened.]1477 * Must do a sense() before returning error.1478 */1479 staticintstart_dma(shortmode, unsignedlongbytes_todo)
/* */1480 /* assume 'bytes_todo'>0 */1481 {1482 intstat;
1483
1484 TPQPUTS("start_dma() enter");
1485 TPQDEB({printk(TPQIC_NAME ": doing_read==%d, doing_write==%d\n", doing_read, doing_write);})
1486
1487 dma_bytes_done = 0;
1488 dma_bytes_todo = bytes_todo;
1489 status_error = NO;
1490 /* dma_mode!=0 indicates that the dma controller is in use */1491 dma_mode = (mode == WRITE)? DMA_MODE_WRITE : DMA_MODE_READ;
1492
1493 /* Only give READ/WRITE DATA command to tape drive if we haven't1494 * done that already. Otherwise the drive will rewind to the beginning1495 * of the current file on tape. Any QIC command given other than1496 * R/W FM will break the read/write transfer cycle.1497 * do_qic_cmd() will terminate doing_{read,write}1498 */1499 if ((doing_read == NO) && (doing_write == NO)) {1500 /* First, we have to clear the status -- maybe remove TP_FIL???1501 */1502
1503 #if 0
1504 /* Next dummy get status is to make sure CNI is valid,1505 since we're only just starting a read/write it doesn't1506 matter some exceptions are cleared by reading the status;1507 we're only interested in CNI and WRP. -Eddy */1508 get_status((char *) &tperror);
1509 #else1510 /* TP_CNI should now be handled in open(). -Hennus */1511 #endif1512
1513 stat = tp_sense(((mode == WRITE)? 0 : TP_WRP) | TP_BOM | TP_FIL);
1514 if (stat != TE_OK)
1515 returnstat;
1516
1517 #ifOBSOLETE1518 /************* not needed iff rd_status() would wait for ready!!!!!! **********/1519 if (wait_for_ready(TIM_S) != TE_OK) {/*** not sure this is needed ***/1520 tpqputs("wait_for_ready failed in start_dma");
1521 return -EIO;
1522 }1523 #endif1524
1525 /* Tell the controller the data direction */1526
1527 /* r/w, timeout medium, check exceptions, sets status_cmd_pending. */1528 stat = send_qic02_cmd((mode == WRITE)? QCMD_WRT_DATA : QCMD_RD_DATA, TIM_M, 0);
1529 if (stat!=TE_OK) {1530 printk(TPQIC_NAME ": start_dma: init %s failed\n",
1531 (mode == WRITE)? "write" : "read");
1532 (void) tp_sense(0);
1533 returnstat;
1534 }1535
1536 /* Do this last, because sense() will clear the doing_{read,write}1537 * flags, causing trouble next time around.1538 */1539 if (wait_for_ready(TIM_M) != TE_OK)
1540 return -EIO;
1541 switch (mode) {1542 caseREAD:
1543 doing_read = YES;
1544 break;
1545 caseWRITE:
1546 doing_write = YES;
1547 break;
1548 default:
1549 printk(TPQIC_NAME ": requested unknown mode %d\n", mode);
1550 panic(TPQIC_NAME ": invalid mode in start_dma()");
1551 }1552
1553 }elseif (is_exception()) {1554 /* This is for Archive drives, to handle reads with 0 bytes1555 * left for the last read request.1556 *1557 * ******** this also affects EOF/EOT handling! ************1558 */1559 tpqputs("detected exception in start_dma() while transfer in progress");
1560 status_error = YES;
1561 returnTE_END;
1562 }1563
1564
1565 status_expect_int = YES;
1566
1567 /* This assumes tape is already positioned, but these1568 * semi-'intelligent' drives are unpredictable...1569 */1570 TIMERON(TIM_M*2);
1571
1572 /* initiate first data block read from/write to the tape controller */1573
1574 cli();
1575 dma_transfer();
1576 sti();
1577
1578 TPQPUTS("start_dma() end");
1579 returnTE_OK;
1580 }/* start_dma */1581
1582
1583 /* This cleans up after the dma transfer has completed1584 * (or failed). If an exception occurred, a sense()1585 * must be done. If the exception was caused by a FM,1586 * sense() will set `status_eof_detected' and1587 * `status_eom_detected', as required.1588 */1589 staticvoidend_dma(unsignedlong * bytes_done)
/* */1590 {1591 intstat = TE_OK;
1592
1593 TIMEROFF;
1594
1595 TPQPUTS("end_dma() enter");
1596
1597 disable_dma(TAPE_QIC02_DMA);
1598 clear_dma_ff(TAPE_QIC02_DMA);
1599
1600 #ifTAPE_QIC02_IFC == WANGTEK1601 outb_p(WT_CTL_ONLINE, QIC_CTL_PORT); /* back to normal */1602 #elifTAPE_QIC02_IFC == ARCHIVE1603 outb_p(0, AR_RESET_DMA_PORT);
1604 #endif1605
1606 stat = wait_for_ready(TIM_M);
1607 if (status_error || (stat!=TE_OK)) {1608 tpqputs("DMA transfer exception");
1609 stat = tp_sense((dma_mode==READ)? TP_WRP : 0);
1610 /* no return here -- got to clean up first! */1611 }1612 /* take the tape controller offline */1613
1614 /* finish off DMA stuff */1615
1616
1617 dma_mode = 0;
1618 /* Note: The drive is left on-line, ready for the next1619 * data transfer.1620 * If the next command to the drive does not continue1621 * the pending cycle, it must do 2 sense()s first.1622 */1623
1624 *bytes_done = dma_bytes_done;
1625 status_expect_int = NO;
1626 ioctl_status.mt_blkno += (dma_bytes_done / TAPE_BLKSIZE);
1627
1628 TPQPUTS("end_dma() exit");
1629 /*** could return stat here ***/1630 }/* end_dma */1631
1632 /*********** Below are the (public) OS-interface procedures ***********/1633
1634
1635 /* tape_qic02_times_out() is called when a DMA transfer doesn't complete1636 * quickly enough. Usually this means there is something seriously wrong1637 * with the hardware/software, but it could just be that the controller1638 * has decided to do a long rewind, just when I didn't expect it.1639 * Just try again.1640 */1641 staticvoidtape_qic02_times_out(void)
/* */1642 {1643 printk("time-out in %s driver\n", TPQIC_NAME);
1644 if ((status_cmd_pending>0) || dma_mode) {1645 /* takes tooo long, shut it down */1646 status_dead = YES;
1647 status_cmd_pending = 0;
1648 status_timer_on = NO;
1649 status_expect_int = NO;
1650 status_error = YES;
1651 if (dma_mode) {1652 dma_mode = 0; /* signal end to read/write routine */1653 wake_up(&tape_qic02_transfer);
1654 }1655 }1656 }/* tape_qic02_times_out */1657
1658 /*1659 * Interrupt handling:1660 *1661 * 1) Interrupt is generated iff at the end of 1662 * a 512-DMA-block transfer.1663 * 2) EXCEPTION is not raised unless something 1664 * is wrong or EOT/FM is detected.1665 * 3) FM EXCEPTION is set *after* the last byte has1666 * been transferred by DMA. By the time the interrupt1667 * is handled, the EXCEPTION may already be set.1668 *1669 * So,1670 * 1) On EXCEPTION, assume data has been transferred, so1671 * continue as usual, but set a flag to indicate the1672 * exception was detected.1673 * Do a sense status when the flag is found set.1674 * 2) Do not attempt to continue a transfer after an exception.1675 * [??? What about marginal blocks???????]1676 */1677
1678
1679 /* tape_qic02_interrupt() is called when the tape controller completes 1680 * a DMA transfer.1681 * We are not allowed to sleep here! 1682 *1683 * Check if the transfer was successful, check if we need to transfer1684 * more. If the buffer contains enough data/is empty enough, signal the1685 * read/write() thread to copy to/from user space.1686 * When we are finished, set flags to indicate end, disable timer.1687 * NOTE: This *must* be fast! 1688 */1689 staticvoidtape_qic02_interrupt(intunused)
/* */1690 {1691 intstat, r, i;
1692
1693 TIMEROFF;
1694
1695 if (status_expect_int) {1696 if (TP_DIAGS(current_tape_dev))
1697 printk("@");
1698
1699 stat = inb(QIC_STAT_PORT); /* Knock, knock */1700 #ifTAPE_QIC02_IFC == ARCHIVE/* "Who's there?" */1701 if (((stat & (AR_STAT_DMADONE)) == 0) &&
1702 ((stat & (QIC_STAT_EXCEPTION)) != 0)) {1703 TIMERCONT;
1704 return; /* "Linux with IRQ sharing" */1705 }1706 #endif1707 if ((stat & QIC_STAT_EXCEPTION) == 0) {/* exception occurred */1708 /* Possible causes for an exception during a transfer:1709 * - during a write-cycle: end of tape (EW) hole detected.1710 * - during a read-cycle: filemark or EOD detected.1711 * - something went wrong1712 * So don't continue with the next block.1713 */1714 tpqputs("isr: exception on tape controller");
1715 printk(" status %02x\n", stat);
1716 status_error = TE_EX;
1717
1718 dma_bytes_done += TAPE_BLKSIZE;
1719
1720 dma_mode = 0; /* wake up rw() */1721 status_expect_int = NO;
1722 wake_up(&tape_qic02_transfer);
1723 return;
1724 }1725 /* return if tape controller not ready, or1726 * if dma channel hasn't finished last byte yet.1727 */1728 r = 0;
1729 /* Skip next ready check for Archive controller because1730 * it may be busy reading ahead. Weird. --hhb1731 */1732 #ifTAPE_QIC02_IFC != ARCHIVE/* I think this is a drive-dependency, not IFC -- hhb */1733 if (stat & QIC_STAT_READY) {/* not ready */1734 tpqputs("isr: ? Tape controller not ready");
1735 r = 1;
1736 }1737 #endif1738
1739 if ( (i = get_dma_residue(TAPE_QIC02_DMA)) != 0 ) {1740 printk(TPQIC_NAME ": dma_residue == %x !!!\n", i);
1741 r = 1; /* big trouble, but can't do much about it... */1742 }1743
1744 if (r)
1745 return;
1746
1747 /* finish DMA cycle */1748
1749 /* no errors detected, continue */1750 dma_bytes_done += TAPE_BLKSIZE;
1751 if (dma_bytes_done >= dma_bytes_todo) {1752 /* finished! Wakeup rw() */1753 dma_mode = 0;
1754 status_expect_int = NO;
1755 TPQPUTS("isr: dma_bytes_done");
1756 wake_up(&tape_qic02_transfer);
1757 }else{1758 /* start next transfer, account for track-switching time */1759 timer_table[TAPE_QIC02_TIMER].expires = jiffies + 6*HZ;
1760 dma_transfer();
1761 }1762 }else{1763 printk(TPQIC_NAME ": Unexpected interrupt, stat == %x\n",
1764 inb(QIC_STAT_PORT));
1765 }1766 }/* tape_qic02_interrupt */1767
1768
1769 staticinttape_qic02_lseek(structinode * inode, structfile * file, off_toffset, intorigin)
/* */1770 {1771 return -EINVAL; /* not supported */1772 }/* tape_qic02_lseek */1773
1774
1775 /* read/write routines:1776 * This code copies between a kernel buffer and a user buffer. The 1777 * actual data transfer is done using DMA and interrupts. Time-outs1778 * are also used.1779 *1780 * When a filemark is read, we return '0 bytes read' and continue with the1781 * next file after that.1782 * When EOM is read, we return '0 bytes read' twice.1783 * When the EOT marker is detected on writes, '0 bytes read' should be1784 * returned twice. If user program does a MTNOP after that, 2 additional1785 * blocks may be written. ------- FIXME: Implement this correctly *************************************************1786 *1787 * Only read/writes in multiples of 512 bytes are accepted.1788 * When no bytes are available, we sleep() until they are. The controller will1789 * generate an interrupt, and we (should) get a wake_up() call.1790 *1791 * Simple buffering is used. User program should ensure that a large enough1792 * buffer is used. Usually the drive does some buffering as well (something1793 * like 4k or so).1794 *1795 * Scott S. Bertilson suggested to continue filling the user buffer, rather1796 * than waste time on a context switch, when the kernel buffer fills up.1797 */1798
1799 /*1800 * Problem: tar(1) doesn't always read the entire file. Sometimes the entire file1801 * has been read, but the EOF token is never returned to tar(1), simply because1802 * tar(1) knows it has already read all of the data it needs. So we must use1803 * open/release to reset the `reported_read_eof' flag. If we don't, the next read1804 * request would return the EOF flag for the previous file.1805 */1806
1807 staticinttape_qic02_read(structinode * inode, structfile * filp, char * buf, intcount)
/* */1808 {1809 interror;
1810 dev_tdev = inode->i_rdev;
1811 unsignedshortflags = filp->f_flags;
1812 unsignedlongbytes_todo, bytes_done, total_bytes_done = 0;
1813 intstat;
1814
1815 if (TP_DIAGS(current_tape_dev))
1816 printk(TPQIC_NAME ": request READ, minor=%x, buf=%lx, count=%x, pos=%x, flags=%x\n",
1817 MINOR(dev), buf, count, filp->f_pos, flags);
1818
1819 if (count % TAPE_BLKSIZE) {/* Only allow mod 512 bytes at a time. */1820 tpqputs("Wrong block size");
1821 return -EINVAL;
1822 }1823
1824 /* Just assume everything is ok. Controller will scream if not. */1825
1826 if (status_bytes_wr) /* Once written, no more reads, 'till after WFM. */1827 return -EACCES;
1828
1829
1830 /* Make sure buffer is safe to write into. */1831 error = verify_area(VERIFY_WRITE, buf, count);
1832 if (error) {1833 printk(TPQIC_NAME ": read: verify_area(WRITE, %lx, %x) failed\n", buf, count);
1834 returnerror;
1835 }1836
1837 /* This is rather ugly because it has to implement a finite state1838 * machine in order to handle the EOF situations properly.1839 */1840 while (count>=0) {1841 bytes_done = 0;
1842 /* see how much fits in the kernel buffer */1843 bytes_todo = TPQBUF_SIZE;
1844 if (bytes_todo>count)
1845 bytes_todo = count;
1846
1847 /* Must ensure that user program sees exactly one EOF token (==0) */1848 if (return_read_eof==YES) {1849 printk("read: return_read_eof==%d, reported_read_eof==%d, total_bytes_done==%d\n", return_read_eof, reported_read_eof, total_bytes_done);
1850
1851 if (reported_read_eof==NO) {1852 /* have not yet returned EOF to user program */1853 if (total_bytes_done>0) {1854 returntotal_bytes_done; /* next time return EOF */1855 }else{1856 reported_read_eof = YES; /* move on next time */1857 return 0; /* return EOF */1858 }1859 }else{1860 /* Application program has already received EOF1861 * (above), now continue with next file on tape,1862 * if possible.1863 * When the FM is reached, EXCEPTION is set,1864 * causing a sense(). Subsequent read/writes will1865 * continue after the FM.1866 */1867 /*********** ?????????? this should check for (EOD|NDT), not EOM, 'cause we can read past EW: ************/1868 if (status_eom_detected)
1869 /* If EOM, nothing left to read, so keep returning EOFs.1870 *** should probably set some flag to avoid clearing1871 *** status_eom_detected through ioctls or something1872 */1873 return 0;
1874 else{1875 /* just eof, there may be more files ahead... */1876 return_read_eof = NO;
1877 reported_read_eof = NO;
1878 status_eof_detected = NO; /* reset this too */1879 /*fall through*/1880 }1881 }1882 }1883
1884 /*****************************/1885 if (bytes_todo==0)
1886 returntotal_bytes_done;
1887
1888 if (bytes_todo>0) {1889 /* start reading data */1890 if (is_exception()) /****************************************/1891 tpqputs("is_exception() before start_dma()!");
1892 /******************************************************************1893 ***** if start_dma() fails because the head is positioned 0 bytes1894 ***** before the FM, (causing EXCEPTION to be set) return_read_eof should1895 ***** be set to YES, and we should return total_bytes_done, rather than -ENXIO.1896 ***** The app should recognize this as an EOF condition.1897 ***************************************************************************/1898 stat = start_dma(READ, bytes_todo);
1899 if (stat == TE_OK) {1900 /* Wait for transfer to complete, interrupt should wake us */1901 while (dma_mode != 0) {1902 sleep_on(&tape_qic02_transfer);
1903 }1904 if (status_error)
1905 return_read_eof = YES;
1906 }elseif (stat != TE_END) {1907 /* should do sense() on error here */1908 #if 0
1909 return -ENXIO;
1910 #else1911 printk("Trouble: stat==%02x\n", stat);
1912 return_read_eof = YES;
1913 /*************** check EOF/EOT handling!!!!!! **/1914 #endif1915 }1916 end_dma(&bytes_done);
1917 if (bytes_done>bytes_todo) {1918 tpqputs("read: Oops, read more bytes than requested");
1919 return -EIO;
1920 }1921 /* copy buffer to user-space in one go */1922 if (bytes_done>0)
1923 memcpy_tofs( (void *) buf, (void *) buffaddr, bytes_done);
1924 #if 1
1925 /* Checks Ton's patch below */1926 if ((return_read_eof == NO) && (status_eof_detected == YES)) {1927 printk(TPQIC_NAME ": read(): return_read_eof=%d, status_eof_detected=YES. return_read_eof:=YES\n", return_read_eof);
1928 }1929 #endif1930 if ((bytes_todo != bytes_done) || (status_eof_detected == YES))
1931 /* EOF or EOM detected. return EOF next time. */1932 return_read_eof = YES;
1933 }/* else: ignore read request for 0 bytes */1934
1935 if (bytes_done>0) {1936 status_bytes_rd = YES;
1937 buf += bytes_done;
1938 filp->f_pos += bytes_done;
1939 total_bytes_done += bytes_done;
1940 count -= bytes_done;
1941 }1942 }1943 tpqputs("read request for <0 bytes");
1944 return -EINVAL;
1945 }/* tape_qic02_read */1946
1947
1948
1949 /* The drive detects near-EOT by means of the holes in the tape.1950 * When the holes are detected, there is some space left. The drive1951 * reports this as a TP_EOM exception. After clearing the exception,1952 * the drive should accept two extra blocks.1953 *1954 * It seems there are some archiver programs that would like to use the1955 * extra space for writing a continuation marker. The driver should return1956 * end-of-file to the user program on writes, when the holes are detected.1957 * If the user-program wants to use the extra space, it should use the1958 * MTNOP ioctl() to get the generic status register and may then continue1959 * writing (max 1kB). ----------- doesn't work yet...............1960 *1961 * EOF behaviour on writes:1962 * If there is enough room, write all of the data.1963 * If there is insufficient room, write as much as will fit and1964 * return the amount written. If the requested amount differs from the1965 * written amount, the application program should recognize that as the1966 * end of file. Subsequent writes will return -ENOSPC.1967 * Unless the minor bits specify a rewind-on-close, the tape will not1968 * be rewound when it is full. The user-program should do that, if desired.1969 * If the driver were to do that automatically, a user-program could be 1970 * confused about the EOT/BOT condition after re-opening the tape device.1971 *1972 * Multiple volume support: Tar closes the tape device before prompting for1973 * the next tape. The user may then insert a new tape and tar will open the1974 * tape device again. The driver will detect an exception status in (No Cartridge)1975 * and force a rewind. After that tar may continue writing.1976 */1977 staticinttape_qic02_write(structinode * inode, structfile * filp, char * buf, intcount)
/* */1978 {1979 interror;
1980 dev_tdev = inode->i_rdev;
1981 unsignedshortflags = filp->f_flags;
1982 unsignedlongbytes_todo, bytes_done, total_bytes_done = 0;
1983
1984 if (TP_DIAGS(current_tape_dev))
1985 printk(TPQIC_NAME ": request WRITE, minor=%x, buf=%lx, count=%x, pos=%x, flags=%x\n",
1986 MINOR(dev), buf, count, filp->f_pos, flags);
1987
1988 if (count % TAPE_BLKSIZE) {/* only allow mod 512 bytes at a time */1989 tpqputs("Wrong block size");
1990 return -EINVAL;
1991 }1992
1993 if (mode_access==READ) {1994 tpqputs("Not in write mode");
1995 return -EACCES;
1996 }1997
1998 /* open() does a sense() and we can assume the tape isn't changed1999 * between open() and release(), so the tperror.exs bits will still2000 * be valid.2001 */2002 if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP)) {2003 tpqputs("Cartridge is write-protected.");
2004 return -EACCES; /* don't even try when write protected */2005 }2006
2007 /* Make sure buffer is safe to read from. */2008 error = verify_area(VERIFY_READ, buf, count);
2009 if (error) {2010 printk(TPQIC_NAME ": write: verify_area(READ, %lx, %x) failed\n", buf, count);
2011 returnerror;
2012 }2013
2014 if (doing_read == YES)
2015 terminate_read(0);
2016
2017 while (count>=0) {2018 /* see how much fits in the kernel buffer */2019 bytes_done = 0;
2020 bytes_todo = TPQBUF_SIZE;
2021 if (bytes_todo>count)
2022 bytes_todo = count;
2023
2024 if (return_write_eof == YES) {2025 /* return_write_eof should be reset on reverse tape movements. */2026
2027 if (reported_write_eof==NO) {2028 if (bytes_todo>0) {2029 tpqputs("partial write");
2030 /* partial write signals EOF to user program */2031 }2032 reported_write_eof = YES;
2033 returntotal_bytes_done;
2034 }else{2035 return -ENOSPC; /* return error */2036 }2037 }2038
2039 /* Quit when done. */2040 if (bytes_todo==0)
2041 returntotal_bytes_done;
2042
2043
2044 /* copy from user to DMA buffer and initiate transfer. */2045 if (bytes_todo>0) {2046 memcpy_fromfs( (void *) buffaddr, (void *) buf, bytes_todo);
2047
2048 /****************** similar problem with read() at FM could happen here at EOT.2049 ******************/2050
2051 /***** if at EOT, 0 bytes can be written. start_dma() will2052 ***** fail and write() will return ENXIO error2053 *****/2054 if (start_dma(WRITE, bytes_todo) != TE_OK) {2055 tpqputs("write: start_dma() failed");
2056 /* should do sense() on error here */2057 return -ENXIO; /*********** FIXTHIS **************/2058 }2059
2060 /* Wait for write to complete, interrupt should wake us. */2061 while ((status_error == 0) && (dma_mode != 0)) {2062 sleep_on(&tape_qic02_transfer);
2063 }2064
2065 end_dma(&bytes_done);
2066 if (bytes_done>bytes_todo) {2067 tpqputs("write: Oops, wrote more bytes than requested");
2068 return -EIO;
2069 }2070 /* If the dma-transfer was aborted because of an exception,2071 * status_error will have been set in the interrupt handler.2072 * Then end_dma() will do a sense().2073 * If the exception was EXC_EOM, the EW-hole was encountered2074 * and two more blocks could be written. For the time being we'll2075 * just consider this to be the EOT.2076 * Otherwise, something Bad happened, such as the maximum number2077 * of block-rewrites was exceeded. [e.g. A very bad spot on tape was2078 * encountered. Normally short dropouts are compensated for by2079 * rewriting the block in error, up to 16 times. I'm not sure2080 * QIC-24 drives can do this.]2081 */2082 if (status_error) {2083 if (status_eom_detected == YES) {2084 tpqputs("write: EW detected");
2085 return_write_eof = YES;
2086 }else{2087 /* probably EXC_RWA */2088 tpqputs("write: dma: error in writing");
2089 return -EIO;
2090 }2091 }2092 if (bytes_todo != bytes_done)
2093 /* EOF or EOM detected. return EOT next time. */2094 return_write_eof = YES;
2095 }2096 /* else: ignore write request for 0 bytes. */2097
2098 if (bytes_done>0) {2099 status_bytes_wr = YES;
2100 buf += bytes_done;
2101 filp->f_pos += bytes_done;
2102 total_bytes_done += bytes_done;
2103 count -= bytes_done;
2104 }2105 }2106 tpqputs("write request for <0 bytes");
2107 printk(TPQIC_NAME ": status_bytes_wr %x, buf %x, total_bytes_done %x, count %x\n", status_bytes_wr, buf, total_bytes_done, count);
2108 return -EINVAL;
2109 }/* tape_qic02_write */2110
2111
2112
2113 /* tape_qic02_open()2114 * We allow the device to be opened, even if it is marked 'dead' because2115 * we want to be able to reset the tape device without rebooting.2116 * Only one open tape file at a time, except when minor=255.2117 * Minor 255 is only allowed for resetting and always returns <0.2118 * 2119 * The density command is only allowed when TP_BOM is set. Thus, remember2120 * the most recently used minor bits. When they are different from the2121 * remembered values, rewind the tape and set the required density.2122 * Don't rewind if the minor bits specify density 0.2123 */2124 staticinttape_qic02_open(structinode * inode, structfile * filp)
/* */2125 {2126 dev_tdev = inode->i_rdev;
2127 unsignedshortflags = filp->f_flags;
2128 unsignedshortdens;
2129 ints;
2130
2131 status_open = NO;
2132
2133 if (TP_DIAGS(dev)) {2134 printk("tape_qic02_open: dev=%x, flags=%x ", dev, flags);
2135 }2136
2137 if (MINOR(dev)==255) /* special case for resetting */2138 if (suser())
2139 return (tape_reset(1)==TE_OK) ? -EAGAIN : -ENXIO;
2140 else2141 return -EPERM;
2142
2143 if (status_open==YES) {2144 return -EBUSY; /* only one at a time... */2145 }2146 status_open = YES;
2147
2148 status_bytes_rd = NO;
2149 status_bytes_wr = NO;
2150
2151 return_read_eof = NO; /********????????????????*****/2152 return_write_eof = (status_eot_detected)? YES : NO;
2153
2154 /* Clear this in case user app close()d before reading EOF token */2155 status_eof_detected = NO;
2156
2157 reported_read_eof = NO;
2158 reported_write_eof = NO;
2159
2160
2161 switch (flags & O_ACCMODE) {2162 caseO_RDONLY:
2163 mode_access = READ;
2164 break;
2165 caseO_WRONLY: /* Fallthru... Strictly speaking this is not correct... */2166 caseO_RDWR: /* reads are allowed as long as nothing is written */2167 mode_access = WRITE;
2168 break;
2169 }2170
2171
2172 /* This is to avoid tape-changed problems (TP_CNI exception). */2173 if (is_exception()) {2174 s = tp_sense(TP_WRP|TP_EOM|TP_BOM|TP_CNI|TP_EOR);
2175 if (s != TE_OK) {2176 status_open = NO;
2177 tpqputs("open: sense() failed after exception was detected");
2178 return -EIO;
2179 }2180 }2181
2182
2183 /* not allowed to do QCMD_DENS_* unless tape is rewound */2184 if ((TP_DENS(dev)!=0) && (TP_DENS(current_tape_dev) != TP_DENS(dev))) {2185 /* force rewind if minor bits have changed,2186 * i.e. user wants to use tape in different format.2187 * [assuming single drive operation]2188 */2189 tpqputs("Density minor bits have changed. Forcing rewind.");
2190 need_rewind = YES;
2191 }else{2192 /* density bits still the same, but TP_DIAGS bit 2193 * may have changed.2194 */2195 current_tape_dev = dev;
2196 }2197
2198 if (need_rewind == YES) {2199 s = do_qic_cmd(QCMD_REWIND, TIM_R);
2200 if (s != 0) {2201 tpqputs("open: rewind failed");
2202 status_open = NO;
2203 return -EIO;
2204 }2205 }2206
2207
2208 /* Note: After a reset command, the controller will rewind the tape2209 * just before performing any tape movement operation!2210 */2211 if (status_dead) {2212 tpqputs("open: tape dead, attempting reset");
2213 if (tape_reset(1)!=TE_OK) {2214 status_open = NO;
2215 return -ENXIO;
2216 }else{2217 status_dead = NO;
2218 if (tp_sense(~(TP_ST1|TP_ILL)) != TE_OK) {2219 tpqputs("open: tp_sense() failed\n");
2220 status_dead = YES; /* try reset next time */2221 status_open = NO;
2222 return -EIO;
2223 }2224 }2225 }2226
2227 /* things should be ok, once we get here */2228
2229
2230 /* set density: only allowed when TP_BOM status bit is set,2231 * so we must have done a rewind by now. If not, just skip over.2232 * Only give set density command when minor bits have changed.2233 */2234 if (TP_DENS(current_tape_dev) == TP_DENS(dev) )
2235 return 0;
2236
2237 current_tape_dev = dev;
2238 need_rewind = NO;
2239 dens = TP_DENS(dev);
2240 if (dens < sizeof(format_names)/sizeof(char *))
2241 printk(TPQIC_NAME ": format: %s%s\n", (dens!=0)? "QIC-" : "", format_names[dens]);
2242 else2243 tpqputs("Wait for retensioning...");
2244
2245 switch (TP_DENS(dev)) {2246 case 0: /* This one's for Eddy ;-) */2247 s = 0;
2248 break;
2249 case 1:
2250 s = do_qic_cmd(QCMD_DENS_11, TIM_S);
2251 break;
2252 case 2:
2253 s = do_qic_cmd(QCMD_DENS_24, TIM_S);
2254 break;
2255 case 3:
2256 s = do_qic_cmd(QCMD_DENS_120, TIM_S);
2257 break;
2258 case 4:
2259 s = do_qic_cmd(QCMD_DENS_150, TIM_S);
2260 break;
2261 case 5:
2262 s = do_qic_cmd(QCMD_DENS_300, TIM_S);
2263 break;
2264 case 6:
2265 s = do_qic_cmd(QCMD_DENS_600, TIM_S);
2266 break;
2267 default: /* otherwise do a retension before anything else */2268 s = do_qic_cmd(QCMD_RETEN, TIM_R);
2269 }2270 if (s != 0) {2271 status_open = NO; /* fail if fault occurred */2272 status_dead = YES; /* force reset */2273 current_tape_dev = 0xff80;
2274 return -EIO;
2275 }2276
2277 return 0;
2278 }/* tape_qic02_open */2279
2280
2281 staticinttape_qic02_readdir(structinode * inode, structfile * filp, structdirent * dp, intcount)
/* */2282 {2283 return -ENOTDIR; /* not supported */2284 }/* tape_qic02_readdir */2285
2286
2287 staticvoidtape_qic02_release(structinode * inode, structfile * filp)
/* */2288 {2289 dev_tdev = inode->i_rdev;
2290
2291 if (TP_DIAGS(dev))
2292 printk("tape_qic02_release: dev=%x\n", dev);
2293
2294 /* Terminate any pending write cycle. Terminating the read-cycle2295 * is delayed until it is required to do so for a new command.2296 */2297 terminate_write(-1);
2298
2299 if (status_dead==YES)
2300 tpqputs("release: device dead!?");
2301
2302 if (status_open==NO) {2303 tpqputs("release: device not open");
2304 return;
2305 }2306 /* Rewind only if minor number requires it AND 2307 * read/writes have been done.2308 */2309 if ((TP_REWCLOSE(dev)) && (status_bytes_rd | status_bytes_wr)) {2310 tpqputs("release: Doing rewind...");
2311 (void) do_qic_cmd(QCMD_REWIND, TIM_R);
2312 }2313
2314 status_open = NO;
2315 return;
2316 }/* tape_qic02_release */2317
2318
2319
2320 /* ioctl allows user programs to rewind the tape and stuff like that */2321 staticinttape_qic02_ioctl(structinode * inode, structfile * filp,
/* */2322 unsignedintiocmd, unsignedlongioarg)
2323 {2324 interror;
2325 shorti;
2326 intdev_maj = MAJOR(inode->i_rdev);
2327 intc;
2328 structmtopoperation;
2329 char *stp, *argp;
2330
2331 #ifdefTP_HAVE_TELL2332 unsignedcharblk_addr[6];
2333 structmtposioctl_tell;
2334 #endif2335
2336 if (TP_DIAGS(current_tape_dev))
2337 printk(TPQIC_NAME ": ioctl(%4x, %4x, %4x)\n", dev_maj, iocmd, ioarg);
2338
2339 if (!inode || !ioarg)
2340 return -EINVAL;
2341
2342 /* check iocmd first */2343
2344 if (dev_maj != TAPE_QIC02_MAJOR) {2345 printk(TPQIC_NAME ": Oops! Wrong device?\n");
2346 /* A panic() would be appropriate here */2347 return -ENODEV;
2348 }2349
2350 c = iocmd & IOCCMD_MASK;
2351 if (c == (MTIOCTOP & IOCCMD_MASK)) {2352
2353 /* Compare expected struct size and actual struct size. This2354 * is useful to catch programs compiled with old #includes.2355 */2356 if (((iocmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(structmtop)) {2357 tpqputs("sizeof(struct mtop) does not match!");
2358 return -EFAULT;
2359 }2360 error = verify_area(VERIFY_READ, (char *) ioarg, sizeof(operation));
2361 if (error)
2362 returnerror;
2363
2364 /* copy mtop struct from user space to kernel space */2365 stp = (char *) &operation;
2366 argp = (char *) ioarg;
2367 for (i=0; i<sizeof(operation); i++)
2368 *stp++ = get_fs_byte(argp++);
2369
2370 /* ---note: mt_count is signed, negative seeks must be2371 * --- translated to seeks in opposite direction!2372 * (only needed for Sun-programs, I think.)2373 */2374 /* ---note: MTFSF with count 0 should position the2375 * --- tape at the beginning of the current file.2376 */2377
2378 if (TP_DIAGS(current_tape_dev))
2379 printk("OP op=%4x, count=%4x\n", operation.mt_op, operation.mt_count);
2380
2381 if (operation.mt_count < 0)
2382 tpqputs("Warning: negative mt_count ignored");
2383
2384 ioctl_status.mt_resid = operation.mt_count;
2385 if (operation.mt_op == MTSEEK) {2386 seek_addr_buf[0] = (operation.mt_count>>16)&0xff;
2387 seek_addr_buf[1] = (operation.mt_count>>8)&0xff;
2388 seek_addr_buf[2] = (operation.mt_count)&0xff;
2389 if (operation.mt_count>>24)
2390 return -EINVAL;
2391
2392 if ((error = do_ioctl_cmd(operation.mt_op)) != 0)
2393 returnerror;
2394 ioctl_status.mt_resid = 0;
2395 }else{2396 while (operation.mt_count > 0) {2397 operation.mt_count--;
2398 if ((error = do_ioctl_cmd(operation.mt_op)) != 0)
2399 returnerror;
2400 ioctl_status.mt_resid = operation.mt_count;
2401 }2402 }2403 return 0;
2404
2405 }elseif (c == (MTIOCGET & IOCCMD_MASK)) {2406 if (TP_DIAGS(current_tape_dev))
2407 printk("GET ");
2408
2409 /* compare expected struct size and actual struct size */2410 if (((iocmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(structmtget)) {2411 tpqputs("sizeof(struct mtget) does not match!");
2412 return -EFAULT;
2413 }2414
2415 /* check for valid user address */2416 error = verify_area(VERIFY_WRITE, (void *) ioarg, sizeof(ioctl_status));
2417 if (error)
2418 returnerror;
2419
2420 /* It appears (gmt(1)) that it is normal behaviour to2421 * first set the status with MTNOP, and then to read2422 * it out with MTIOCGET2423 */2424
2425 /* copy results to user space */2426 stp = (char *) &ioctl_status;
2427 argp = (char *) ioarg;
2428 for (i=0; i<sizeof(ioctl_status); i++)
2429 put_fs_byte(*stp++, argp++);
2430 return 0;
2431
2432 #ifdefTP_HAVE_TELL2433 }elseif (c == (MTIOCPOS & IOCCMD_MASK)) {2434 if (TP_DIAGS(current_tape_dev))
2435 printk("POS ");
2436
2437 /* compare expected struct size and actual struct size */2438 if (((iocmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(structmtpos)) {2439 tpqputs("sizeof(struct mtpos) does not match!");
2440 return -EFAULT;
2441 }2442
2443 /* check for valid user address */2444 error = verify_area(VERIFY_WRITE, (void *) ioarg, sizeof(ioctl_tell));
2445 if (error)
2446 returnerror;
2447
2448 tpqputs("MTTELL reading block address");
2449 if ((doing_read==YES) || (doing_write==YES))
2450 finish_rw(QCMDV_TELL_BLK);
2451
2452 c = rdstatus((char *) blk_addr, sizeof(blk_addr), QCMDV_TELL_BLK);
2453 if (c!=TE_OK)
2454 return -EIO;
2455
2456 ioctl_tell.mt_blkno = (blk_addr[3] << 16) | (blk_addr[4] << 8) | blk_addr[5];
2457
2458 /* copy results to user space */2459 stp = (char *) &ioctl_tell;
2460 argp = (char *) ioarg;
2461 for (i=0; i<sizeof(ioctl_tell); i++)
2462 put_fs_byte(*stp++, argp++);
2463 return 0;
2464 #endif2465 }else2466 return -ENOTTY; /* Other cmds not supported. */2467 }/* tape_qic02_ioctl */2468
2469
2470
2471 /* These are (most) of the interface functions: */2472 staticstructfile_operationstape_qic02_fops = {2473 tape_qic02_lseek, /* not allowed */2474 tape_qic02_read, /* read */2475 tape_qic02_write, /* write */2476 tape_qic02_readdir, /* not allowed */2477 NULL, /* select ??? */2478 tape_qic02_ioctl, /* ioctl */2479 NULL, /* mmap not allowed */2480 tape_qic02_open, /* open */2481 tape_qic02_release, /* release */2482 NULL/* fsync */2483 };
2484
2485
2486 /* Attribute `SA_INTERRUPT' makes the interrupt atomic with2487 * interrupts disabled. We could do without the atomic stuff, but2488 * then dma_transfer() would have to disable interrupts explicitly.2489 * System load is high enough as it is :-(2490 */2491 staticstructsigactiontape_qic02_sigaction = {2492 tape_qic02_interrupt,
2493 0,
2494 SA_INTERRUPT,
2495 NULL2496 };
2497
2498
2499 /* align `a' at `size' bytes. `size' must be a power of 2 */2500 staticinlineunsignedlongconstalign_buffer(unsignedlonga, unsignedsize)
/* */2501 {2502 if (a & (size-1)) /* if not aligned */2503 return (a | (size-1)) + 1;
2504 else/* else is aligned */2505 returna;
2506 }2507
2508
2509 /* init() is called from chr_dev_init() in kernel/chr_drv/mem.c */2510 longtape_qic02_init(longkmem_start)
/* */2511 /* Shouldn't this be a caddr_t ? */2512 {2513
2514 printk(TPQIC_NAME ": IRQ %d, DMA %d, IO %xh, IFC %s, %s, %s\n",
2515 TAPE_QIC02_IRQ, TAPE_QIC02_DMA, TAPE_QIC02_PORT,
2516 #ifTAPE_QIC02_IFC == WANGTEK2517 "Wangtek",
2518 #elifTAPE_QIC02_IFC == ARCHIVE2519 "Archive",
2520 #else2521 # error2522 #endif2523 rcs_revision, rcs_date);
2524
2525 /* First perform some checks. If one of them fails,2526 * the tape driver will not be registered to the system.2527 */2528
2529 /* Should do IRQ/DMA allocation in open(). Use free_irq() in release()2530 * return -EBUSY, if allocation fails in open().2531 * Make IRQ settable/readable through ioctls. DMA is trickier because2532 * some bits change for different DMA numbers. Also, this would add 2533 * runtime overhead for having the dma channel number be a variable2534 * rather than a constant. Probably need to make the DMA stuff #ifdef'd2535 * to choose between hardcoded and changeable DMA channel.2536 *2537 * Also, Linux needs a more generic way to set DMA/IRQ and other stuff.2538 * Right now, this is done differently for every device. (setserial,2539 * ctrlaltdel, setdfprm, setfdthr, tunelp, ((setterm))...)2540 *2541 * #include <hint.h>2542 */2543
2544 /* get IRQ */2545 if (irqaction(TAPE_QIC02_IRQ, &tape_qic02_sigaction)) {2546 printk(TPQIC_NAME ": can't allocate IRQ%d for QIC-02 tape\n",
2547 TAPE_QIC02_IRQ);
2548 returnkmem_start;
2549 }2550
2551 /* After IRQ, allocate DMA channel */2552 if (request_dma(TAPE_QIC02_DMA)) {2553 printk(TPQIC_NAME ": can't allocate DMA%d for QIC-02 tape\n",
2554 TAPE_QIC02_DMA);
2555 free_irq(TAPE_QIC02_IRQ);
2556 returnkmem_start;
2557 }2558
2559 if (TPSTATSIZE != 6) {2560 printk(TPQIC_NAME ": internal error: tpstatus struct incorrect!\n");
2561 returnkmem_start;
2562 }2563 if ((TPQBUF_SIZE<512) || (TPQBUF_SIZE>=0x10000)) {2564 printk(TPQIC_NAME ": internal error: DMA buffer size out of range\n");
2565 returnkmem_start;
2566 }2567
2568 printk(TPQIC_NAME ": DMA buffers: %u blocks", NR_BLK_BUF);
2569
2570 /* Setup the page-address for the dma transfer.2571 * This assumes a one-to-one identity mapping between2572 * kernel addresses and physical memory.2573 */2574 buffaddr = align_buffer((unsignedlong) &tape_qic02_buf, TAPE_BLKSIZE);
2575 printk(", at address 0x%lx (0x%lx)\n", buffaddr, (unsignedlong) &tape_qic02_buf);
2576
2577 #ifndefCONFIG_MAX_16M2578 if (buffaddr+TPQBUF_SIZE>=0x1000000) {2579 printk(TPQIC_NAME ": DMA buffer *must* be in lower 16MB\n");
2580 returnkmem_start;
2581 }2582 #endif2583
2584 /* If we got this far, install driver functions */2585 if (register_chrdev(TAPE_QIC02_MAJOR, TPQIC_NAME, &tape_qic02_fops)) {2586 printk(TPQIC_NAME ": Unable to get chrdev major %d\n", TAPE_QIC02_MAJOR);
2587 returnkmem_start;
2588 }2589
2590 /* prepare timer */2591 TIMEROFF;
2592 timer_table[TAPE_QIC02_TIMER].expires = 0;
2593 timer_table[TAPE_QIC02_TIMER].fn = tape_qic02_times_out;
2594
2595 if (tape_reset(0)!=TE_OK || tp_sense(TP_WRP|TP_POR|TP_CNI)!=TE_OK) {2596 status_dead = YES;
2597 }else{2598 if (is_exception()) {2599 tpqputs("exception detected\n");
2600 (void) tp_sense(TP_WRP|TP_POR|TP_CNI);
2601 }2602 }2603
2604 /* initialize generic status for ioctl requests */2605
2606 ioctl_status.mt_type = TAPE_QIC02_DRIVE; /* MT_IS* id nr */2607
2608 ioctl_status.mt_resid = 0; /* ---residual count */2609 ioctl_status.mt_gstat = 0; /* ---generic status */2610 ioctl_status.mt_erreg = 0; /* not used */2611 ioctl_status.mt_fileno = 0; /* number of current file on tape */2612 ioctl_status.mt_blkno = 0; /* number of current (logical) block */2613
2614 returnkmem_start;
2615 }/* tape_qic02_init */2616
2617
2618 #endif/* CONFIG_TAPE_QIC02 */