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