GNU Linux-libre 4.19.245-gnu1
[releases.git] / drivers / s390 / char / tape_std.c
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 KMSG_COMPONENT "tape"
15 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
16
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 #include <asm/tape390.h>
26
27 #define TAPE_DBF_AREA   tape_core_dbf
28
29 #include "tape.h"
30 #include "tape_std.h"
31
32 /*
33  * tape_std_assign
34  */
35 static void
36 tape_std_assign_timeout(struct timer_list *t)
37 {
38         struct tape_request *   request = from_timer(request, t, 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
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         del_timer_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
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  * TAPE390_DISPLAY: Show a string on the tape display.
122  */
123 int
124 tape_std_display(struct tape_device *device, struct display_struct *disp)
125 {
126         struct tape_request *request;
127         int rc;
128
129         request = tape_alloc_request(2, 17);
130         if (IS_ERR(request)) {
131                 DBF_EVENT(3, "TAPE: load display failed\n");
132                 return PTR_ERR(request);
133         }
134         request->op = TO_DIS;
135
136         *(unsigned char *) request->cpdata = disp->cntrl;
137         DBF_EVENT(5, "TAPE: display cntrl=%04x\n", disp->cntrl);
138         memcpy(((unsigned char *) request->cpdata) + 1, disp->message1, 8);
139         memcpy(((unsigned char *) request->cpdata) + 9, disp->message2, 8);
140         ASCEBC(((unsigned char*) request->cpdata) + 1, 16);
141
142         tape_ccw_cc(request->cpaddr, LOAD_DISPLAY, 17, request->cpdata);
143         tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
144
145         rc = tape_do_io_interruptible(device, request);
146         tape_free_request(request);
147         return rc;
148 }
149
150 /*
151  * Read block id.
152  */
153 int
154 tape_std_read_block_id(struct tape_device *device, __u64 *id)
155 {
156         struct tape_request *request;
157         int rc;
158
159         request = tape_alloc_request(3, 8);
160         if (IS_ERR(request))
161                 return PTR_ERR(request);
162         request->op = TO_RBI;
163         /* setup ccws */
164         tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
165         tape_ccw_cc(request->cpaddr + 1, READ_BLOCK_ID, 8, request->cpdata);
166         tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
167         /* execute it */
168         rc = tape_do_io(device, request);
169         if (rc == 0)
170                 /* Get result from read buffer. */
171                 *id = *(__u64 *) request->cpdata;
172         tape_free_request(request);
173         return rc;
174 }
175
176 int
177 tape_std_terminate_write(struct tape_device *device)
178 {
179         int rc;
180
181         if(device->required_tapemarks == 0)
182                 return 0;
183
184         DBF_LH(5, "tape%d: terminate write %dxEOF\n", device->first_minor,
185                 device->required_tapemarks);
186
187         rc = tape_mtop(device, MTWEOF, device->required_tapemarks);
188         if (rc)
189                 return rc;
190
191         device->required_tapemarks = 0;
192         return tape_mtop(device, MTBSR, 1);
193 }
194
195 /*
196  * MTLOAD: Loads the tape.
197  * The default implementation just wait until the tape medium state changes
198  * to MS_LOADED.
199  */
200 int
201 tape_std_mtload(struct tape_device *device, int count)
202 {
203         return wait_event_interruptible(device->state_change_wq,
204                 (device->medium_state == MS_LOADED));
205 }
206
207 /*
208  * MTSETBLK: Set block size.
209  */
210 int
211 tape_std_mtsetblk(struct tape_device *device, int count)
212 {
213         struct idal_buffer *new;
214
215         DBF_LH(6, "tape_std_mtsetblk(%d)\n", count);
216         if (count <= 0) {
217                 /*
218                  * Just set block_size to 0. tapechar_read/tapechar_write
219                  * will realloc the idal buffer if a bigger one than the
220                  * current is needed.
221                  */
222                 device->char_data.block_size = 0;
223                 return 0;
224         }
225         if (device->char_data.idal_buf != NULL &&
226             device->char_data.idal_buf->size == count)
227                 /* We already have a idal buffer of that size. */
228                 return 0;
229
230         if (count > MAX_BLOCKSIZE) {
231                 DBF_EVENT(3, "Invalid block size (%d > %d) given.\n",
232                         count, MAX_BLOCKSIZE);
233                 return -EINVAL;
234         }
235
236         /* Allocate a new idal buffer. */
237         new = idal_buffer_alloc(count, 0);
238         if (IS_ERR(new))
239                 return -ENOMEM;
240         if (device->char_data.idal_buf != NULL)
241                 idal_buffer_free(device->char_data.idal_buf);
242         device->char_data.idal_buf = new;
243         device->char_data.block_size = count;
244
245         DBF_LH(6, "new blocksize is %d\n", device->char_data.block_size);
246
247         return 0;
248 }
249
250 /*
251  * MTRESET: Set block size to 0.
252  */
253 int
254 tape_std_mtreset(struct tape_device *device, int count)
255 {
256         DBF_EVENT(6, "TCHAR:devreset:\n");
257         device->char_data.block_size = 0;
258         return 0;
259 }
260
261 /*
262  * MTFSF: Forward space over 'count' file marks. The tape is positioned
263  * at the EOT (End of Tape) side of the file mark.
264  */
265 int
266 tape_std_mtfsf(struct tape_device *device, int mt_count)
267 {
268         struct tape_request *request;
269         struct ccw1 *ccw;
270
271         request = tape_alloc_request(mt_count + 2, 0);
272         if (IS_ERR(request))
273                 return PTR_ERR(request);
274         request->op = TO_FSF;
275         /* setup ccws */
276         ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
277                           device->modeset_byte);
278         ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
279         ccw = tape_ccw_end(ccw, NOP, 0, NULL);
280
281         /* execute it */
282         return tape_do_io_free(device, request);
283 }
284
285 /*
286  * MTFSR: Forward space over 'count' tape blocks (blocksize is set
287  * via MTSETBLK.
288  */
289 int
290 tape_std_mtfsr(struct tape_device *device, int mt_count)
291 {
292         struct tape_request *request;
293         struct ccw1 *ccw;
294         int rc;
295
296         request = tape_alloc_request(mt_count + 2, 0);
297         if (IS_ERR(request))
298                 return PTR_ERR(request);
299         request->op = TO_FSB;
300         /* setup ccws */
301         ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
302                           device->modeset_byte);
303         ccw = tape_ccw_repeat(ccw, FORSPACEBLOCK, mt_count);
304         ccw = tape_ccw_end(ccw, NOP, 0, NULL);
305
306         /* execute it */
307         rc = tape_do_io(device, request);
308         if (rc == 0 && request->rescnt > 0) {
309                 DBF_LH(3, "FSR over tapemark\n");
310                 rc = 1;
311         }
312         tape_free_request(request);
313
314         return rc;
315 }
316
317 /*
318  * MTBSR: Backward space over 'count' tape blocks.
319  * (blocksize is set via MTSETBLK.
320  */
321 int
322 tape_std_mtbsr(struct tape_device *device, int mt_count)
323 {
324         struct tape_request *request;
325         struct ccw1 *ccw;
326         int rc;
327
328         request = tape_alloc_request(mt_count + 2, 0);
329         if (IS_ERR(request))
330                 return PTR_ERR(request);
331         request->op = TO_BSB;
332         /* setup ccws */
333         ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
334                           device->modeset_byte);
335         ccw = tape_ccw_repeat(ccw, BACKSPACEBLOCK, mt_count);
336         ccw = tape_ccw_end(ccw, NOP, 0, NULL);
337
338         /* execute it */
339         rc = tape_do_io(device, request);
340         if (rc == 0 && request->rescnt > 0) {
341                 DBF_LH(3, "BSR over tapemark\n");
342                 rc = 1;
343         }
344         tape_free_request(request);
345
346         return rc;
347 }
348
349 /*
350  * MTWEOF: Write 'count' file marks at the current position.
351  */
352 int
353 tape_std_mtweof(struct tape_device *device, int mt_count)
354 {
355         struct tape_request *request;
356         struct ccw1 *ccw;
357
358         request = tape_alloc_request(mt_count + 2, 0);
359         if (IS_ERR(request))
360                 return PTR_ERR(request);
361         request->op = TO_WTM;
362         /* setup ccws */
363         ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
364                           device->modeset_byte);
365         ccw = tape_ccw_repeat(ccw, WRITETAPEMARK, mt_count);
366         ccw = tape_ccw_end(ccw, NOP, 0, NULL);
367
368         /* execute it */
369         return tape_do_io_free(device, request);
370 }
371
372 /*
373  * MTBSFM: Backward space over 'count' file marks.
374  * The tape is positioned at the BOT (Begin Of Tape) side of the
375  * last skipped file mark.
376  */
377 int
378 tape_std_mtbsfm(struct tape_device *device, int mt_count)
379 {
380         struct tape_request *request;
381         struct ccw1 *ccw;
382
383         request = tape_alloc_request(mt_count + 2, 0);
384         if (IS_ERR(request))
385                 return PTR_ERR(request);
386         request->op = TO_BSF;
387         /* setup ccws */
388         ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
389                           device->modeset_byte);
390         ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count);
391         ccw = tape_ccw_end(ccw, NOP, 0, NULL);
392
393         /* execute it */
394         return tape_do_io_free(device, request);
395 }
396
397 /*
398  * MTBSF: Backward space over 'count' file marks. The tape is positioned at
399  * the EOT (End of Tape) side of the last skipped file mark.
400  */
401 int
402 tape_std_mtbsf(struct tape_device *device, int mt_count)
403 {
404         struct tape_request *request;
405         struct ccw1 *ccw;
406         int rc;
407
408         request = tape_alloc_request(mt_count + 2, 0);
409         if (IS_ERR(request))
410                 return PTR_ERR(request);
411         request->op = TO_BSF;
412         /* setup ccws */
413         ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
414                           device->modeset_byte);
415         ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count);
416         ccw = tape_ccw_end(ccw, NOP, 0, NULL);
417         /* execute it */
418         rc = tape_do_io_free(device, request);
419         if (rc == 0) {
420                 rc = tape_mtop(device, MTFSR, 1);
421                 if (rc > 0)
422                         rc = 0;
423         }
424         return rc;
425 }
426
427 /*
428  * MTFSFM: Forward space over 'count' file marks.
429  * The tape is positioned at the BOT (Begin Of Tape) side
430  * of the last skipped file mark.
431  */
432 int
433 tape_std_mtfsfm(struct tape_device *device, int mt_count)
434 {
435         struct tape_request *request;
436         struct ccw1 *ccw;
437         int rc;
438
439         request = tape_alloc_request(mt_count + 2, 0);
440         if (IS_ERR(request))
441                 return PTR_ERR(request);
442         request->op = TO_FSF;
443         /* setup ccws */
444         ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
445                           device->modeset_byte);
446         ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
447         ccw = tape_ccw_end(ccw, NOP, 0, NULL);
448         /* execute it */
449         rc = tape_do_io_free(device, request);
450         if (rc == 0) {
451                 rc = tape_mtop(device, MTBSR, 1);
452                 if (rc > 0)
453                         rc = 0;
454         }
455
456         return rc;
457 }
458
459 /*
460  * MTREW: Rewind the tape.
461  */
462 int
463 tape_std_mtrew(struct tape_device *device, int mt_count)
464 {
465         struct tape_request *request;
466
467         request = tape_alloc_request(3, 0);
468         if (IS_ERR(request))
469                 return PTR_ERR(request);
470         request->op = TO_REW;
471         /* setup ccws */
472         tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
473                     device->modeset_byte);
474         tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
475         tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
476
477         /* execute it */
478         return tape_do_io_free(device, request);
479 }
480
481 /*
482  * MTOFFL: Rewind the tape and put the drive off-line.
483  * Implement 'rewind unload'
484  */
485 int
486 tape_std_mtoffl(struct tape_device *device, int mt_count)
487 {
488         struct tape_request *request;
489
490         request = tape_alloc_request(3, 0);
491         if (IS_ERR(request))
492                 return PTR_ERR(request);
493         request->op = TO_RUN;
494         /* setup ccws */
495         tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
496         tape_ccw_cc(request->cpaddr + 1, REWIND_UNLOAD, 0, NULL);
497         tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
498
499         /* execute it */
500         return tape_do_io_free(device, request);
501 }
502
503 /*
504  * MTNOP: 'No operation'.
505  */
506 int
507 tape_std_mtnop(struct tape_device *device, int mt_count)
508 {
509         struct tape_request *request;
510
511         request = tape_alloc_request(2, 0);
512         if (IS_ERR(request))
513                 return PTR_ERR(request);
514         request->op = TO_NOP;
515         /* setup ccws */
516         tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
517         tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
518         /* execute it */
519         return tape_do_io_free(device, request);
520 }
521
522 /*
523  * MTEOM: positions at the end of the portion of the tape already used
524  * for recordind data. MTEOM positions after the last file mark, ready for
525  * appending another file.
526  */
527 int
528 tape_std_mteom(struct tape_device *device, int mt_count)
529 {
530         int rc;
531
532         /*
533          * Seek from the beginning of tape (rewind).
534          */
535         if ((rc = tape_mtop(device, MTREW, 1)) < 0)
536                 return rc;
537
538         /*
539          * The logical end of volume is given by two sewuential tapemarks.
540          * Look for this by skipping to the next file (over one tapemark)
541          * and then test for another one (fsr returns 1 if a tapemark was
542          * encountered).
543          */
544         do {
545                 if ((rc = tape_mtop(device, MTFSF, 1)) < 0)
546                         return rc;
547                 if ((rc = tape_mtop(device, MTFSR, 1)) < 0)
548                         return rc;
549         } while (rc == 0);
550
551         return tape_mtop(device, MTBSR, 1);
552 }
553
554 /*
555  * MTRETEN: Retension the tape, i.e. forward space to end of tape and rewind.
556  */
557 int
558 tape_std_mtreten(struct tape_device *device, int mt_count)
559 {
560         struct tape_request *request;
561
562         request = tape_alloc_request(4, 0);
563         if (IS_ERR(request))
564                 return PTR_ERR(request);
565         request->op = TO_FSF;
566         /* setup ccws */
567         tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
568         tape_ccw_cc(request->cpaddr + 1,FORSPACEFILE, 0, NULL);
569         tape_ccw_cc(request->cpaddr + 2, NOP, 0, NULL);
570         tape_ccw_end(request->cpaddr + 3, CCW_CMD_TIC, 0, request->cpaddr);
571         /* execute it, MTRETEN rc gets ignored */
572         tape_do_io_interruptible(device, request);
573         tape_free_request(request);
574         return tape_mtop(device, MTREW, 1);
575 }
576
577 /*
578  * MTERASE: erases the tape.
579  */
580 int
581 tape_std_mterase(struct tape_device *device, int mt_count)
582 {
583         struct tape_request *request;
584
585         request = tape_alloc_request(6, 0);
586         if (IS_ERR(request))
587                 return PTR_ERR(request);
588         request->op = TO_DSE;
589         /* setup ccws */
590         tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
591         tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
592         tape_ccw_cc(request->cpaddr + 2, ERASE_GAP, 0, NULL);
593         tape_ccw_cc(request->cpaddr + 3, DATA_SEC_ERASE, 0, NULL);
594         tape_ccw_cc(request->cpaddr + 4, REWIND, 0, NULL);
595         tape_ccw_end(request->cpaddr + 5, NOP, 0, NULL);
596
597         /* execute it */
598         return tape_do_io_free(device, request);
599 }
600
601 /*
602  * MTUNLOAD: Rewind the tape and unload it.
603  */
604 int
605 tape_std_mtunload(struct tape_device *device, int mt_count)
606 {
607         return tape_mtop(device, MTOFFL, mt_count);
608 }
609
610 /*
611  * MTCOMPRESSION: used to enable compression.
612  * Sets the IDRC on/off.
613  */
614 int
615 tape_std_mtcompression(struct tape_device *device, int mt_count)
616 {
617         struct tape_request *request;
618
619         if (mt_count < 0 || mt_count > 1) {
620                 DBF_EXCEPTION(6, "xcom parm\n");
621                 return -EINVAL;
622         }
623         request = tape_alloc_request(2, 0);
624         if (IS_ERR(request))
625                 return PTR_ERR(request);
626         request->op = TO_NOP;
627         /* setup ccws */
628         if (mt_count == 0)
629                 *device->modeset_byte &= ~0x08;
630         else
631                 *device->modeset_byte |= 0x08;
632         tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
633         tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
634         /* execute it */
635         return tape_do_io_free(device, request);
636 }
637
638 /*
639  * Read Block
640  */
641 struct tape_request *
642 tape_std_read_block(struct tape_device *device, size_t count)
643 {
644         struct tape_request *request;
645
646         /*
647          * We have to alloc 4 ccws in order to be able to transform request
648          * into a read backward request in error case.
649          */
650         request = tape_alloc_request(4, 0);
651         if (IS_ERR(request)) {
652                 DBF_EXCEPTION(6, "xrbl fail");
653                 return request;
654         }
655         request->op = TO_RFO;
656         tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
657         tape_ccw_end_idal(request->cpaddr + 1, READ_FORWARD,
658                           device->char_data.idal_buf);
659         DBF_EVENT(6, "xrbl ccwg\n");
660         return request;
661 }
662
663 /*
664  * Read Block backward transformation function.
665  */
666 void
667 tape_std_read_backward(struct tape_device *device, struct tape_request *request)
668 {
669         /*
670          * We have allocated 4 ccws in tape_std_read, so we can now
671          * transform the request to a read backward, followed by a
672          * forward space block.
673          */
674         request->op = TO_RBA;
675         tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
676         tape_ccw_cc_idal(request->cpaddr + 1, READ_BACKWARD,
677                          device->char_data.idal_buf);
678         tape_ccw_cc(request->cpaddr + 2, FORSPACEBLOCK, 0, NULL);
679         tape_ccw_end(request->cpaddr + 3, NOP, 0, NULL);
680         DBF_EVENT(6, "xrop ccwg");}
681
682 /*
683  * Write Block
684  */
685 struct tape_request *
686 tape_std_write_block(struct tape_device *device, size_t count)
687 {
688         struct tape_request *request;
689
690         request = tape_alloc_request(2, 0);
691         if (IS_ERR(request)) {
692                 DBF_EXCEPTION(6, "xwbl fail\n");
693                 return request;
694         }
695         request->op = TO_WRI;
696         tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
697         tape_ccw_end_idal(request->cpaddr + 1, WRITE_CMD,
698                           device->char_data.idal_buf);
699         DBF_EVENT(6, "xwbl ccwg\n");
700         return request;
701 }
702
703 /*
704  * This routine is called by frontend after an ENOSP on write
705  */
706 void
707 tape_std_process_eov(struct tape_device *device)
708 {
709         /*
710          * End of volume: We have to backspace the last written record, then
711          * we TRY to write a tapemark and then backspace over the written TM
712          */
713         if (tape_mtop(device, MTBSR, 1) == 0 &&
714             tape_mtop(device, MTWEOF, 1) == 0) {
715                 tape_mtop(device, MTBSR, 1);
716         }
717 }
718
719 EXPORT_SYMBOL(tape_std_assign);
720 EXPORT_SYMBOL(tape_std_unassign);
721 EXPORT_SYMBOL(tape_std_display);
722 EXPORT_SYMBOL(tape_std_read_block_id);
723 EXPORT_SYMBOL(tape_std_mtload);
724 EXPORT_SYMBOL(tape_std_mtsetblk);
725 EXPORT_SYMBOL(tape_std_mtreset);
726 EXPORT_SYMBOL(tape_std_mtfsf);
727 EXPORT_SYMBOL(tape_std_mtfsr);
728 EXPORT_SYMBOL(tape_std_mtbsr);
729 EXPORT_SYMBOL(tape_std_mtweof);
730 EXPORT_SYMBOL(tape_std_mtbsfm);
731 EXPORT_SYMBOL(tape_std_mtbsf);
732 EXPORT_SYMBOL(tape_std_mtfsfm);
733 EXPORT_SYMBOL(tape_std_mtrew);
734 EXPORT_SYMBOL(tape_std_mtoffl);
735 EXPORT_SYMBOL(tape_std_mtnop);
736 EXPORT_SYMBOL(tape_std_mteom);
737 EXPORT_SYMBOL(tape_std_mtreten);
738 EXPORT_SYMBOL(tape_std_mterase);
739 EXPORT_SYMBOL(tape_std_mtunload);
740 EXPORT_SYMBOL(tape_std_mtcompression);
741 EXPORT_SYMBOL(tape_std_read_block);
742 EXPORT_SYMBOL(tape_std_read_backward);
743 EXPORT_SYMBOL(tape_std_write_block);
744 EXPORT_SYMBOL(tape_std_process_eov);