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