Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v5.7 745 lines 18 kB view raw
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 */ 35static void 36tape_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 52int 53tape_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 */ 92int 93tape_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 */ 124int 125tape_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 */ 154int 155tape_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 177int 178tape_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 */ 201int 202tape_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 */ 211int 212tape_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 */ 254int 255tape_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 */ 266int 267tape_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 */ 290int 291tape_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 */ 322int 323tape_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 */ 353int 354tape_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 */ 378int 379tape_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 */ 402int 403tape_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 */ 433int 434tape_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 */ 463int 464tape_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 */ 486int 487tape_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 */ 507int 508tape_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 */ 528int 529tape_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 */ 558int 559tape_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 */ 581int 582tape_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 */ 605int 606tape_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 */ 615int 616tape_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 */ 642struct tape_request * 643tape_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 */ 667void 668tape_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 */ 686struct tape_request * 687tape_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 */ 707void 708tape_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 720EXPORT_SYMBOL(tape_std_assign); 721EXPORT_SYMBOL(tape_std_unassign); 722EXPORT_SYMBOL(tape_std_display); 723EXPORT_SYMBOL(tape_std_read_block_id); 724EXPORT_SYMBOL(tape_std_mtload); 725EXPORT_SYMBOL(tape_std_mtsetblk); 726EXPORT_SYMBOL(tape_std_mtreset); 727EXPORT_SYMBOL(tape_std_mtfsf); 728EXPORT_SYMBOL(tape_std_mtfsr); 729EXPORT_SYMBOL(tape_std_mtbsr); 730EXPORT_SYMBOL(tape_std_mtweof); 731EXPORT_SYMBOL(tape_std_mtbsfm); 732EXPORT_SYMBOL(tape_std_mtbsf); 733EXPORT_SYMBOL(tape_std_mtfsfm); 734EXPORT_SYMBOL(tape_std_mtrew); 735EXPORT_SYMBOL(tape_std_mtoffl); 736EXPORT_SYMBOL(tape_std_mtnop); 737EXPORT_SYMBOL(tape_std_mteom); 738EXPORT_SYMBOL(tape_std_mtreten); 739EXPORT_SYMBOL(tape_std_mterase); 740EXPORT_SYMBOL(tape_std_mtunload); 741EXPORT_SYMBOL(tape_std_mtcompression); 742EXPORT_SYMBOL(tape_std_read_block); 743EXPORT_SYMBOL(tape_std_read_backward); 744EXPORT_SYMBOL(tape_std_write_block); 745EXPORT_SYMBOL(tape_std_process_eov);