Linux 2.6.17.7
[linux/fpc-iii.git] / drivers / s390 / char / tape_std.c
blob99cf881f41db8b3f995c5199e8440bb18f6ab711
1 /*
2 * drivers/s390/char/tape_std.c
3 * standard tape device functions for ibm tapes.
5 * S390 and zSeries version
6 * Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Author(s): Carsten Otte <cotte@de.ibm.com>
8 * Michael Holzheu <holzheu@de.ibm.com>
9 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
10 * Martin Schwidefsky <schwidefsky@de.ibm.com>
11 * Stefan Bader <shbader@de.ibm.com>
14 #include <linux/config.h>
15 #include <linux/stddef.h>
16 #include <linux/kernel.h>
17 #include <linux/bio.h>
18 #include <linux/timer.h>
20 #include <asm/types.h>
21 #include <asm/idals.h>
22 #include <asm/ebcdic.h>
23 #include <asm/tape390.h>
25 #define TAPE_DBF_AREA tape_core_dbf
27 #include "tape.h"
28 #include "tape_std.h"
30 #define PRINTK_HEADER "TAPE_STD: "
33 * tape_std_assign
35 static void
36 tape_std_assign_timeout(unsigned long data)
38 struct tape_request * request;
39 struct tape_device * device;
40 int rc;
42 request = (struct tape_request *) data;
43 if ((device = request->device) == NULL)
44 BUG();
46 DBF_EVENT(3, "%08x: Assignment timeout. Device busy.\n",
47 device->cdev_id);
48 rc = tape_cancel_io(device, request);
49 if(rc)
50 PRINT_ERR("(%s): Assign timeout: Cancel failed with rc = %i\n",
51 device->cdev->dev.bus_id, rc);
55 int
56 tape_std_assign(struct tape_device *device)
58 int rc;
59 struct timer_list timeout;
60 struct tape_request *request;
62 request = tape_alloc_request(2, 11);
63 if (IS_ERR(request))
64 return PTR_ERR(request);
66 request->op = TO_ASSIGN;
67 tape_ccw_cc(request->cpaddr, ASSIGN, 11, request->cpdata);
68 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
71 * The assign command sometimes blocks if the device is assigned
72 * to another host (actually this shouldn't happen but it does).
73 * So we set up a timeout for this call.
75 init_timer(&timeout);
76 timeout.function = tape_std_assign_timeout;
77 timeout.data = (unsigned long) request;
78 timeout.expires = jiffies + 2 * HZ;
79 add_timer(&timeout);
81 rc = tape_do_io_interruptible(device, request);
83 del_timer(&timeout);
85 if (rc != 0) {
86 PRINT_WARN("%s: assign failed - device might be busy\n",
87 device->cdev->dev.bus_id);
88 DBF_EVENT(3, "%08x: assign failed - device might be busy\n",
89 device->cdev_id);
90 } else {
91 DBF_EVENT(3, "%08x: Tape assigned\n", device->cdev_id);
93 tape_free_request(request);
94 return rc;
98 * tape_std_unassign
101 tape_std_unassign (struct tape_device *device)
103 int rc;
104 struct tape_request *request;
106 if (device->tape_state == TS_NOT_OPER) {
107 DBF_EVENT(3, "(%08x): Can't unassign device\n",
108 device->cdev_id);
109 PRINT_WARN("(%s): Can't unassign device - device gone\n",
110 device->cdev->dev.bus_id);
111 return -EIO;
114 request = tape_alloc_request(2, 11);
115 if (IS_ERR(request))
116 return PTR_ERR(request);
118 request->op = TO_UNASSIGN;
119 tape_ccw_cc(request->cpaddr, UNASSIGN, 11, request->cpdata);
120 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
122 if ((rc = tape_do_io(device, request)) != 0) {
123 DBF_EVENT(3, "%08x: Unassign failed\n", device->cdev_id);
124 PRINT_WARN("%s: Unassign failed\n", device->cdev->dev.bus_id);
125 } else {
126 DBF_EVENT(3, "%08x: Tape unassigned\n", device->cdev_id);
128 tape_free_request(request);
129 return rc;
133 * TAPE390_DISPLAY: Show a string on the tape display.
136 tape_std_display(struct tape_device *device, struct display_struct *disp)
138 struct tape_request *request;
139 int rc;
141 request = tape_alloc_request(2, 17);
142 if (IS_ERR(request)) {
143 DBF_EVENT(3, "TAPE: load display failed\n");
144 return PTR_ERR(request);
146 request->op = TO_DIS;
148 *(unsigned char *) request->cpdata = disp->cntrl;
149 DBF_EVENT(5, "TAPE: display cntrl=%04x\n", disp->cntrl);
150 memcpy(((unsigned char *) request->cpdata) + 1, disp->message1, 8);
151 memcpy(((unsigned char *) request->cpdata) + 9, disp->message2, 8);
152 ASCEBC(((unsigned char*) request->cpdata) + 1, 16);
154 tape_ccw_cc(request->cpaddr, LOAD_DISPLAY, 17, request->cpdata);
155 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
157 rc = tape_do_io_interruptible(device, request);
158 tape_free_request(request);
159 return rc;
163 * Read block id.
166 tape_std_read_block_id(struct tape_device *device, __u64 *id)
168 struct tape_request *request;
169 int rc;
171 request = tape_alloc_request(3, 8);
172 if (IS_ERR(request))
173 return PTR_ERR(request);
174 request->op = TO_RBI;
175 /* setup ccws */
176 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
177 tape_ccw_cc(request->cpaddr + 1, READ_BLOCK_ID, 8, request->cpdata);
178 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
179 /* execute it */
180 rc = tape_do_io(device, request);
181 if (rc == 0)
182 /* Get result from read buffer. */
183 *id = *(__u64 *) request->cpdata;
184 tape_free_request(request);
185 return rc;
189 tape_std_terminate_write(struct tape_device *device)
191 int rc;
193 if(device->required_tapemarks == 0)
194 return 0;
196 DBF_LH(5, "tape%d: terminate write %dxEOF\n", device->first_minor,
197 device->required_tapemarks);
199 rc = tape_mtop(device, MTWEOF, device->required_tapemarks);
200 if (rc)
201 return rc;
203 device->required_tapemarks = 0;
204 return tape_mtop(device, MTBSR, 1);
208 * MTLOAD: Loads the tape.
209 * The default implementation just wait until the tape medium state changes
210 * to MS_LOADED.
213 tape_std_mtload(struct tape_device *device, int count)
215 return wait_event_interruptible(device->state_change_wq,
216 (device->medium_state == MS_LOADED));
220 * MTSETBLK: Set block size.
223 tape_std_mtsetblk(struct tape_device *device, int count)
225 struct idal_buffer *new;
227 DBF_LH(6, "tape_std_mtsetblk(%d)\n", count);
228 if (count <= 0) {
230 * Just set block_size to 0. tapechar_read/tapechar_write
231 * will realloc the idal buffer if a bigger one than the
232 * current is needed.
234 device->char_data.block_size = 0;
235 return 0;
237 if (device->char_data.idal_buf != NULL &&
238 device->char_data.idal_buf->size == count)
239 /* We already have a idal buffer of that size. */
240 return 0;
242 if (count > MAX_BLOCKSIZE) {
243 DBF_EVENT(3, "Invalid block size (%d > %d) given.\n",
244 count, MAX_BLOCKSIZE);
245 PRINT_ERR("Invalid block size (%d > %d) given.\n",
246 count, MAX_BLOCKSIZE);
247 return -EINVAL;
250 /* Allocate a new idal buffer. */
251 new = idal_buffer_alloc(count, 0);
252 if (new == NULL)
253 return -ENOMEM;
254 if (device->char_data.idal_buf != NULL)
255 idal_buffer_free(device->char_data.idal_buf);
256 device->char_data.idal_buf = new;
257 device->char_data.block_size = count;
259 DBF_LH(6, "new blocksize is %d\n", device->char_data.block_size);
261 return 0;
265 * MTRESET: Set block size to 0.
268 tape_std_mtreset(struct tape_device *device, int count)
270 DBF_EVENT(6, "TCHAR:devreset:\n");
271 device->char_data.block_size = 0;
272 return 0;
276 * MTFSF: Forward space over 'count' file marks. The tape is positioned
277 * at the EOT (End of Tape) side of the file mark.
280 tape_std_mtfsf(struct tape_device *device, int mt_count)
282 struct tape_request *request;
283 struct ccw1 *ccw;
285 request = tape_alloc_request(mt_count + 2, 0);
286 if (IS_ERR(request))
287 return PTR_ERR(request);
288 request->op = TO_FSF;
289 /* setup ccws */
290 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
291 device->modeset_byte);
292 ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
293 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
295 /* execute it */
296 return tape_do_io_free(device, request);
300 * MTFSR: Forward space over 'count' tape blocks (blocksize is set
301 * via MTSETBLK.
304 tape_std_mtfsr(struct tape_device *device, int mt_count)
306 struct tape_request *request;
307 struct ccw1 *ccw;
308 int rc;
310 request = tape_alloc_request(mt_count + 2, 0);
311 if (IS_ERR(request))
312 return PTR_ERR(request);
313 request->op = TO_FSB;
314 /* setup ccws */
315 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
316 device->modeset_byte);
317 ccw = tape_ccw_repeat(ccw, FORSPACEBLOCK, mt_count);
318 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
320 /* execute it */
321 rc = tape_do_io(device, request);
322 if (rc == 0 && request->rescnt > 0) {
323 DBF_LH(3, "FSR over tapemark\n");
324 rc = 1;
326 tape_free_request(request);
328 return rc;
332 * MTBSR: Backward space over 'count' tape blocks.
333 * (blocksize is set via MTSETBLK.
336 tape_std_mtbsr(struct tape_device *device, int mt_count)
338 struct tape_request *request;
339 struct ccw1 *ccw;
340 int rc;
342 request = tape_alloc_request(mt_count + 2, 0);
343 if (IS_ERR(request))
344 return PTR_ERR(request);
345 request->op = TO_BSB;
346 /* setup ccws */
347 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
348 device->modeset_byte);
349 ccw = tape_ccw_repeat(ccw, BACKSPACEBLOCK, mt_count);
350 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
352 /* execute it */
353 rc = tape_do_io(device, request);
354 if (rc == 0 && request->rescnt > 0) {
355 DBF_LH(3, "BSR over tapemark\n");
356 rc = 1;
358 tape_free_request(request);
360 return rc;
364 * MTWEOF: Write 'count' file marks at the current position.
367 tape_std_mtweof(struct tape_device *device, int mt_count)
369 struct tape_request *request;
370 struct ccw1 *ccw;
372 request = tape_alloc_request(mt_count + 2, 0);
373 if (IS_ERR(request))
374 return PTR_ERR(request);
375 request->op = TO_WTM;
376 /* setup ccws */
377 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
378 device->modeset_byte);
379 ccw = tape_ccw_repeat(ccw, WRITETAPEMARK, mt_count);
380 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
382 /* execute it */
383 return tape_do_io_free(device, request);
387 * MTBSFM: Backward space over 'count' file marks.
388 * The tape is positioned at the BOT (Begin Of Tape) side of the
389 * last skipped file mark.
392 tape_std_mtbsfm(struct tape_device *device, int mt_count)
394 struct tape_request *request;
395 struct ccw1 *ccw;
397 request = tape_alloc_request(mt_count + 2, 0);
398 if (IS_ERR(request))
399 return PTR_ERR(request);
400 request->op = TO_BSF;
401 /* setup ccws */
402 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
403 device->modeset_byte);
404 ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count);
405 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
407 /* execute it */
408 return tape_do_io_free(device, request);
412 * MTBSF: Backward space over 'count' file marks. The tape is positioned at
413 * the EOT (End of Tape) side of the last skipped file mark.
416 tape_std_mtbsf(struct tape_device *device, int mt_count)
418 struct tape_request *request;
419 struct ccw1 *ccw;
420 int rc;
422 request = tape_alloc_request(mt_count + 2, 0);
423 if (IS_ERR(request))
424 return PTR_ERR(request);
425 request->op = TO_BSF;
426 /* setup ccws */
427 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
428 device->modeset_byte);
429 ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count);
430 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
431 /* execute it */
432 rc = tape_do_io_free(device, request);
433 if (rc == 0) {
434 rc = tape_mtop(device, MTFSR, 1);
435 if (rc > 0)
436 rc = 0;
438 return rc;
442 * MTFSFM: Forward space over 'count' file marks.
443 * The tape is positioned at the BOT (Begin Of Tape) side
444 * of the last skipped file mark.
447 tape_std_mtfsfm(struct tape_device *device, int mt_count)
449 struct tape_request *request;
450 struct ccw1 *ccw;
451 int rc;
453 request = tape_alloc_request(mt_count + 2, 0);
454 if (IS_ERR(request))
455 return PTR_ERR(request);
456 request->op = TO_FSF;
457 /* setup ccws */
458 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
459 device->modeset_byte);
460 ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
461 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
462 /* execute it */
463 rc = tape_do_io_free(device, request);
464 if (rc == 0) {
465 rc = tape_mtop(device, MTBSR, 1);
466 if (rc > 0)
467 rc = 0;
470 return rc;
474 * MTREW: Rewind the tape.
477 tape_std_mtrew(struct tape_device *device, int mt_count)
479 struct tape_request *request;
481 request = tape_alloc_request(3, 0);
482 if (IS_ERR(request))
483 return PTR_ERR(request);
484 request->op = TO_REW;
485 /* setup ccws */
486 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
487 device->modeset_byte);
488 tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
489 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
491 /* execute it */
492 return tape_do_io_free(device, request);
496 * MTOFFL: Rewind the tape and put the drive off-line.
497 * Implement 'rewind unload'
500 tape_std_mtoffl(struct tape_device *device, int mt_count)
502 struct tape_request *request;
504 request = tape_alloc_request(3, 0);
505 if (IS_ERR(request))
506 return PTR_ERR(request);
507 request->op = TO_RUN;
508 /* setup ccws */
509 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
510 tape_ccw_cc(request->cpaddr + 1, REWIND_UNLOAD, 0, NULL);
511 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
513 /* execute it */
514 return tape_do_io_free(device, request);
518 * MTNOP: 'No operation'.
521 tape_std_mtnop(struct tape_device *device, int mt_count)
523 struct tape_request *request;
525 request = tape_alloc_request(2, 0);
526 if (IS_ERR(request))
527 return PTR_ERR(request);
528 request->op = TO_NOP;
529 /* setup ccws */
530 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
531 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
532 /* execute it */
533 return tape_do_io_free(device, request);
537 * MTEOM: positions at the end of the portion of the tape already used
538 * for recordind data. MTEOM positions after the last file mark, ready for
539 * appending another file.
542 tape_std_mteom(struct tape_device *device, int mt_count)
544 int rc;
547 * Seek from the beginning of tape (rewind).
549 if ((rc = tape_mtop(device, MTREW, 1)) < 0)
550 return rc;
553 * The logical end of volume is given by two sewuential tapemarks.
554 * Look for this by skipping to the next file (over one tapemark)
555 * and then test for another one (fsr returns 1 if a tapemark was
556 * encountered).
558 do {
559 if ((rc = tape_mtop(device, MTFSF, 1)) < 0)
560 return rc;
561 if ((rc = tape_mtop(device, MTFSR, 1)) < 0)
562 return rc;
563 } while (rc == 0);
565 return tape_mtop(device, MTBSR, 1);
569 * MTRETEN: Retension the tape, i.e. forward space to end of tape and rewind.
572 tape_std_mtreten(struct tape_device *device, int mt_count)
574 struct tape_request *request;
575 int rc;
577 request = tape_alloc_request(4, 0);
578 if (IS_ERR(request))
579 return PTR_ERR(request);
580 request->op = TO_FSF;
581 /* setup ccws */
582 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
583 tape_ccw_cc(request->cpaddr + 1,FORSPACEFILE, 0, NULL);
584 tape_ccw_cc(request->cpaddr + 2, NOP, 0, NULL);
585 tape_ccw_end(request->cpaddr + 3, CCW_CMD_TIC, 0, request->cpaddr);
586 /* execute it, MTRETEN rc gets ignored */
587 rc = tape_do_io_interruptible(device, request);
588 tape_free_request(request);
589 return tape_mtop(device, MTREW, 1);
593 * MTERASE: erases the tape.
596 tape_std_mterase(struct tape_device *device, int mt_count)
598 struct tape_request *request;
600 request = tape_alloc_request(6, 0);
601 if (IS_ERR(request))
602 return PTR_ERR(request);
603 request->op = TO_DSE;
604 /* setup ccws */
605 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
606 tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
607 tape_ccw_cc(request->cpaddr + 2, ERASE_GAP, 0, NULL);
608 tape_ccw_cc(request->cpaddr + 3, DATA_SEC_ERASE, 0, NULL);
609 tape_ccw_cc(request->cpaddr + 4, REWIND, 0, NULL);
610 tape_ccw_end(request->cpaddr + 5, NOP, 0, NULL);
612 /* execute it */
613 return tape_do_io_free(device, request);
617 * MTUNLOAD: Rewind the tape and unload it.
620 tape_std_mtunload(struct tape_device *device, int mt_count)
622 return tape_mtop(device, MTOFFL, mt_count);
626 * MTCOMPRESSION: used to enable compression.
627 * Sets the IDRC on/off.
630 tape_std_mtcompression(struct tape_device *device, int mt_count)
632 struct tape_request *request;
634 if (mt_count < 0 || mt_count > 1) {
635 DBF_EXCEPTION(6, "xcom parm\n");
636 if (*device->modeset_byte & 0x08)
637 PRINT_INFO("(%s) Compression is currently on\n",
638 device->cdev->dev.bus_id);
639 else
640 PRINT_INFO("(%s) Compression is currently off\n",
641 device->cdev->dev.bus_id);
642 PRINT_INFO("Use 1 to switch compression on, 0 to "
643 "switch it off\n");
644 return -EINVAL;
646 request = tape_alloc_request(2, 0);
647 if (IS_ERR(request))
648 return PTR_ERR(request);
649 request->op = TO_NOP;
650 /* setup ccws */
651 *device->modeset_byte = (mt_count == 0) ? 0x00 : 0x08;
652 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
653 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
654 /* execute it */
655 return tape_do_io_free(device, request);
659 * Read Block
661 struct tape_request *
662 tape_std_read_block(struct tape_device *device, size_t count)
664 struct tape_request *request;
667 * We have to alloc 4 ccws in order to be able to transform request
668 * into a read backward request in error case.
670 request = tape_alloc_request(4, 0);
671 if (IS_ERR(request)) {
672 DBF_EXCEPTION(6, "xrbl fail");
673 return request;
675 request->op = TO_RFO;
676 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
677 tape_ccw_end_idal(request->cpaddr + 1, READ_FORWARD,
678 device->char_data.idal_buf);
679 DBF_EVENT(6, "xrbl ccwg\n");
680 return request;
684 * Read Block backward transformation function.
686 void
687 tape_std_read_backward(struct tape_device *device, struct tape_request *request)
690 * We have allocated 4 ccws in tape_std_read, so we can now
691 * transform the request to a read backward, followed by a
692 * forward space block.
694 request->op = TO_RBA;
695 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
696 tape_ccw_cc_idal(request->cpaddr + 1, READ_BACKWARD,
697 device->char_data.idal_buf);
698 tape_ccw_cc(request->cpaddr + 2, FORSPACEBLOCK, 0, NULL);
699 tape_ccw_end(request->cpaddr + 3, NOP, 0, NULL);
700 DBF_EVENT(6, "xrop ccwg");}
703 * Write Block
705 struct tape_request *
706 tape_std_write_block(struct tape_device *device, size_t count)
708 struct tape_request *request;
710 request = tape_alloc_request(2, 0);
711 if (IS_ERR(request)) {
712 DBF_EXCEPTION(6, "xwbl fail\n");
713 return request;
715 request->op = TO_WRI;
716 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
717 tape_ccw_end_idal(request->cpaddr + 1, WRITE_CMD,
718 device->char_data.idal_buf);
719 DBF_EVENT(6, "xwbl ccwg\n");
720 return request;
724 * This routine is called by frontend after an ENOSP on write
726 void
727 tape_std_process_eov(struct tape_device *device)
730 * End of volume: We have to backspace the last written record, then
731 * we TRY to write a tapemark and then backspace over the written TM
733 if (tape_mtop(device, MTBSR, 1) == 0 &&
734 tape_mtop(device, MTWEOF, 1) == 0) {
735 tape_mtop(device, MTBSR, 1);
739 EXPORT_SYMBOL(tape_std_assign);
740 EXPORT_SYMBOL(tape_std_unassign);
741 EXPORT_SYMBOL(tape_std_display);
742 EXPORT_SYMBOL(tape_std_read_block_id);
743 EXPORT_SYMBOL(tape_std_mtload);
744 EXPORT_SYMBOL(tape_std_mtsetblk);
745 EXPORT_SYMBOL(tape_std_mtreset);
746 EXPORT_SYMBOL(tape_std_mtfsf);
747 EXPORT_SYMBOL(tape_std_mtfsr);
748 EXPORT_SYMBOL(tape_std_mtbsr);
749 EXPORT_SYMBOL(tape_std_mtweof);
750 EXPORT_SYMBOL(tape_std_mtbsfm);
751 EXPORT_SYMBOL(tape_std_mtbsf);
752 EXPORT_SYMBOL(tape_std_mtfsfm);
753 EXPORT_SYMBOL(tape_std_mtrew);
754 EXPORT_SYMBOL(tape_std_mtoffl);
755 EXPORT_SYMBOL(tape_std_mtnop);
756 EXPORT_SYMBOL(tape_std_mteom);
757 EXPORT_SYMBOL(tape_std_mtreten);
758 EXPORT_SYMBOL(tape_std_mterase);
759 EXPORT_SYMBOL(tape_std_mtunload);
760 EXPORT_SYMBOL(tape_std_mtcompression);
761 EXPORT_SYMBOL(tape_std_read_block);
762 EXPORT_SYMBOL(tape_std_read_backward);
763 EXPORT_SYMBOL(tape_std_write_block);
764 EXPORT_SYMBOL(tape_std_process_eov);