1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * standard tape device functions for ibm tapes.
4 *
5 * S390 and zSeries version
6 * Copyright IBM Corp. 2001, 2002
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>
12 */
13
14 #define pr_fmt(fmt) "tape: " fmt
15
16 #include <linux/export.h>
17 #include <linux/stddef.h>
18 #include <linux/kernel.h>
19 #include <linux/bio.h>
20 #include <linux/timer.h>
21
22 #include <asm/types.h>
23 #include <asm/idals.h>
24 #include <asm/ebcdic.h>
25
26 #define TAPE_DBF_AREA tape_core_dbf
27
28 #include "tape.h"
29 #include "tape_std.h"
30
31 /*
32 * tape_std_assign
33 */
34 static void
tape_std_assign_timeout(struct timer_list * t)35 tape_std_assign_timeout(struct timer_list *t)
36 {
37 struct tape_request * request = timer_container_of(request, t,
38 timer);
39 struct tape_device * device = request->device;
40 int rc;
41
42 BUG_ON(!device);
43
44 DBF_EVENT(3, "%08x: Assignment timeout. Device busy.\n",
45 device->cdev_id);
46 rc = tape_cancel_io(device, request);
47 if(rc)
48 DBF_EVENT(3, "(%08x): Assign timeout: Cancel failed with rc = "
49 "%i\n", device->cdev_id, rc);
50 }
51
52 int
tape_std_assign(struct tape_device * device)53 tape_std_assign(struct tape_device *device)
54 {
55 int rc;
56 struct tape_request *request;
57
58 request = tape_alloc_request(2, 11);
59 if (IS_ERR(request))
60 return PTR_ERR(request);
61
62 request->op = TO_ASSIGN;
63 tape_ccw_cc(request->cpaddr, ASSIGN, 11, request->cpdata);
64 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
65
66 /*
67 * The assign command sometimes blocks if the device is assigned
68 * to another host (actually this shouldn't happen but it does).
69 * So we set up a timeout for this call.
70 */
71 timer_setup(&request->timer, tape_std_assign_timeout, 0);
72 mod_timer(&request->timer, jiffies + msecs_to_jiffies(2000));
73
74 rc = tape_do_io_interruptible(device, request);
75
76 timer_delete_sync(&request->timer);
77
78 if (rc != 0) {
79 DBF_EVENT(3, "%08x: assign failed - device might be busy\n",
80 device->cdev_id);
81 } else {
82 DBF_EVENT(3, "%08x: Tape assigned\n", device->cdev_id);
83 }
84 tape_free_request(request);
85 return rc;
86 }
87
88 /*
89 * tape_std_unassign
90 */
91 int
tape_std_unassign(struct tape_device * device)92 tape_std_unassign (struct tape_device *device)
93 {
94 int rc;
95 struct tape_request *request;
96
97 if (device->tape_state == TS_NOT_OPER) {
98 DBF_EVENT(3, "(%08x): Can't unassign device\n",
99 device->cdev_id);
100 return -EIO;
101 }
102
103 request = tape_alloc_request(2, 11);
104 if (IS_ERR(request))
105 return PTR_ERR(request);
106
107 request->op = TO_UNASSIGN;
108 tape_ccw_cc(request->cpaddr, UNASSIGN, 11, request->cpdata);
109 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
110
111 if ((rc = tape_do_io(device, request)) != 0) {
112 DBF_EVENT(3, "%08x: Unassign failed\n", device->cdev_id);
113 } else {
114 DBF_EVENT(3, "%08x: Tape unassigned\n", device->cdev_id);
115 }
116 tape_free_request(request);
117 return rc;
118 }
119
120 /*
121 * Read block id.
122 */
123 int
tape_std_read_block_id(struct tape_device * device,__u64 * id)124 tape_std_read_block_id(struct tape_device *device, __u64 *id)
125 {
126 struct tape_request *request;
127 int rc;
128
129 request = tape_alloc_request(3, 8);
130 if (IS_ERR(request))
131 return PTR_ERR(request);
132 request->op = TO_RBI;
133 /* setup ccws */
134 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
135 tape_ccw_cc(request->cpaddr + 1, READ_BLOCK_ID, 8, request->cpdata);
136 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
137 /* execute it */
138 rc = tape_do_io(device, request);
139 if (rc == 0)
140 /* Get result from read buffer. */
141 *id = *(__u64 *) request->cpdata;
142 tape_free_request(request);
143 return rc;
144 }
145
146 int
tape_std_terminate_write(struct tape_device * device)147 tape_std_terminate_write(struct tape_device *device)
148 {
149 int rc;
150
151 if(device->required_tapemarks == 0)
152 return 0;
153
154 DBF_LH(5, "tape%d: terminate write %dxEOF\n", device->first_minor,
155 device->required_tapemarks);
156
157 rc = tape_mtop(device, MTWEOF, device->required_tapemarks);
158 if (rc)
159 return rc;
160
161 device->required_tapemarks = 0;
162 return tape_mtop(device, MTBSR, 1);
163 }
164
165 /*
166 * MTLOAD: Loads the tape.
167 * The default implementation just wait until the tape medium state changes
168 * to MS_LOADED.
169 */
170 int
tape_std_mtload(struct tape_device * device,int count)171 tape_std_mtload(struct tape_device *device, int count)
172 {
173 return wait_event_interruptible(device->state_change_wq,
174 (device->medium_state == MS_LOADED));
175 }
176
177 /*
178 * MTSETBLK: Set block size.
179 */
180 int
tape_std_mtsetblk(struct tape_device * device,int count)181 tape_std_mtsetblk(struct tape_device *device, int count)
182 {
183 int rc;
184
185 DBF_LH(6, "tape_std_mtsetblk(%d)\n", count);
186 if (count <= 0) {
187 /*
188 * Just set block_size to 0. tapechar_read/tapechar_write
189 * will realloc the idal buffer if a bigger one than the
190 * current is needed.
191 */
192 device->char_data.block_size = 0;
193 return 0;
194 }
195
196 rc = tape_check_idalbuffer(device, count);
197 if (rc)
198 return rc;
199
200 device->char_data.block_size = count;
201 DBF_LH(6, "new blocksize is %d\n", device->char_data.block_size);
202
203 return 0;
204 }
205
206 /*
207 * MTRESET: Set block size to 0.
208 */
209 int
tape_std_mtreset(struct tape_device * device,int count)210 tape_std_mtreset(struct tape_device *device, int count)
211 {
212 DBF_EVENT(6, "TCHAR:devreset:\n");
213 device->char_data.block_size = 0;
214 return 0;
215 }
216
217 /*
218 * MTFSF: Forward space over 'count' file marks. The tape is positioned
219 * at the EOT (End of Tape) side of the file mark.
220 */
221 int
tape_std_mtfsf(struct tape_device * device,int mt_count)222 tape_std_mtfsf(struct tape_device *device, int mt_count)
223 {
224 struct tape_request *request;
225 struct ccw1 *ccw;
226
227 request = tape_alloc_request(mt_count + 2, 0);
228 if (IS_ERR(request))
229 return PTR_ERR(request);
230 request->op = TO_FSF;
231 /* setup ccws */
232 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
233 device->modeset_byte);
234 ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
235 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
236
237 /* execute it */
238 return tape_do_io_free(device, request);
239 }
240
241 /*
242 * MTFSR: Forward space over 'count' tape blocks (blocksize is set
243 * via MTSETBLK.
244 */
245 int
tape_std_mtfsr(struct tape_device * device,int mt_count)246 tape_std_mtfsr(struct tape_device *device, int mt_count)
247 {
248 struct tape_request *request;
249 struct ccw1 *ccw;
250 int rc;
251
252 request = tape_alloc_request(mt_count + 2, 0);
253 if (IS_ERR(request))
254 return PTR_ERR(request);
255 request->op = TO_FSB;
256 /* setup ccws */
257 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
258 device->modeset_byte);
259 ccw = tape_ccw_repeat(ccw, FORSPACEBLOCK, mt_count);
260 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
261
262 /* execute it */
263 rc = tape_do_io(device, request);
264 if (rc == 0 && request->rescnt > 0) {
265 DBF_LH(3, "FSR over tapemark\n");
266 rc = 1;
267 }
268 tape_free_request(request);
269
270 return rc;
271 }
272
273 /*
274 * MTBSR: Backward space over 'count' tape blocks.
275 * (blocksize is set via MTSETBLK.
276 */
277 int
tape_std_mtbsr(struct tape_device * device,int mt_count)278 tape_std_mtbsr(struct tape_device *device, int mt_count)
279 {
280 struct tape_request *request;
281 struct ccw1 *ccw;
282 int rc;
283
284 request = tape_alloc_request(mt_count + 2, 0);
285 if (IS_ERR(request))
286 return PTR_ERR(request);
287 request->op = TO_BSB;
288 /* setup ccws */
289 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
290 device->modeset_byte);
291 ccw = tape_ccw_repeat(ccw, BACKSPACEBLOCK, mt_count);
292 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
293
294 /* execute it */
295 rc = tape_do_io(device, request);
296 if (rc == 0 && request->rescnt > 0) {
297 DBF_LH(3, "BSR over tapemark\n");
298 rc = 1;
299 }
300 tape_free_request(request);
301
302 return rc;
303 }
304
305 /*
306 * MTWEOF: Write 'count' file marks at the current position.
307 */
308 int
tape_std_mtweof(struct tape_device * device,int mt_count)309 tape_std_mtweof(struct tape_device *device, int mt_count)
310 {
311 struct tape_request *request;
312 struct ccw1 *ccw;
313
314 request = tape_alloc_request(mt_count + 2, 0);
315 if (IS_ERR(request))
316 return PTR_ERR(request);
317 request->op = TO_WTM;
318 /* setup ccws */
319 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
320 device->modeset_byte);
321 ccw = tape_ccw_repeat(ccw, WRITETAPEMARK, mt_count);
322 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
323
324 /* execute it */
325 return tape_do_io_free(device, request);
326 }
327
328 /*
329 * MTBSFM: Backward space over 'count' file marks.
330 * The tape is positioned at the BOT (Begin Of Tape) side of the
331 * last skipped file mark.
332 */
333 int
tape_std_mtbsfm(struct tape_device * device,int mt_count)334 tape_std_mtbsfm(struct tape_device *device, int mt_count)
335 {
336 struct tape_request *request;
337 struct ccw1 *ccw;
338
339 request = tape_alloc_request(mt_count + 2, 0);
340 if (IS_ERR(request))
341 return PTR_ERR(request);
342 request->op = TO_BSF;
343 /* setup ccws */
344 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
345 device->modeset_byte);
346 ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count);
347 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
348
349 /* execute it */
350 return tape_do_io_free(device, request);
351 }
352
353 /*
354 * MTBSF: Backward space over 'count' file marks. The tape is positioned at
355 * the EOT (End of Tape) side of the last skipped file mark.
356 */
357 int
tape_std_mtbsf(struct tape_device * device,int mt_count)358 tape_std_mtbsf(struct tape_device *device, int mt_count)
359 {
360 struct tape_request *request;
361 struct ccw1 *ccw;
362 int rc;
363
364 request = tape_alloc_request(mt_count + 2, 0);
365 if (IS_ERR(request))
366 return PTR_ERR(request);
367 request->op = TO_BSF;
368 /* setup ccws */
369 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
370 device->modeset_byte);
371 ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count);
372 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
373 /* execute it */
374 rc = tape_do_io_free(device, request);
375 if (rc == 0) {
376 rc = tape_mtop(device, MTFSR, 1);
377 if (rc > 0)
378 rc = 0;
379 }
380 return rc;
381 }
382
383 /*
384 * MTFSFM: Forward space over 'count' file marks.
385 * The tape is positioned at the BOT (Begin Of Tape) side
386 * of the last skipped file mark.
387 */
388 int
tape_std_mtfsfm(struct tape_device * device,int mt_count)389 tape_std_mtfsfm(struct tape_device *device, int mt_count)
390 {
391 struct tape_request *request;
392 struct ccw1 *ccw;
393 int rc;
394
395 request = tape_alloc_request(mt_count + 2, 0);
396 if (IS_ERR(request))
397 return PTR_ERR(request);
398 request->op = TO_FSF;
399 /* setup ccws */
400 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
401 device->modeset_byte);
402 ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
403 ccw = tape_ccw_end(ccw, NOP, 0, NULL);
404 /* execute it */
405 rc = tape_do_io_free(device, request);
406 if (rc == 0) {
407 rc = tape_mtop(device, MTBSR, 1);
408 if (rc > 0)
409 rc = 0;
410 }
411
412 return rc;
413 }
414
415 /*
416 * MTREW: Rewind the tape.
417 */
418 int
tape_std_mtrew(struct tape_device * device,int mt_count)419 tape_std_mtrew(struct tape_device *device, int mt_count)
420 {
421 struct tape_request *request;
422
423 request = tape_alloc_request(3, 0);
424 if (IS_ERR(request))
425 return PTR_ERR(request);
426 request->op = TO_REW;
427 /* setup ccws */
428 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
429 device->modeset_byte);
430 tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
431 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
432
433 /* execute it */
434 return tape_do_io_free(device, request);
435 }
436
437 /*
438 * MTOFFL: Rewind the tape and put the drive off-line.
439 * Implement 'rewind unload'
440 */
441 int
tape_std_mtoffl(struct tape_device * device,int mt_count)442 tape_std_mtoffl(struct tape_device *device, int mt_count)
443 {
444 struct tape_request *request;
445
446 request = tape_alloc_request(3, 0);
447 if (IS_ERR(request))
448 return PTR_ERR(request);
449 request->op = TO_RUN;
450 /* setup ccws */
451 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
452 tape_ccw_cc(request->cpaddr + 1, REWIND_UNLOAD, 0, NULL);
453 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
454
455 /* execute it */
456 return tape_do_io_free(device, request);
457 }
458
459 /*
460 * MTNOP: 'No operation'.
461 */
462 int
tape_std_mtnop(struct tape_device * device,int mt_count)463 tape_std_mtnop(struct tape_device *device, int mt_count)
464 {
465 struct tape_request *request;
466
467 request = tape_alloc_request(2, 0);
468 if (IS_ERR(request))
469 return PTR_ERR(request);
470 request->op = TO_NOP;
471 /* setup ccws */
472 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
473 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
474 /* execute it */
475 return tape_do_io_free(device, request);
476 }
477
478 /*
479 * MTEOM: positions at the end of the portion of the tape already used
480 * for recordind data. MTEOM positions after the last file mark, ready for
481 * appending another file.
482 */
483 int
tape_std_mteom(struct tape_device * device,int mt_count)484 tape_std_mteom(struct tape_device *device, int mt_count)
485 {
486 int rc;
487
488 /*
489 * Seek from the beginning of tape (rewind).
490 */
491 if ((rc = tape_mtop(device, MTREW, 1)) < 0)
492 return rc;
493
494 /*
495 * The logical end of volume is given by two sewuential tapemarks.
496 * Look for this by skipping to the next file (over one tapemark)
497 * and then test for another one (fsr returns 1 if a tapemark was
498 * encountered).
499 */
500 do {
501 if ((rc = tape_mtop(device, MTFSF, 1)) < 0)
502 return rc;
503 if ((rc = tape_mtop(device, MTFSR, 1)) < 0)
504 return rc;
505 } while (rc == 0);
506
507 return tape_mtop(device, MTBSR, 1);
508 }
509
510 /*
511 * MTRETEN: Retension the tape, i.e. forward space to end of tape and rewind.
512 */
513 int
tape_std_mtreten(struct tape_device * device,int mt_count)514 tape_std_mtreten(struct tape_device *device, int mt_count)
515 {
516 struct tape_request *request;
517
518 request = tape_alloc_request(4, 0);
519 if (IS_ERR(request))
520 return PTR_ERR(request);
521 request->op = TO_FSF;
522 /* setup ccws */
523 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
524 tape_ccw_cc(request->cpaddr + 1,FORSPACEFILE, 0, NULL);
525 tape_ccw_cc(request->cpaddr + 2, NOP, 0, NULL);
526 tape_ccw_end(request->cpaddr + 3, CCW_CMD_TIC, 0, request->cpaddr);
527 /* execute it, MTRETEN rc gets ignored */
528 tape_do_io_interruptible(device, request);
529 tape_free_request(request);
530 return tape_mtop(device, MTREW, 1);
531 }
532
533 /*
534 * MTERASE: erases the tape.
535 */
536 int
tape_std_mterase(struct tape_device * device,int mt_count)537 tape_std_mterase(struct tape_device *device, int mt_count)
538 {
539 struct tape_request *request;
540
541 request = tape_alloc_request(6, 0);
542 if (IS_ERR(request))
543 return PTR_ERR(request);
544 request->op = TO_DSE;
545 /* setup ccws */
546 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
547 tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
548 tape_ccw_cc(request->cpaddr + 2, ERASE_GAP, 0, NULL);
549 tape_ccw_cc(request->cpaddr + 3, DATA_SEC_ERASE, 0, NULL);
550 tape_ccw_cc(request->cpaddr + 4, REWIND, 0, NULL);
551 tape_ccw_end(request->cpaddr + 5, NOP, 0, NULL);
552
553 /* execute it */
554 return tape_do_io_free(device, request);
555 }
556
557 /*
558 * MTUNLOAD: Rewind the tape and unload it.
559 */
560 int
tape_std_mtunload(struct tape_device * device,int mt_count)561 tape_std_mtunload(struct tape_device *device, int mt_count)
562 {
563 return tape_mtop(device, MTOFFL, mt_count);
564 }
565
566 /*
567 * MTCOMPRESSION: used to enable compression.
568 * Sets the IDRC on/off.
569 */
570 int
tape_std_mtcompression(struct tape_device * device,int mt_count)571 tape_std_mtcompression(struct tape_device *device, int mt_count)
572 {
573 struct tape_request *request;
574
575 if (mt_count < 0 || mt_count > 1) {
576 DBF_EXCEPTION(6, "xcom parm\n");
577 return -EINVAL;
578 }
579 request = tape_alloc_request(2, 0);
580 if (IS_ERR(request))
581 return PTR_ERR(request);
582 request->op = TO_NOP;
583 /* setup ccws */
584 if (mt_count == 0)
585 *device->modeset_byte &= ~0x08;
586 else
587 *device->modeset_byte |= 0x08;
588 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
589 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
590 /* execute it */
591 return tape_do_io_free(device, request);
592 }
593
594 /*
595 * Read Block
596 */
597 struct tape_request *
tape_std_read_block(struct tape_device * device)598 tape_std_read_block(struct tape_device *device)
599 {
600 struct tape_request *request;
601 struct idal_buffer **ibs;
602 struct ccw1 *ccw;
603 size_t count;
604
605 ibs = device->char_data.ibs;
606 count = idal_buffer_array_size(ibs);
607 request = tape_alloc_request(count + 1 /* MODE_SET_DB */, 0);
608 if (IS_ERR(request)) {
609 DBF_EXCEPTION(6, "xrbl fail");
610 return request;
611 }
612 request->op = TO_RFO;
613 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
614 while (count-- > 1)
615 ccw = tape_ccw_dc_idal(ccw, READ_FORWARD, *ibs++);
616 tape_ccw_end_idal(ccw, READ_FORWARD, *ibs);
617
618 DBF_EVENT(6, "xrbl ccwg\n");
619 return request;
620 }
621
622 /*
623 * Write Block
624 */
625 struct tape_request *
tape_std_write_block(struct tape_device * device)626 tape_std_write_block(struct tape_device *device)
627 {
628 struct tape_request *request;
629 struct idal_buffer **ibs;
630 struct ccw1 *ccw;
631 size_t count;
632
633 count = idal_buffer_array_size(device->char_data.ibs);
634 request = tape_alloc_request(count + 1 /* MODE_SET_DB */, 0);
635 if (IS_ERR(request)) {
636 DBF_EXCEPTION(6, "xwbl fail\n");
637 return request;
638 }
639 request->op = TO_WRI;
640 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
641 ibs = device->char_data.ibs;
642 while (count-- > 1)
643 ccw = tape_ccw_dc_idal(ccw, WRITE_CMD, *ibs++);
644 tape_ccw_end_idal(ccw, WRITE_CMD, *ibs);
645
646 DBF_EVENT(6, "xwbl ccwg\n");
647 return request;
648 }
649
650 /*
651 * This routine is called by frontend after an ENOSP on write
652 */
653 void
tape_std_process_eov(struct tape_device * device)654 tape_std_process_eov(struct tape_device *device)
655 {
656 /*
657 * End of volume: We have to backspace the last written record, then
658 * we TRY to write a tapemark and then backspace over the written TM
659 */
660 if (tape_mtop(device, MTBSR, 1) == 0 &&
661 tape_mtop(device, MTWEOF, 1) == 0) {
662 tape_mtop(device, MTBSR, 1);
663 }
664 }
665
666 EXPORT_SYMBOL(tape_std_assign);
667 EXPORT_SYMBOL(tape_std_unassign);
668 EXPORT_SYMBOL(tape_std_read_block_id);
669 EXPORT_SYMBOL(tape_std_mtload);
670 EXPORT_SYMBOL(tape_std_mtsetblk);
671 EXPORT_SYMBOL(tape_std_mtreset);
672 EXPORT_SYMBOL(tape_std_mtfsf);
673 EXPORT_SYMBOL(tape_std_mtfsr);
674 EXPORT_SYMBOL(tape_std_mtbsr);
675 EXPORT_SYMBOL(tape_std_mtweof);
676 EXPORT_SYMBOL(tape_std_mtbsfm);
677 EXPORT_SYMBOL(tape_std_mtbsf);
678 EXPORT_SYMBOL(tape_std_mtfsfm);
679 EXPORT_SYMBOL(tape_std_mtrew);
680 EXPORT_SYMBOL(tape_std_mtoffl);
681 EXPORT_SYMBOL(tape_std_mtnop);
682 EXPORT_SYMBOL(tape_std_mteom);
683 EXPORT_SYMBOL(tape_std_mtreten);
684 EXPORT_SYMBOL(tape_std_mterase);
685 EXPORT_SYMBOL(tape_std_mtunload);
686 EXPORT_SYMBOL(tape_std_mtcompression);
687 EXPORT_SYMBOL(tape_std_read_block);
688 EXPORT_SYMBOL(tape_std_write_block);
689 EXPORT_SYMBOL(tape_std_process_eov);
690