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