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