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