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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 * 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 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