xref: /linux/drivers/s390/char/tape_std.c (revision 7fc2cd2e4b398c57c9cf961cfea05eadbf34c05c)
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 #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 = timer_container_of(request, t,
39 								  timer);
40 	struct tape_device *	device = request->device;
41 	int rc;
42 
43 	BUG_ON(!device);
44 
45 	DBF_EVENT(3, "%08x: Assignment timeout. Device busy.\n",
46 			device->cdev_id);
47 	rc = tape_cancel_io(device, request);
48 	if(rc)
49 		DBF_EVENT(3, "(%08x): Assign timeout: Cancel failed with rc = "
50 			  "%i\n", device->cdev_id, rc);
51 }
52 
53 int
54 tape_std_assign(struct tape_device *device)
55 {
56 	int                  rc;
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(&request->timer, jiffies + msecs_to_jiffies(2000));
74 
75 	rc = tape_do_io_interruptible(device, request);
76 
77 	timer_delete_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 	int rc;
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 
227 	rc = tape_check_idalbuffer(device, count);
228 	if (rc)
229 		return rc;
230 
231 	device->char_data.block_size = count;
232 	DBF_LH(6, "new blocksize is %d\n", device->char_data.block_size);
233 
234 	return 0;
235 }
236 
237 /*
238  * MTRESET: Set block size to 0.
239  */
240 int
241 tape_std_mtreset(struct tape_device *device, int count)
242 {
243 	DBF_EVENT(6, "TCHAR:devreset:\n");
244 	device->char_data.block_size = 0;
245 	return 0;
246 }
247 
248 /*
249  * MTFSF: Forward space over 'count' file marks. The tape is positioned
250  * at the EOT (End of Tape) side of the file mark.
251  */
252 int
253 tape_std_mtfsf(struct tape_device *device, int mt_count)
254 {
255 	struct tape_request *request;
256 	struct ccw1 *ccw;
257 
258 	request = tape_alloc_request(mt_count + 2, 0);
259 	if (IS_ERR(request))
260 		return PTR_ERR(request);
261 	request->op = TO_FSF;
262 	/* setup ccws */
263 	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
264 			  device->modeset_byte);
265 	ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
266 	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
267 
268 	/* execute it */
269 	return tape_do_io_free(device, request);
270 }
271 
272 /*
273  * MTFSR: Forward space over 'count' tape blocks (blocksize is set
274  * via MTSETBLK.
275  */
276 int
277 tape_std_mtfsr(struct tape_device *device, int mt_count)
278 {
279 	struct tape_request *request;
280 	struct ccw1 *ccw;
281 	int rc;
282 
283 	request = tape_alloc_request(mt_count + 2, 0);
284 	if (IS_ERR(request))
285 		return PTR_ERR(request);
286 	request->op = TO_FSB;
287 	/* setup ccws */
288 	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
289 			  device->modeset_byte);
290 	ccw = tape_ccw_repeat(ccw, FORSPACEBLOCK, mt_count);
291 	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
292 
293 	/* execute it */
294 	rc = tape_do_io(device, request);
295 	if (rc == 0 && request->rescnt > 0) {
296 		DBF_LH(3, "FSR over tapemark\n");
297 		rc = 1;
298 	}
299 	tape_free_request(request);
300 
301 	return rc;
302 }
303 
304 /*
305  * MTBSR: Backward space over 'count' tape blocks.
306  * (blocksize is set via MTSETBLK.
307  */
308 int
309 tape_std_mtbsr(struct tape_device *device, int mt_count)
310 {
311 	struct tape_request *request;
312 	struct ccw1 *ccw;
313 	int rc;
314 
315 	request = tape_alloc_request(mt_count + 2, 0);
316 	if (IS_ERR(request))
317 		return PTR_ERR(request);
318 	request->op = TO_BSB;
319 	/* setup ccws */
320 	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
321 			  device->modeset_byte);
322 	ccw = tape_ccw_repeat(ccw, BACKSPACEBLOCK, mt_count);
323 	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
324 
325 	/* execute it */
326 	rc = tape_do_io(device, request);
327 	if (rc == 0 && request->rescnt > 0) {
328 		DBF_LH(3, "BSR over tapemark\n");
329 		rc = 1;
330 	}
331 	tape_free_request(request);
332 
333 	return rc;
334 }
335 
336 /*
337  * MTWEOF: Write 'count' file marks at the current position.
338  */
339 int
340 tape_std_mtweof(struct tape_device *device, int mt_count)
341 {
342 	struct tape_request *request;
343 	struct ccw1 *ccw;
344 
345 	request = tape_alloc_request(mt_count + 2, 0);
346 	if (IS_ERR(request))
347 		return PTR_ERR(request);
348 	request->op = TO_WTM;
349 	/* setup ccws */
350 	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
351 			  device->modeset_byte);
352 	ccw = tape_ccw_repeat(ccw, WRITETAPEMARK, mt_count);
353 	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
354 
355 	/* execute it */
356 	return tape_do_io_free(device, request);
357 }
358 
359 /*
360  * MTBSFM: Backward space over 'count' file marks.
361  * The tape is positioned at the BOT (Begin Of Tape) side of the
362  * last skipped file mark.
363  */
364 int
365 tape_std_mtbsfm(struct tape_device *device, int mt_count)
366 {
367 	struct tape_request *request;
368 	struct ccw1 *ccw;
369 
370 	request = tape_alloc_request(mt_count + 2, 0);
371 	if (IS_ERR(request))
372 		return PTR_ERR(request);
373 	request->op = TO_BSF;
374 	/* setup ccws */
375 	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
376 			  device->modeset_byte);
377 	ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count);
378 	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
379 
380 	/* execute it */
381 	return tape_do_io_free(device, request);
382 }
383 
384 /*
385  * MTBSF: Backward space over 'count' file marks. The tape is positioned at
386  * the EOT (End of Tape) side of the last skipped file mark.
387  */
388 int
389 tape_std_mtbsf(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_BSF;
399 	/* setup ccws */
400 	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
401 			  device->modeset_byte);
402 	ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, 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, MTFSR, 1);
408 		if (rc > 0)
409 			rc = 0;
410 	}
411 	return rc;
412 }
413 
414 /*
415  * MTFSFM: Forward space over 'count' file marks.
416  * The tape is positioned at the BOT (Begin Of Tape) side
417  * of the last skipped file mark.
418  */
419 int
420 tape_std_mtfsfm(struct tape_device *device, int mt_count)
421 {
422 	struct tape_request *request;
423 	struct ccw1 *ccw;
424 	int rc;
425 
426 	request = tape_alloc_request(mt_count + 2, 0);
427 	if (IS_ERR(request))
428 		return PTR_ERR(request);
429 	request->op = TO_FSF;
430 	/* setup ccws */
431 	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
432 			  device->modeset_byte);
433 	ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
434 	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
435 	/* execute it */
436 	rc = tape_do_io_free(device, request);
437 	if (rc == 0) {
438 		rc = tape_mtop(device, MTBSR, 1);
439 		if (rc > 0)
440 			rc = 0;
441 	}
442 
443 	return rc;
444 }
445 
446 /*
447  * MTREW: Rewind the tape.
448  */
449 int
450 tape_std_mtrew(struct tape_device *device, int mt_count)
451 {
452 	struct tape_request *request;
453 
454 	request = tape_alloc_request(3, 0);
455 	if (IS_ERR(request))
456 		return PTR_ERR(request);
457 	request->op = TO_REW;
458 	/* setup ccws */
459 	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
460 		    device->modeset_byte);
461 	tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
462 	tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
463 
464 	/* execute it */
465 	return tape_do_io_free(device, request);
466 }
467 
468 /*
469  * MTOFFL: Rewind the tape and put the drive off-line.
470  * Implement 'rewind unload'
471  */
472 int
473 tape_std_mtoffl(struct tape_device *device, int mt_count)
474 {
475 	struct tape_request *request;
476 
477 	request = tape_alloc_request(3, 0);
478 	if (IS_ERR(request))
479 		return PTR_ERR(request);
480 	request->op = TO_RUN;
481 	/* setup ccws */
482 	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
483 	tape_ccw_cc(request->cpaddr + 1, REWIND_UNLOAD, 0, NULL);
484 	tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
485 
486 	/* execute it */
487 	return tape_do_io_free(device, request);
488 }
489 
490 /*
491  * MTNOP: 'No operation'.
492  */
493 int
494 tape_std_mtnop(struct tape_device *device, int mt_count)
495 {
496 	struct tape_request *request;
497 
498 	request = tape_alloc_request(2, 0);
499 	if (IS_ERR(request))
500 		return PTR_ERR(request);
501 	request->op = TO_NOP;
502 	/* setup ccws */
503 	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
504 	tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
505 	/* execute it */
506 	return tape_do_io_free(device, request);
507 }
508 
509 /*
510  * MTEOM: positions at the end of the portion of the tape already used
511  * for recordind data. MTEOM positions after the last file mark, ready for
512  * appending another file.
513  */
514 int
515 tape_std_mteom(struct tape_device *device, int mt_count)
516 {
517 	int rc;
518 
519 	/*
520 	 * Seek from the beginning of tape (rewind).
521 	 */
522 	if ((rc = tape_mtop(device, MTREW, 1)) < 0)
523 		return rc;
524 
525 	/*
526 	 * The logical end of volume is given by two sewuential tapemarks.
527 	 * Look for this by skipping to the next file (over one tapemark)
528 	 * and then test for another one (fsr returns 1 if a tapemark was
529 	 * encountered).
530 	 */
531 	do {
532 		if ((rc = tape_mtop(device, MTFSF, 1)) < 0)
533 			return rc;
534 		if ((rc = tape_mtop(device, MTFSR, 1)) < 0)
535 			return rc;
536 	} while (rc == 0);
537 
538 	return tape_mtop(device, MTBSR, 1);
539 }
540 
541 /*
542  * MTRETEN: Retension the tape, i.e. forward space to end of tape and rewind.
543  */
544 int
545 tape_std_mtreten(struct tape_device *device, int mt_count)
546 {
547 	struct tape_request *request;
548 
549 	request = tape_alloc_request(4, 0);
550 	if (IS_ERR(request))
551 		return PTR_ERR(request);
552 	request->op = TO_FSF;
553 	/* setup ccws */
554 	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
555 	tape_ccw_cc(request->cpaddr + 1,FORSPACEFILE, 0, NULL);
556 	tape_ccw_cc(request->cpaddr + 2, NOP, 0, NULL);
557 	tape_ccw_end(request->cpaddr + 3, CCW_CMD_TIC, 0, request->cpaddr);
558 	/* execute it, MTRETEN rc gets ignored */
559 	tape_do_io_interruptible(device, request);
560 	tape_free_request(request);
561 	return tape_mtop(device, MTREW, 1);
562 }
563 
564 /*
565  * MTERASE: erases the tape.
566  */
567 int
568 tape_std_mterase(struct tape_device *device, int mt_count)
569 {
570 	struct tape_request *request;
571 
572 	request = tape_alloc_request(6, 0);
573 	if (IS_ERR(request))
574 		return PTR_ERR(request);
575 	request->op = TO_DSE;
576 	/* setup ccws */
577 	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
578 	tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
579 	tape_ccw_cc(request->cpaddr + 2, ERASE_GAP, 0, NULL);
580 	tape_ccw_cc(request->cpaddr + 3, DATA_SEC_ERASE, 0, NULL);
581 	tape_ccw_cc(request->cpaddr + 4, REWIND, 0, NULL);
582 	tape_ccw_end(request->cpaddr + 5, NOP, 0, NULL);
583 
584 	/* execute it */
585 	return tape_do_io_free(device, request);
586 }
587 
588 /*
589  * MTUNLOAD: Rewind the tape and unload it.
590  */
591 int
592 tape_std_mtunload(struct tape_device *device, int mt_count)
593 {
594 	return tape_mtop(device, MTOFFL, mt_count);
595 }
596 
597 /*
598  * MTCOMPRESSION: used to enable compression.
599  * Sets the IDRC on/off.
600  */
601 int
602 tape_std_mtcompression(struct tape_device *device, int mt_count)
603 {
604 	struct tape_request *request;
605 
606 	if (mt_count < 0 || mt_count > 1) {
607 		DBF_EXCEPTION(6, "xcom parm\n");
608 		return -EINVAL;
609 	}
610 	request = tape_alloc_request(2, 0);
611 	if (IS_ERR(request))
612 		return PTR_ERR(request);
613 	request->op = TO_NOP;
614 	/* setup ccws */
615 	if (mt_count == 0)
616 		*device->modeset_byte &= ~0x08;
617 	else
618 		*device->modeset_byte |= 0x08;
619 	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
620 	tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
621 	/* execute it */
622 	return tape_do_io_free(device, request);
623 }
624 
625 /*
626  * Read Block
627  */
628 struct tape_request *
629 tape_std_read_block(struct tape_device *device)
630 {
631 	struct tape_request *request;
632 	struct idal_buffer **ibs;
633 	struct ccw1 *ccw;
634 	size_t count;
635 
636 	ibs = device->char_data.ibs;
637 	count = idal_buffer_array_size(ibs);
638 	request = tape_alloc_request(count + 1 /* MODE_SET_DB */, 0);
639 	if (IS_ERR(request)) {
640 		DBF_EXCEPTION(6, "xrbl fail");
641 		return request;
642 	}
643 	request->op = TO_RFO;
644 	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
645 	while (count-- > 1)
646 		ccw = tape_ccw_dc_idal(ccw, READ_FORWARD, *ibs++);
647 	tape_ccw_end_idal(ccw, READ_FORWARD, *ibs);
648 
649 	DBF_EVENT(6, "xrbl ccwg\n");
650 	return request;
651 }
652 
653 /*
654  * Write Block
655  */
656 struct tape_request *
657 tape_std_write_block(struct tape_device *device)
658 {
659 	struct tape_request *request;
660 	struct idal_buffer **ibs;
661 	struct ccw1 *ccw;
662 	size_t count;
663 
664 	count = idal_buffer_array_size(device->char_data.ibs);
665 	request = tape_alloc_request(count + 1 /* MODE_SET_DB */, 0);
666 	if (IS_ERR(request)) {
667 		DBF_EXCEPTION(6, "xwbl fail\n");
668 		return request;
669 	}
670 	request->op = TO_WRI;
671 	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
672 	ibs = device->char_data.ibs;
673 	while (count-- > 1)
674 		ccw = tape_ccw_dc_idal(ccw, WRITE_CMD, *ibs++);
675 	tape_ccw_end_idal(ccw, WRITE_CMD, *ibs);
676 
677 	DBF_EVENT(6, "xwbl ccwg\n");
678 	return request;
679 }
680 
681 /*
682  * This routine is called by frontend after an ENOSP on write
683  */
684 void
685 tape_std_process_eov(struct tape_device *device)
686 {
687 	/*
688 	 * End of volume: We have to backspace the last written record, then
689 	 * we TRY to write a tapemark and then backspace over the written TM
690 	 */
691 	if (tape_mtop(device, MTBSR, 1) == 0 &&
692 	    tape_mtop(device, MTWEOF, 1) == 0) {
693 		tape_mtop(device, MTBSR, 1);
694 	}
695 }
696 
697 EXPORT_SYMBOL(tape_std_assign);
698 EXPORT_SYMBOL(tape_std_unassign);
699 EXPORT_SYMBOL(tape_std_display);
700 EXPORT_SYMBOL(tape_std_read_block_id);
701 EXPORT_SYMBOL(tape_std_mtload);
702 EXPORT_SYMBOL(tape_std_mtsetblk);
703 EXPORT_SYMBOL(tape_std_mtreset);
704 EXPORT_SYMBOL(tape_std_mtfsf);
705 EXPORT_SYMBOL(tape_std_mtfsr);
706 EXPORT_SYMBOL(tape_std_mtbsr);
707 EXPORT_SYMBOL(tape_std_mtweof);
708 EXPORT_SYMBOL(tape_std_mtbsfm);
709 EXPORT_SYMBOL(tape_std_mtbsf);
710 EXPORT_SYMBOL(tape_std_mtfsfm);
711 EXPORT_SYMBOL(tape_std_mtrew);
712 EXPORT_SYMBOL(tape_std_mtoffl);
713 EXPORT_SYMBOL(tape_std_mtnop);
714 EXPORT_SYMBOL(tape_std_mteom);
715 EXPORT_SYMBOL(tape_std_mtreten);
716 EXPORT_SYMBOL(tape_std_mterase);
717 EXPORT_SYMBOL(tape_std_mtunload);
718 EXPORT_SYMBOL(tape_std_mtcompression);
719 EXPORT_SYMBOL(tape_std_read_block);
720 EXPORT_SYMBOL(tape_std_write_block);
721 EXPORT_SYMBOL(tape_std_process_eov);
722