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