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); 746