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 pr_fmt(fmt) "tape: " fmt 15 16 #include <linux/export.h> 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 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(struct timer_list *t) 36 { 37 struct tape_request * request = timer_container_of(request, t, 38 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 tape_request *request; 57 58 request = tape_alloc_request(2, 11); 59 if (IS_ERR(request)) 60 return PTR_ERR(request); 61 62 request->op = TO_ASSIGN; 63 tape_ccw_cc(request->cpaddr, ASSIGN, 11, request->cpdata); 64 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL); 65 66 /* 67 * The assign command sometimes blocks if the device is assigned 68 * to another host (actually this shouldn't happen but it does). 69 * So we set up a timeout for this call. 70 */ 71 timer_setup(&request->timer, tape_std_assign_timeout, 0); 72 mod_timer(&request->timer, jiffies + msecs_to_jiffies(2000)); 73 74 rc = tape_do_io_interruptible(device, request); 75 76 timer_delete_sync(&request->timer); 77 78 if (rc != 0) { 79 DBF_EVENT(3, "%08x: assign failed - device might be busy\n", 80 device->cdev_id); 81 } else { 82 DBF_EVENT(3, "%08x: Tape assigned\n", device->cdev_id); 83 } 84 tape_free_request(request); 85 return rc; 86 } 87 88 /* 89 * tape_std_unassign 90 */ 91 int 92 tape_std_unassign (struct tape_device *device) 93 { 94 int rc; 95 struct tape_request *request; 96 97 if (device->tape_state == TS_NOT_OPER) { 98 DBF_EVENT(3, "(%08x): Can't unassign device\n", 99 device->cdev_id); 100 return -EIO; 101 } 102 103 request = tape_alloc_request(2, 11); 104 if (IS_ERR(request)) 105 return PTR_ERR(request); 106 107 request->op = TO_UNASSIGN; 108 tape_ccw_cc(request->cpaddr, UNASSIGN, 11, request->cpdata); 109 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL); 110 111 if ((rc = tape_do_io(device, request)) != 0) { 112 DBF_EVENT(3, "%08x: Unassign failed\n", device->cdev_id); 113 } else { 114 DBF_EVENT(3, "%08x: Tape unassigned\n", device->cdev_id); 115 } 116 tape_free_request(request); 117 return rc; 118 } 119 120 /* 121 * Read block id. 122 */ 123 int 124 tape_std_read_block_id(struct tape_device *device, __u64 *id) 125 { 126 struct tape_request *request; 127 int rc; 128 129 request = tape_alloc_request(3, 8); 130 if (IS_ERR(request)) 131 return PTR_ERR(request); 132 request->op = TO_RBI; 133 /* setup ccws */ 134 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); 135 tape_ccw_cc(request->cpaddr + 1, READ_BLOCK_ID, 8, request->cpdata); 136 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); 137 /* execute it */ 138 rc = tape_do_io(device, request); 139 if (rc == 0) 140 /* Get result from read buffer. */ 141 *id = *(__u64 *) request->cpdata; 142 tape_free_request(request); 143 return rc; 144 } 145 146 int 147 tape_std_terminate_write(struct tape_device *device) 148 { 149 int rc; 150 151 if(device->required_tapemarks == 0) 152 return 0; 153 154 DBF_LH(5, "tape%d: terminate write %dxEOF\n", device->first_minor, 155 device->required_tapemarks); 156 157 rc = tape_mtop(device, MTWEOF, device->required_tapemarks); 158 if (rc) 159 return rc; 160 161 device->required_tapemarks = 0; 162 return tape_mtop(device, MTBSR, 1); 163 } 164 165 /* 166 * MTLOAD: Loads the tape. 167 * The default implementation just wait until the tape medium state changes 168 * to MS_LOADED. 169 */ 170 int 171 tape_std_mtload(struct tape_device *device, int count) 172 { 173 return wait_event_interruptible(device->state_change_wq, 174 (device->medium_state == MS_LOADED)); 175 } 176 177 /* 178 * MTSETBLK: Set block size. 179 */ 180 int 181 tape_std_mtsetblk(struct tape_device *device, int count) 182 { 183 int rc; 184 185 DBF_LH(6, "tape_std_mtsetblk(%d)\n", count); 186 if (count <= 0) { 187 /* 188 * Just set block_size to 0. tapechar_read/tapechar_write 189 * will realloc the idal buffer if a bigger one than the 190 * current is needed. 191 */ 192 device->char_data.block_size = 0; 193 return 0; 194 } 195 196 rc = tape_check_idalbuffer(device, count); 197 if (rc) 198 return rc; 199 200 device->char_data.block_size = count; 201 DBF_LH(6, "new blocksize is %d\n", device->char_data.block_size); 202 203 return 0; 204 } 205 206 /* 207 * MTRESET: Set block size to 0. 208 */ 209 int 210 tape_std_mtreset(struct tape_device *device, int count) 211 { 212 DBF_EVENT(6, "TCHAR:devreset:\n"); 213 device->char_data.block_size = 0; 214 return 0; 215 } 216 217 /* 218 * MTFSF: Forward space over 'count' file marks. The tape is positioned 219 * at the EOT (End of Tape) side of the file mark. 220 */ 221 int 222 tape_std_mtfsf(struct tape_device *device, int mt_count) 223 { 224 struct tape_request *request; 225 struct ccw1 *ccw; 226 227 request = tape_alloc_request(mt_count + 2, 0); 228 if (IS_ERR(request)) 229 return PTR_ERR(request); 230 request->op = TO_FSF; 231 /* setup ccws */ 232 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, 233 device->modeset_byte); 234 ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count); 235 ccw = tape_ccw_end(ccw, NOP, 0, NULL); 236 237 /* execute it */ 238 return tape_do_io_free(device, request); 239 } 240 241 /* 242 * MTFSR: Forward space over 'count' tape blocks (blocksize is set 243 * via MTSETBLK. 244 */ 245 int 246 tape_std_mtfsr(struct tape_device *device, int mt_count) 247 { 248 struct tape_request *request; 249 struct ccw1 *ccw; 250 int rc; 251 252 request = tape_alloc_request(mt_count + 2, 0); 253 if (IS_ERR(request)) 254 return PTR_ERR(request); 255 request->op = TO_FSB; 256 /* setup ccws */ 257 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, 258 device->modeset_byte); 259 ccw = tape_ccw_repeat(ccw, FORSPACEBLOCK, mt_count); 260 ccw = tape_ccw_end(ccw, NOP, 0, NULL); 261 262 /* execute it */ 263 rc = tape_do_io(device, request); 264 if (rc == 0 && request->rescnt > 0) { 265 DBF_LH(3, "FSR over tapemark\n"); 266 rc = 1; 267 } 268 tape_free_request(request); 269 270 return rc; 271 } 272 273 /* 274 * MTBSR: Backward space over 'count' tape blocks. 275 * (blocksize is set via MTSETBLK. 276 */ 277 int 278 tape_std_mtbsr(struct tape_device *device, int mt_count) 279 { 280 struct tape_request *request; 281 struct ccw1 *ccw; 282 int rc; 283 284 request = tape_alloc_request(mt_count + 2, 0); 285 if (IS_ERR(request)) 286 return PTR_ERR(request); 287 request->op = TO_BSB; 288 /* setup ccws */ 289 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, 290 device->modeset_byte); 291 ccw = tape_ccw_repeat(ccw, BACKSPACEBLOCK, mt_count); 292 ccw = tape_ccw_end(ccw, NOP, 0, NULL); 293 294 /* execute it */ 295 rc = tape_do_io(device, request); 296 if (rc == 0 && request->rescnt > 0) { 297 DBF_LH(3, "BSR over tapemark\n"); 298 rc = 1; 299 } 300 tape_free_request(request); 301 302 return rc; 303 } 304 305 /* 306 * MTWEOF: Write 'count' file marks at the current position. 307 */ 308 int 309 tape_std_mtweof(struct tape_device *device, int mt_count) 310 { 311 struct tape_request *request; 312 struct ccw1 *ccw; 313 314 request = tape_alloc_request(mt_count + 2, 0); 315 if (IS_ERR(request)) 316 return PTR_ERR(request); 317 request->op = TO_WTM; 318 /* setup ccws */ 319 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, 320 device->modeset_byte); 321 ccw = tape_ccw_repeat(ccw, WRITETAPEMARK, mt_count); 322 ccw = tape_ccw_end(ccw, NOP, 0, NULL); 323 324 /* execute it */ 325 return tape_do_io_free(device, request); 326 } 327 328 /* 329 * MTBSFM: Backward space over 'count' file marks. 330 * The tape is positioned at the BOT (Begin Of Tape) side of the 331 * last skipped file mark. 332 */ 333 int 334 tape_std_mtbsfm(struct tape_device *device, int mt_count) 335 { 336 struct tape_request *request; 337 struct ccw1 *ccw; 338 339 request = tape_alloc_request(mt_count + 2, 0); 340 if (IS_ERR(request)) 341 return PTR_ERR(request); 342 request->op = TO_BSF; 343 /* setup ccws */ 344 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, 345 device->modeset_byte); 346 ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count); 347 ccw = tape_ccw_end(ccw, NOP, 0, NULL); 348 349 /* execute it */ 350 return tape_do_io_free(device, request); 351 } 352 353 /* 354 * MTBSF: Backward space over 'count' file marks. The tape is positioned at 355 * the EOT (End of Tape) side of the last skipped file mark. 356 */ 357 int 358 tape_std_mtbsf(struct tape_device *device, int mt_count) 359 { 360 struct tape_request *request; 361 struct ccw1 *ccw; 362 int rc; 363 364 request = tape_alloc_request(mt_count + 2, 0); 365 if (IS_ERR(request)) 366 return PTR_ERR(request); 367 request->op = TO_BSF; 368 /* setup ccws */ 369 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, 370 device->modeset_byte); 371 ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count); 372 ccw = tape_ccw_end(ccw, NOP, 0, NULL); 373 /* execute it */ 374 rc = tape_do_io_free(device, request); 375 if (rc == 0) { 376 rc = tape_mtop(device, MTFSR, 1); 377 if (rc > 0) 378 rc = 0; 379 } 380 return rc; 381 } 382 383 /* 384 * MTFSFM: Forward space over 'count' file marks. 385 * The tape is positioned at the BOT (Begin Of Tape) side 386 * of the last skipped file mark. 387 */ 388 int 389 tape_std_mtfsfm(struct tape_device *device, int mt_count) 390 { 391 struct tape_request *request; 392 struct ccw1 *ccw; 393 int rc; 394 395 request = tape_alloc_request(mt_count + 2, 0); 396 if (IS_ERR(request)) 397 return PTR_ERR(request); 398 request->op = TO_FSF; 399 /* setup ccws */ 400 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, 401 device->modeset_byte); 402 ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count); 403 ccw = tape_ccw_end(ccw, NOP, 0, NULL); 404 /* execute it */ 405 rc = tape_do_io_free(device, request); 406 if (rc == 0) { 407 rc = tape_mtop(device, MTBSR, 1); 408 if (rc > 0) 409 rc = 0; 410 } 411 412 return rc; 413 } 414 415 /* 416 * MTREW: Rewind the tape. 417 */ 418 int 419 tape_std_mtrew(struct tape_device *device, int mt_count) 420 { 421 struct tape_request *request; 422 423 request = tape_alloc_request(3, 0); 424 if (IS_ERR(request)) 425 return PTR_ERR(request); 426 request->op = TO_REW; 427 /* setup ccws */ 428 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, 429 device->modeset_byte); 430 tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL); 431 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); 432 433 /* execute it */ 434 return tape_do_io_free(device, request); 435 } 436 437 /* 438 * MTOFFL: Rewind the tape and put the drive off-line. 439 * Implement 'rewind unload' 440 */ 441 int 442 tape_std_mtoffl(struct tape_device *device, int mt_count) 443 { 444 struct tape_request *request; 445 446 request = tape_alloc_request(3, 0); 447 if (IS_ERR(request)) 448 return PTR_ERR(request); 449 request->op = TO_RUN; 450 /* setup ccws */ 451 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); 452 tape_ccw_cc(request->cpaddr + 1, REWIND_UNLOAD, 0, NULL); 453 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); 454 455 /* execute it */ 456 return tape_do_io_free(device, request); 457 } 458 459 /* 460 * MTNOP: 'No operation'. 461 */ 462 int 463 tape_std_mtnop(struct tape_device *device, int mt_count) 464 { 465 struct tape_request *request; 466 467 request = tape_alloc_request(2, 0); 468 if (IS_ERR(request)) 469 return PTR_ERR(request); 470 request->op = TO_NOP; 471 /* setup ccws */ 472 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); 473 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL); 474 /* execute it */ 475 return tape_do_io_free(device, request); 476 } 477 478 /* 479 * MTEOM: positions at the end of the portion of the tape already used 480 * for recordind data. MTEOM positions after the last file mark, ready for 481 * appending another file. 482 */ 483 int 484 tape_std_mteom(struct tape_device *device, int mt_count) 485 { 486 int rc; 487 488 /* 489 * Seek from the beginning of tape (rewind). 490 */ 491 if ((rc = tape_mtop(device, MTREW, 1)) < 0) 492 return rc; 493 494 /* 495 * The logical end of volume is given by two sewuential tapemarks. 496 * Look for this by skipping to the next file (over one tapemark) 497 * and then test for another one (fsr returns 1 if a tapemark was 498 * encountered). 499 */ 500 do { 501 if ((rc = tape_mtop(device, MTFSF, 1)) < 0) 502 return rc; 503 if ((rc = tape_mtop(device, MTFSR, 1)) < 0) 504 return rc; 505 } while (rc == 0); 506 507 return tape_mtop(device, MTBSR, 1); 508 } 509 510 /* 511 * MTRETEN: Retension the tape, i.e. forward space to end of tape and rewind. 512 */ 513 int 514 tape_std_mtreten(struct tape_device *device, int mt_count) 515 { 516 struct tape_request *request; 517 518 request = tape_alloc_request(4, 0); 519 if (IS_ERR(request)) 520 return PTR_ERR(request); 521 request->op = TO_FSF; 522 /* setup ccws */ 523 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); 524 tape_ccw_cc(request->cpaddr + 1,FORSPACEFILE, 0, NULL); 525 tape_ccw_cc(request->cpaddr + 2, NOP, 0, NULL); 526 tape_ccw_end(request->cpaddr + 3, CCW_CMD_TIC, 0, request->cpaddr); 527 /* execute it, MTRETEN rc gets ignored */ 528 tape_do_io_interruptible(device, request); 529 tape_free_request(request); 530 return tape_mtop(device, MTREW, 1); 531 } 532 533 /* 534 * MTERASE: erases the tape. 535 */ 536 int 537 tape_std_mterase(struct tape_device *device, int mt_count) 538 { 539 struct tape_request *request; 540 541 request = tape_alloc_request(6, 0); 542 if (IS_ERR(request)) 543 return PTR_ERR(request); 544 request->op = TO_DSE; 545 /* setup ccws */ 546 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); 547 tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL); 548 tape_ccw_cc(request->cpaddr + 2, ERASE_GAP, 0, NULL); 549 tape_ccw_cc(request->cpaddr + 3, DATA_SEC_ERASE, 0, NULL); 550 tape_ccw_cc(request->cpaddr + 4, REWIND, 0, NULL); 551 tape_ccw_end(request->cpaddr + 5, NOP, 0, NULL); 552 553 /* execute it */ 554 return tape_do_io_free(device, request); 555 } 556 557 /* 558 * MTUNLOAD: Rewind the tape and unload it. 559 */ 560 int 561 tape_std_mtunload(struct tape_device *device, int mt_count) 562 { 563 return tape_mtop(device, MTOFFL, mt_count); 564 } 565 566 /* 567 * MTCOMPRESSION: used to enable compression. 568 * Sets the IDRC on/off. 569 */ 570 int 571 tape_std_mtcompression(struct tape_device *device, int mt_count) 572 { 573 struct tape_request *request; 574 575 if (mt_count < 0 || mt_count > 1) { 576 DBF_EXCEPTION(6, "xcom parm\n"); 577 return -EINVAL; 578 } 579 request = tape_alloc_request(2, 0); 580 if (IS_ERR(request)) 581 return PTR_ERR(request); 582 request->op = TO_NOP; 583 /* setup ccws */ 584 if (mt_count == 0) 585 *device->modeset_byte &= ~0x08; 586 else 587 *device->modeset_byte |= 0x08; 588 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); 589 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL); 590 /* execute it */ 591 return tape_do_io_free(device, request); 592 } 593 594 /* 595 * Read Block 596 */ 597 struct tape_request * 598 tape_std_read_block(struct tape_device *device) 599 { 600 struct tape_request *request; 601 struct idal_buffer **ibs; 602 struct ccw1 *ccw; 603 size_t count; 604 605 ibs = device->char_data.ibs; 606 count = idal_buffer_array_size(ibs); 607 request = tape_alloc_request(count + 1 /* MODE_SET_DB */, 0); 608 if (IS_ERR(request)) { 609 DBF_EXCEPTION(6, "xrbl fail"); 610 return request; 611 } 612 request->op = TO_RFO; 613 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); 614 while (count-- > 1) 615 ccw = tape_ccw_dc_idal(ccw, READ_FORWARD, *ibs++); 616 tape_ccw_end_idal(ccw, READ_FORWARD, *ibs); 617 618 DBF_EVENT(6, "xrbl ccwg\n"); 619 return request; 620 } 621 622 /* 623 * Write Block 624 */ 625 struct tape_request * 626 tape_std_write_block(struct tape_device *device) 627 { 628 struct tape_request *request; 629 struct idal_buffer **ibs; 630 struct ccw1 *ccw; 631 size_t count; 632 633 count = idal_buffer_array_size(device->char_data.ibs); 634 request = tape_alloc_request(count + 1 /* MODE_SET_DB */, 0); 635 if (IS_ERR(request)) { 636 DBF_EXCEPTION(6, "xwbl fail\n"); 637 return request; 638 } 639 request->op = TO_WRI; 640 ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); 641 ibs = device->char_data.ibs; 642 while (count-- > 1) 643 ccw = tape_ccw_dc_idal(ccw, WRITE_CMD, *ibs++); 644 tape_ccw_end_idal(ccw, WRITE_CMD, *ibs); 645 646 DBF_EVENT(6, "xwbl ccwg\n"); 647 return request; 648 } 649 650 /* 651 * This routine is called by frontend after an ENOSP on write 652 */ 653 void 654 tape_std_process_eov(struct tape_device *device) 655 { 656 /* 657 * End of volume: We have to backspace the last written record, then 658 * we TRY to write a tapemark and then backspace over the written TM 659 */ 660 if (tape_mtop(device, MTBSR, 1) == 0 && 661 tape_mtop(device, MTWEOF, 1) == 0) { 662 tape_mtop(device, MTBSR, 1); 663 } 664 } 665 666 EXPORT_SYMBOL(tape_std_assign); 667 EXPORT_SYMBOL(tape_std_unassign); 668 EXPORT_SYMBOL(tape_std_read_block_id); 669 EXPORT_SYMBOL(tape_std_mtload); 670 EXPORT_SYMBOL(tape_std_mtsetblk); 671 EXPORT_SYMBOL(tape_std_mtreset); 672 EXPORT_SYMBOL(tape_std_mtfsf); 673 EXPORT_SYMBOL(tape_std_mtfsr); 674 EXPORT_SYMBOL(tape_std_mtbsr); 675 EXPORT_SYMBOL(tape_std_mtweof); 676 EXPORT_SYMBOL(tape_std_mtbsfm); 677 EXPORT_SYMBOL(tape_std_mtbsf); 678 EXPORT_SYMBOL(tape_std_mtfsfm); 679 EXPORT_SYMBOL(tape_std_mtrew); 680 EXPORT_SYMBOL(tape_std_mtoffl); 681 EXPORT_SYMBOL(tape_std_mtnop); 682 EXPORT_SYMBOL(tape_std_mteom); 683 EXPORT_SYMBOL(tape_std_mtreten); 684 EXPORT_SYMBOL(tape_std_mterase); 685 EXPORT_SYMBOL(tape_std_mtunload); 686 EXPORT_SYMBOL(tape_std_mtcompression); 687 EXPORT_SYMBOL(tape_std_read_block); 688 EXPORT_SYMBOL(tape_std_write_block); 689 EXPORT_SYMBOL(tape_std_process_eov); 690