1233 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * tape device discipline for 3480/3490 tapes.4 *5 * Copyright IBM Corp. 2001, 20096 * Author(s): Carsten Otte <cotte@de.ibm.com>7 * Tuan Ngo-Anh <ngoanh@de.ibm.com>8 * Martin Schwidefsky <schwidefsky@de.ibm.com>9 */10 11#define KMSG_COMPONENT "tape_34xx"12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt13 14#include <linux/module.h>15#include <linux/init.h>16#include <linux/bio.h>17#include <linux/workqueue.h>18#include <linux/slab.h>19 20#define TAPE_DBF_AREA tape_34xx_dbf21 22#include "tape.h"23#include "tape_std.h"24 25/*26 * Pointer to debug area.27 */28debug_info_t *TAPE_DBF_AREA = NULL;29EXPORT_SYMBOL(TAPE_DBF_AREA);30 31#define TAPE34XX_FMT_3480 032#define TAPE34XX_FMT_3480_2_XF 133#define TAPE34XX_FMT_3480_XF 234 35struct tape_34xx_block_id {36 unsigned int wrap : 1;37 unsigned int segment : 7;38 unsigned int format : 2;39 unsigned int block : 22;40};41 42/*43 * A list of block ID's is used to faster seek blocks.44 */45struct tape_34xx_sbid {46 struct list_head list;47 struct tape_34xx_block_id bid;48};49 50static void tape_34xx_delete_sbid_from(struct tape_device *, int);51 52/*53 * Medium sense for 34xx tapes. There is no 'real' medium sense call.54 * So we just do a normal sense.55 */56static void __tape_34xx_medium_sense(struct tape_request *request)57{58 struct tape_device *device = request->device;59 unsigned char *sense;60 61 if (request->rc == 0) {62 sense = request->cpdata;63 64 /*65 * This isn't quite correct. But since INTERVENTION_REQUIRED66 * means that the drive is 'neither ready nor on-line' it is67 * only slightly inaccurate to say there is no tape loaded if68 * the drive isn't online...69 */70 if (sense[0] & SENSE_INTERVENTION_REQUIRED)71 tape_med_state_set(device, MS_UNLOADED);72 else73 tape_med_state_set(device, MS_LOADED);74 75 if (sense[1] & SENSE_WRITE_PROTECT)76 device->tape_generic_status |= GMT_WR_PROT(~0);77 else78 device->tape_generic_status &= ~GMT_WR_PROT(~0);79 } else80 DBF_EVENT(4, "tape_34xx: medium sense failed with rc=%d\n",81 request->rc);82 tape_free_request(request);83}84 85static int tape_34xx_medium_sense(struct tape_device *device)86{87 struct tape_request *request;88 int rc;89 90 request = tape_alloc_request(1, 32);91 if (IS_ERR(request)) {92 DBF_EXCEPTION(6, "MSEN fail\n");93 return PTR_ERR(request);94 }95 96 request->op = TO_MSEN;97 tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata);98 rc = tape_do_io_interruptible(device, request);99 __tape_34xx_medium_sense(request);100 return rc;101}102 103static void tape_34xx_medium_sense_async(struct tape_device *device)104{105 struct tape_request *request;106 107 request = tape_alloc_request(1, 32);108 if (IS_ERR(request)) {109 DBF_EXCEPTION(6, "MSEN fail\n");110 return;111 }112 113 request->op = TO_MSEN;114 tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata);115 request->callback = (void *) __tape_34xx_medium_sense;116 request->callback_data = NULL;117 tape_do_io_async(device, request);118}119 120struct tape_34xx_work {121 struct tape_device *device;122 enum tape_op op;123 struct work_struct work;124};125 126/*127 * These functions are currently used only to schedule a medium_sense for128 * later execution. This is because we get an interrupt whenever a medium129 * is inserted but cannot call tape_do_io* from an interrupt context.130 * Maybe that's useful for other actions we want to start from the131 * interrupt handler.132 * Note: the work handler is called by the system work queue. The tape133 * commands started by the handler need to be asynchrounous, otherwise134 * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq).135 */136static void137tape_34xx_work_handler(struct work_struct *work)138{139 struct tape_34xx_work *p =140 container_of(work, struct tape_34xx_work, work);141 struct tape_device *device = p->device;142 143 switch(p->op) {144 case TO_MSEN:145 tape_34xx_medium_sense_async(device);146 break;147 default:148 DBF_EVENT(3, "T34XX: internal error: unknown work\n");149 }150 tape_put_device(device);151 kfree(p);152}153 154static int155tape_34xx_schedule_work(struct tape_device *device, enum tape_op op)156{157 struct tape_34xx_work *p;158 159 if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL)160 return -ENOMEM;161 162 INIT_WORK(&p->work, tape_34xx_work_handler);163 164 p->device = tape_get_device(device);165 p->op = op;166 167 schedule_work(&p->work);168 return 0;169}170 171/*172 * Done Handler is called when dev stat = DEVICE-END (successful operation)173 */174static inline int175tape_34xx_done(struct tape_request *request)176{177 DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]);178 179 switch (request->op) {180 case TO_DSE:181 case TO_RUN:182 case TO_WRI:183 case TO_WTM:184 case TO_ASSIGN:185 case TO_UNASSIGN:186 tape_34xx_delete_sbid_from(request->device, 0);187 break;188 default:189 ;190 }191 return TAPE_IO_SUCCESS;192}193 194static inline int195tape_34xx_erp_failed(struct tape_request *request, int rc)196{197 DBF_EVENT(3, "Error recovery failed for %s (RC=%d)\n",198 tape_op_verbose[request->op], rc);199 return rc;200}201 202static inline int203tape_34xx_erp_succeeded(struct tape_request *request)204{205 DBF_EVENT(3, "Error Recovery successful for %s\n",206 tape_op_verbose[request->op]);207 return tape_34xx_done(request);208}209 210static inline int211tape_34xx_erp_retry(struct tape_request *request)212{213 DBF_EVENT(3, "xerp retr %s\n", tape_op_verbose[request->op]);214 return TAPE_IO_RETRY;215}216 217/*218 * This function is called, when no request is outstanding and we get an219 * interrupt220 */221static int222tape_34xx_unsolicited_irq(struct tape_device *device, struct irb *irb)223{224 if (irb->scsw.cmd.dstat == 0x85) { /* READY */225 /* A medium was inserted in the drive. */226 DBF_EVENT(6, "xuud med\n");227 tape_34xx_delete_sbid_from(device, 0);228 tape_34xx_schedule_work(device, TO_MSEN);229 } else {230 DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);231 tape_dump_sense_dbf(device, NULL, irb);232 }233 return TAPE_IO_SUCCESS;234}235 236/*237 * Read Opposite Error Recovery Function:238 * Used, when Read Forward does not work239 */240static int241tape_34xx_erp_read_opposite(struct tape_device *device,242 struct tape_request *request)243{244 if (request->op == TO_RFO) {245 /*246 * We did read forward, but the data could not be read247 * *correctly*. We transform the request to a read backward248 * and try again.249 */250 tape_std_read_backward(device, request);251 return tape_34xx_erp_retry(request);252 }253 254 /*255 * We tried to read forward and backward, but hat no256 * success -> failed.257 */258 return tape_34xx_erp_failed(request, -EIO);259}260 261static int262tape_34xx_erp_bug(struct tape_device *device, struct tape_request *request,263 struct irb *irb, int no)264{265 if (request->op != TO_ASSIGN) {266 dev_err(&device->cdev->dev, "An unexpected condition %d "267 "occurred in tape error recovery\n", no);268 tape_dump_sense_dbf(device, request, irb);269 }270 return tape_34xx_erp_failed(request, -EIO);271}272 273/*274 * Handle data overrun between cu and drive. The channel speed might275 * be too slow.276 */277static int278tape_34xx_erp_overrun(struct tape_device *device, struct tape_request *request,279 struct irb *irb)280{281 if (irb->ecw[3] == 0x40) {282 dev_warn (&device->cdev->dev, "A data overrun occurred between"283 " the control unit and tape unit\n");284 return tape_34xx_erp_failed(request, -EIO);285 }286 return tape_34xx_erp_bug(device, request, irb, -1);287}288 289/*290 * Handle record sequence error.291 */292static int293tape_34xx_erp_sequence(struct tape_device *device,294 struct tape_request *request, struct irb *irb)295{296 if (irb->ecw[3] == 0x41) {297 /*298 * cu detected incorrect block-id sequence on tape.299 */300 dev_warn (&device->cdev->dev, "The block ID sequence on the "301 "tape is incorrect\n");302 return tape_34xx_erp_failed(request, -EIO);303 }304 /*305 * Record sequence error bit is set, but erpa does not306 * show record sequence error.307 */308 return tape_34xx_erp_bug(device, request, irb, -2);309}310 311/*312 * This function analyses the tape's sense-data in case of a unit-check.313 * If possible, it tries to recover from the error. Else the user is314 * informed about the problem.315 */316static int317tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,318 struct irb *irb)319{320 int inhibit_cu_recovery;321 __u8* sense;322 323 inhibit_cu_recovery = (*device->modeset_byte & 0x80) ? 1 : 0;324 sense = irb->ecw;325 326 if (327 sense[0] & SENSE_COMMAND_REJECT &&328 sense[1] & SENSE_WRITE_PROTECT329 ) {330 if (331 request->op == TO_DSE ||332 request->op == TO_WRI ||333 request->op == TO_WTM334 ) {335 /* medium is write protected */336 return tape_34xx_erp_failed(request, -EACCES);337 } else {338 return tape_34xx_erp_bug(device, request, irb, -3);339 }340 }341 342 /*343 * Special cases for various tape-states when reaching344 * end of recorded area345 *346 * FIXME: Maybe a special case of the special case:347 * sense[0] == SENSE_EQUIPMENT_CHECK &&348 * sense[1] == SENSE_DRIVE_ONLINE &&349 * sense[3] == 0x47 (Volume Fenced)350 *351 * This was caused by continued FSF or FSR after an352 * 'End Of Data'.353 */354 if ((355 sense[0] == SENSE_DATA_CHECK ||356 sense[0] == SENSE_EQUIPMENT_CHECK ||357 sense[0] == (SENSE_EQUIPMENT_CHECK | SENSE_DEFERRED_UNIT_CHECK)358 ) && (359 sense[1] == SENSE_DRIVE_ONLINE ||360 sense[1] == (SENSE_BEGINNING_OF_TAPE | SENSE_WRITE_MODE)361 )) {362 switch (request->op) {363 /*364 * sense[0] == SENSE_DATA_CHECK &&365 * sense[1] == SENSE_DRIVE_ONLINE366 * sense[3] == 0x36 (End Of Data)367 *368 * Further seeks might return a 'Volume Fenced'.369 */370 case TO_FSF:371 case TO_FSB:372 /* Trying to seek beyond end of recorded area */373 return tape_34xx_erp_failed(request, -ENOSPC);374 case TO_BSB:375 return tape_34xx_erp_retry(request);376 377 /*378 * sense[0] == SENSE_DATA_CHECK &&379 * sense[1] == SENSE_DRIVE_ONLINE &&380 * sense[3] == 0x36 (End Of Data)381 */382 case TO_LBL:383 /* Block could not be located. */384 tape_34xx_delete_sbid_from(device, 0);385 return tape_34xx_erp_failed(request, -EIO);386 387 case TO_RFO:388 /* Read beyond end of recorded area -> 0 bytes read */389 return tape_34xx_erp_failed(request, 0);390 391 /*392 * sense[0] == SENSE_EQUIPMENT_CHECK &&393 * sense[1] == SENSE_DRIVE_ONLINE &&394 * sense[3] == 0x38 (Physical End Of Volume)395 */396 case TO_WRI:397 /* Writing at physical end of volume */398 return tape_34xx_erp_failed(request, -ENOSPC);399 default:400 return tape_34xx_erp_failed(request, 0);401 }402 }403 404 /* Sensing special bits */405 if (sense[0] & SENSE_BUS_OUT_CHECK)406 return tape_34xx_erp_retry(request);407 408 if (sense[0] & SENSE_DATA_CHECK) {409 /*410 * hardware failure, damaged tape or improper411 * operating conditions412 */413 switch (sense[3]) {414 case 0x23:415 /* a read data check occurred */416 if ((sense[2] & SENSE_TAPE_SYNC_MODE) ||417 inhibit_cu_recovery)418 // data check is not permanent, may be419 // recovered. We always use async-mode with420 // cu-recovery, so this should *never* happen.421 return tape_34xx_erp_bug(device, request,422 irb, -4);423 424 /* data check is permanent, CU recovery has failed */425 dev_warn (&device->cdev->dev, "A read error occurred "426 "that cannot be recovered\n");427 return tape_34xx_erp_failed(request, -EIO);428 case 0x25:429 // a write data check occurred430 if ((sense[2] & SENSE_TAPE_SYNC_MODE) ||431 inhibit_cu_recovery)432 // data check is not permanent, may be433 // recovered. We always use async-mode with434 // cu-recovery, so this should *never* happen.435 return tape_34xx_erp_bug(device, request,436 irb, -5);437 438 // data check is permanent, cu-recovery has failed439 dev_warn (&device->cdev->dev, "A write error on the "440 "tape cannot be recovered\n");441 return tape_34xx_erp_failed(request, -EIO);442 case 0x26:443 /* Data Check (read opposite) occurred. */444 return tape_34xx_erp_read_opposite(device, request);445 case 0x28:446 /* ID-Mark at tape start couldn't be written */447 dev_warn (&device->cdev->dev, "Writing the ID-mark "448 "failed\n");449 return tape_34xx_erp_failed(request, -EIO);450 case 0x31:451 /* Tape void. Tried to read beyond end of device. */452 dev_warn (&device->cdev->dev, "Reading the tape beyond"453 " the end of the recorded area failed\n");454 return tape_34xx_erp_failed(request, -ENOSPC);455 case 0x41:456 /* Record sequence error. */457 dev_warn (&device->cdev->dev, "The tape contains an "458 "incorrect block ID sequence\n");459 return tape_34xx_erp_failed(request, -EIO);460 default:461 /* all data checks for 3480 should result in one of462 * the above erpa-codes. For 3490, other data-check463 * conditions do exist. */464 if (device->cdev->id.driver_info == tape_3480)465 return tape_34xx_erp_bug(device, request,466 irb, -6);467 }468 }469 470 if (sense[0] & SENSE_OVERRUN)471 return tape_34xx_erp_overrun(device, request, irb);472 473 if (sense[1] & SENSE_RECORD_SEQUENCE_ERR)474 return tape_34xx_erp_sequence(device, request, irb);475 476 /* Sensing erpa codes */477 switch (sense[3]) {478 case 0x00:479 /* Unit check with erpa code 0. Report and ignore. */480 return TAPE_IO_SUCCESS;481 case 0x21:482 /*483 * Data streaming not operational. CU will switch to484 * interlock mode. Reissue the command.485 */486 return tape_34xx_erp_retry(request);487 case 0x22:488 /*489 * Path equipment check. Might be drive adapter error, buffer490 * error on the lower interface, internal path not usable,491 * or error during cartridge load.492 */493 dev_warn (&device->cdev->dev, "A path equipment check occurred"494 " for the tape device\n");495 return tape_34xx_erp_failed(request, -EIO);496 case 0x24:497 /*498 * Load display check. Load display was command was issued,499 * but the drive is displaying a drive check message. Can500 * be threated as "device end".501 */502 return tape_34xx_erp_succeeded(request);503 case 0x27:504 /*505 * Command reject. May indicate illegal channel program or506 * buffer over/underrun. Since all channel programs are507 * issued by this driver and ought be correct, we assume a508 * over/underrun situation and retry the channel program.509 */510 return tape_34xx_erp_retry(request);511 case 0x29:512 /*513 * Function incompatible. Either the tape is idrc compressed514 * but the hardware isn't capable to do idrc, or a perform515 * subsystem func is issued and the CU is not on-line.516 */517 return tape_34xx_erp_failed(request, -EIO);518 case 0x2a:519 /*520 * Unsolicited environmental data. An internal counter521 * overflows, we can ignore this and reissue the cmd.522 */523 return tape_34xx_erp_retry(request);524 case 0x2b:525 /*526 * Environmental data present. Indicates either unload527 * completed ok or read buffered log command completed ok.528 */529 if (request->op == TO_RUN) {530 /* Rewind unload completed ok. */531 tape_med_state_set(device, MS_UNLOADED);532 return tape_34xx_erp_succeeded(request);533 }534 /* tape_34xx doesn't use read buffered log commands. */535 return tape_34xx_erp_bug(device, request, irb, sense[3]);536 case 0x2c:537 /*538 * Permanent equipment check. CU has tried recovery, but539 * did not succeed.540 */541 return tape_34xx_erp_failed(request, -EIO);542 case 0x2d:543 /* Data security erase failure. */544 if (request->op == TO_DSE)545 return tape_34xx_erp_failed(request, -EIO);546 /* Data security erase failure, but no such command issued. */547 return tape_34xx_erp_bug(device, request, irb, sense[3]);548 case 0x2e:549 /*550 * Not capable. This indicates either that the drive fails551 * reading the format id mark or that format specified552 * is not supported by the drive.553 */554 dev_warn (&device->cdev->dev, "The tape unit cannot process "555 "the tape format\n");556 return tape_34xx_erp_failed(request, -EMEDIUMTYPE);557 case 0x30:558 /* The medium is write protected. */559 dev_warn (&device->cdev->dev, "The tape medium is write-"560 "protected\n");561 return tape_34xx_erp_failed(request, -EACCES);562 case 0x32:563 // Tension loss. We cannot recover this, it's an I/O error.564 dev_warn (&device->cdev->dev, "The tape does not have the "565 "required tape tension\n");566 return tape_34xx_erp_failed(request, -EIO);567 case 0x33:568 /*569 * Load Failure. The cartridge was not inserted correctly or570 * the tape is not threaded correctly.571 */572 dev_warn (&device->cdev->dev, "The tape unit failed to load"573 " the cartridge\n");574 tape_34xx_delete_sbid_from(device, 0);575 return tape_34xx_erp_failed(request, -EIO);576 case 0x34:577 /*578 * Unload failure. The drive cannot maintain tape tension579 * and control tape movement during an unload operation.580 */581 dev_warn (&device->cdev->dev, "Automatic unloading of the tape"582 " cartridge failed\n");583 if (request->op == TO_RUN)584 return tape_34xx_erp_failed(request, -EIO);585 return tape_34xx_erp_bug(device, request, irb, sense[3]);586 case 0x35:587 /*588 * Drive equipment check. One of the following:589 * - cu cannot recover from a drive detected error590 * - a check code message is shown on drive display591 * - the cartridge loader does not respond correctly592 * - a failure occurs during an index, load, or unload cycle593 */594 dev_warn (&device->cdev->dev, "An equipment check has occurred"595 " on the tape unit\n");596 return tape_34xx_erp_failed(request, -EIO);597 case 0x36:598 if (device->cdev->id.driver_info == tape_3490)599 /* End of data. */600 return tape_34xx_erp_failed(request, -EIO);601 /* This erpa is reserved for 3480 */602 return tape_34xx_erp_bug(device, request, irb, sense[3]);603 case 0x37:604 /*605 * Tape length error. The tape is shorter than reported in606 * the beginning-of-tape data.607 */608 dev_warn (&device->cdev->dev, "The tape information states an"609 " incorrect length\n");610 return tape_34xx_erp_failed(request, -EIO);611 case 0x38:612 /*613 * Physical end of tape. A read/write operation reached614 * the physical end of tape.615 */616 if (request->op==TO_WRI ||617 request->op==TO_DSE ||618 request->op==TO_WTM)619 return tape_34xx_erp_failed(request, -ENOSPC);620 return tape_34xx_erp_failed(request, -EIO);621 case 0x39:622 /* Backward at Beginning of tape. */623 return tape_34xx_erp_failed(request, -EIO);624 case 0x3a:625 /* Drive switched to not ready. */626 dev_warn (&device->cdev->dev, "The tape unit is not ready\n");627 return tape_34xx_erp_failed(request, -EIO);628 case 0x3b:629 /* Manual rewind or unload. This causes an I/O error. */630 dev_warn (&device->cdev->dev, "The tape medium has been "631 "rewound or unloaded manually\n");632 tape_34xx_delete_sbid_from(device, 0);633 return tape_34xx_erp_failed(request, -EIO);634 case 0x42:635 /*636 * Degraded mode. A condition that can cause degraded637 * performance is detected.638 */639 dev_warn (&device->cdev->dev, "The tape subsystem is running "640 "in degraded mode\n");641 return tape_34xx_erp_retry(request);642 case 0x43:643 /* Drive not ready. */644 tape_34xx_delete_sbid_from(device, 0);645 tape_med_state_set(device, MS_UNLOADED);646 /* Some commands commands are successful even in this case */647 if (sense[1] & SENSE_DRIVE_ONLINE) {648 switch(request->op) {649 case TO_ASSIGN:650 case TO_UNASSIGN:651 case TO_DIS:652 case TO_NOP:653 return tape_34xx_done(request);654 break;655 default:656 break;657 }658 }659 return tape_34xx_erp_failed(request, -ENOMEDIUM);660 case 0x44:661 /* Locate Block unsuccessful. */662 if (request->op != TO_BLOCK && request->op != TO_LBL)663 /* No locate block was issued. */664 return tape_34xx_erp_bug(device, request,665 irb, sense[3]);666 return tape_34xx_erp_failed(request, -EIO);667 case 0x45:668 /* The drive is assigned to a different channel path. */669 dev_warn (&device->cdev->dev, "The tape unit is already "670 "assigned\n");671 return tape_34xx_erp_failed(request, -EIO);672 case 0x46:673 /*674 * Drive not on-line. Drive may be switched offline,675 * the power supply may be switched off or676 * the drive address may not be set correctly.677 */678 dev_warn (&device->cdev->dev, "The tape unit is not online\n");679 return tape_34xx_erp_failed(request, -EIO);680 case 0x47:681 /* Volume fenced. CU reports volume integrity is lost. */682 dev_warn (&device->cdev->dev, "The control unit has fenced "683 "access to the tape volume\n");684 tape_34xx_delete_sbid_from(device, 0);685 return tape_34xx_erp_failed(request, -EIO);686 case 0x48:687 /* Log sense data and retry request. */688 return tape_34xx_erp_retry(request);689 case 0x49:690 /* Bus out check. A parity check error on the bus was found. */691 dev_warn (&device->cdev->dev, "A parity error occurred on the "692 "tape bus\n");693 return tape_34xx_erp_failed(request, -EIO);694 case 0x4a:695 /* Control unit erp failed. */696 dev_warn (&device->cdev->dev, "I/O error recovery failed on "697 "the tape control unit\n");698 return tape_34xx_erp_failed(request, -EIO);699 case 0x4b:700 /*701 * CU and drive incompatible. The drive requests micro-program702 * patches, which are not available on the CU.703 */704 dev_warn (&device->cdev->dev, "The tape unit requires a "705 "firmware update\n");706 return tape_34xx_erp_failed(request, -EIO);707 case 0x4c:708 /*709 * Recovered Check-One failure. Cu develops a hardware error,710 * but is able to recover.711 */712 return tape_34xx_erp_retry(request);713 case 0x4d:714 if (device->cdev->id.driver_info == tape_3490)715 /*716 * Resetting event received. Since the driver does717 * not support resetting event recovery (which has to718 * be handled by the I/O Layer), retry our command.719 */720 return tape_34xx_erp_retry(request);721 /* This erpa is reserved for 3480. */722 return tape_34xx_erp_bug(device, request, irb, sense[3]);723 case 0x4e:724 if (device->cdev->id.driver_info == tape_3490) {725 /*726 * Maximum block size exceeded. This indicates, that727 * the block to be written is larger than allowed for728 * buffered mode.729 */730 dev_warn (&device->cdev->dev, "The maximum block size"731 " for buffered mode is exceeded\n");732 return tape_34xx_erp_failed(request, -ENOBUFS);733 }734 /* This erpa is reserved for 3480. */735 return tape_34xx_erp_bug(device, request, irb, sense[3]);736 case 0x50:737 /*738 * Read buffered log (Overflow). CU is running in extended739 * buffered log mode, and a counter overflows. This should740 * never happen, since we're never running in extended741 * buffered log mode.742 */743 return tape_34xx_erp_retry(request);744 case 0x51:745 /*746 * Read buffered log (EOV). EOF processing occurs while the747 * CU is in extended buffered log mode. This should never748 * happen, since we're never running in extended buffered749 * log mode.750 */751 return tape_34xx_erp_retry(request);752 case 0x52:753 /* End of Volume complete. Rewind unload completed ok. */754 if (request->op == TO_RUN) {755 tape_med_state_set(device, MS_UNLOADED);756 tape_34xx_delete_sbid_from(device, 0);757 return tape_34xx_erp_succeeded(request);758 }759 return tape_34xx_erp_bug(device, request, irb, sense[3]);760 case 0x53:761 /* Global command intercept. */762 return tape_34xx_erp_retry(request);763 case 0x54:764 /* Channel interface recovery (temporary). */765 return tape_34xx_erp_retry(request);766 case 0x55:767 /* Channel interface recovery (permanent). */768 dev_warn (&device->cdev->dev, "A channel interface error cannot be"769 " recovered\n");770 return tape_34xx_erp_failed(request, -EIO);771 case 0x56:772 /* Channel protocol error. */773 dev_warn (&device->cdev->dev, "A channel protocol error "774 "occurred\n");775 return tape_34xx_erp_failed(request, -EIO);776 case 0x57:777 /*778 * 3480: Attention intercept.779 * 3490: Global status intercept.780 */781 return tape_34xx_erp_retry(request);782 case 0x5a:783 /*784 * Tape length incompatible. The tape inserted is too long,785 * which could cause damage to the tape or the drive.786 */787 dev_warn (&device->cdev->dev, "The tape unit does not support "788 "the tape length\n");789 return tape_34xx_erp_failed(request, -EIO);790 case 0x5b:791 /* Format 3480 XF incompatible */792 if (sense[1] & SENSE_BEGINNING_OF_TAPE)793 /* The tape will get overwritten. */794 return tape_34xx_erp_retry(request);795 dev_warn (&device->cdev->dev, "The tape unit does not support"796 " format 3480 XF\n");797 return tape_34xx_erp_failed(request, -EIO);798 case 0x5c:799 /* Format 3480-2 XF incompatible */800 dev_warn (&device->cdev->dev, "The tape unit does not support tape "801 "format 3480-2 XF\n");802 return tape_34xx_erp_failed(request, -EIO);803 case 0x5d:804 /* Tape length violation. */805 dev_warn (&device->cdev->dev, "The tape unit does not support"806 " the current tape length\n");807 return tape_34xx_erp_failed(request, -EMEDIUMTYPE);808 case 0x5e:809 /* Compaction algorithm incompatible. */810 dev_warn (&device->cdev->dev, "The tape unit does not support"811 " the compaction algorithm\n");812 return tape_34xx_erp_failed(request, -EMEDIUMTYPE);813 814 /* The following erpas should have been covered earlier. */815 case 0x23: /* Read data check. */816 case 0x25: /* Write data check. */817 case 0x26: /* Data check (read opposite). */818 case 0x28: /* Write id mark check. */819 case 0x31: /* Tape void. */820 case 0x40: /* Overrun error. */821 case 0x41: /* Record sequence error. */822 /* All other erpas are reserved for future use. */823 default:824 return tape_34xx_erp_bug(device, request, irb, sense[3]);825 }826}827 828/*829 * 3480/3490 interrupt handler830 */831static int832tape_34xx_irq(struct tape_device *device, struct tape_request *request,833 struct irb *irb)834{835 if (request == NULL)836 return tape_34xx_unsolicited_irq(device, irb);837 838 if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) &&839 (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&840 (request->op == TO_WRI)) {841 /* Write at end of volume */842 return tape_34xx_erp_failed(request, -ENOSPC);843 }844 845 if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)846 return tape_34xx_unit_check(device, request, irb);847 848 if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) {849 /*850 * A unit exception occurs on skipping over a tapemark block.851 */852 if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) {853 if (request->op == TO_BSB || request->op == TO_FSB)854 request->rescnt++;855 else856 DBF_EVENT(5, "Unit Exception!\n");857 }858 return tape_34xx_done(request);859 }860 861 DBF_EVENT(6, "xunknownirq\n");862 tape_dump_sense_dbf(device, request, irb);863 return TAPE_IO_STOP;864}865 866/*867 * ioctl_overload868 */869static int870tape_34xx_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg)871{872 if (cmd == TAPE390_DISPLAY) {873 struct display_struct disp;874 875 if (copy_from_user(&disp, (char __user *) arg, sizeof(disp)) != 0)876 return -EFAULT;877 878 return tape_std_display(device, &disp);879 } else880 return -EINVAL;881}882 883static inline void884tape_34xx_append_new_sbid(struct tape_34xx_block_id bid, struct list_head *l)885{886 struct tape_34xx_sbid * new_sbid;887 888 new_sbid = kmalloc(sizeof(*new_sbid), GFP_ATOMIC);889 if (!new_sbid)890 return;891 892 new_sbid->bid = bid;893 list_add(&new_sbid->list, l);894}895 896/*897 * Build up the search block ID list. The block ID consists of a logical898 * block number and a hardware specific part. The hardware specific part899 * helps the tape drive to speed up searching for a specific block.900 */901static void902tape_34xx_add_sbid(struct tape_device *device, struct tape_34xx_block_id bid)903{904 struct list_head * sbid_list;905 struct tape_34xx_sbid * sbid;906 struct list_head * l;907 908 /*909 * immediately return if there is no list at all or the block to add910 * is located in segment 1 of wrap 0 because this position is used911 * if no hardware position data is supplied.912 */913 sbid_list = (struct list_head *) device->discdata;914 if (!sbid_list || (bid.segment < 2 && bid.wrap == 0))915 return;916 917 /*918 * Search the position where to insert the new entry. Hardware919 * acceleration uses only the segment and wrap number. So we920 * need only one entry for a specific wrap/segment combination.921 * If there is a block with a lower number but the same hard-922 * ware position data we just update the block number in the923 * existing entry.924 */925 list_for_each(l, sbid_list) {926 sbid = list_entry(l, struct tape_34xx_sbid, list);927 928 if (929 (sbid->bid.segment == bid.segment) &&930 (sbid->bid.wrap == bid.wrap)931 ) {932 if (bid.block < sbid->bid.block)933 sbid->bid = bid;934 else return;935 break;936 }937 938 /* Sort in according to logical block number. */939 if (bid.block < sbid->bid.block) {940 tape_34xx_append_new_sbid(bid, l->prev);941 break;942 }943 }944 /* List empty or new block bigger than last entry. */945 if (l == sbid_list)946 tape_34xx_append_new_sbid(bid, l->prev);947 948 DBF_LH(4, "Current list is:\n");949 list_for_each(l, sbid_list) {950 sbid = list_entry(l, struct tape_34xx_sbid, list);951 DBF_LH(4, "%d:%03d@%05d\n",952 sbid->bid.wrap,953 sbid->bid.segment,954 sbid->bid.block955 );956 }957}958 959/*960 * Delete all entries from the search block ID list that belong to tape blocks961 * equal or higher than the given number.962 */963static void964tape_34xx_delete_sbid_from(struct tape_device *device, int from)965{966 struct list_head * sbid_list;967 struct tape_34xx_sbid * sbid;968 struct list_head * l;969 struct list_head * n;970 971 sbid_list = (struct list_head *) device->discdata;972 if (!sbid_list)973 return;974 975 list_for_each_safe(l, n, sbid_list) {976 sbid = list_entry(l, struct tape_34xx_sbid, list);977 if (sbid->bid.block >= from) {978 DBF_LH(4, "Delete sbid %d:%03d@%05d\n",979 sbid->bid.wrap,980 sbid->bid.segment,981 sbid->bid.block982 );983 list_del(l);984 kfree(sbid);985 }986 }987}988 989/*990 * Merge hardware position data into a block id.991 */992static void993tape_34xx_merge_sbid(994 struct tape_device * device,995 struct tape_34xx_block_id * bid996) {997 struct tape_34xx_sbid * sbid;998 struct tape_34xx_sbid * sbid_to_use;999 struct list_head * sbid_list;1000 struct list_head * l;1001 1002 sbid_list = (struct list_head *) device->discdata;1003 bid->wrap = 0;1004 bid->segment = 1;1005 1006 if (!sbid_list || list_empty(sbid_list))1007 return;1008 1009 sbid_to_use = NULL;1010 list_for_each(l, sbid_list) {1011 sbid = list_entry(l, struct tape_34xx_sbid, list);1012 1013 if (sbid->bid.block >= bid->block)1014 break;1015 sbid_to_use = sbid;1016 }1017 if (sbid_to_use) {1018 bid->wrap = sbid_to_use->bid.wrap;1019 bid->segment = sbid_to_use->bid.segment;1020 DBF_LH(4, "Use %d:%03d@%05d for %05d\n",1021 sbid_to_use->bid.wrap,1022 sbid_to_use->bid.segment,1023 sbid_to_use->bid.block,1024 bid->block1025 );1026 }1027}1028 1029static int1030tape_34xx_setup_device(struct tape_device * device)1031{1032 int rc;1033 struct list_head * discdata;1034 1035 DBF_EVENT(6, "34xx device setup\n");1036 if ((rc = tape_std_assign(device)) == 0) {1037 if ((rc = tape_34xx_medium_sense(device)) != 0) {1038 DBF_LH(3, "34xx medium sense returned %d\n", rc);1039 }1040 }1041 discdata = kmalloc(sizeof(struct list_head), GFP_KERNEL);1042 if (discdata) {1043 INIT_LIST_HEAD(discdata);1044 device->discdata = discdata;1045 }1046 1047 return rc;1048}1049 1050static void1051tape_34xx_cleanup_device(struct tape_device *device)1052{1053 tape_std_unassign(device);1054 1055 if (device->discdata) {1056 tape_34xx_delete_sbid_from(device, 0);1057 kfree(device->discdata);1058 device->discdata = NULL;1059 }1060}1061 1062 1063/*1064 * MTTELL: Tell block. Return the number of block relative to current file.1065 */1066static int1067tape_34xx_mttell(struct tape_device *device, int mt_count)1068{1069 struct {1070 struct tape_34xx_block_id cbid;1071 struct tape_34xx_block_id dbid;1072 } __attribute__ ((packed)) block_id;1073 int rc;1074 1075 rc = tape_std_read_block_id(device, (__u64 *) &block_id);1076 if (rc)1077 return rc;1078 1079 tape_34xx_add_sbid(device, block_id.cbid);1080 return block_id.cbid.block;1081}1082 1083/*1084 * MTSEEK: seek to the specified block.1085 */1086static int1087tape_34xx_mtseek(struct tape_device *device, int mt_count)1088{1089 struct tape_request *request;1090 struct tape_34xx_block_id * bid;1091 1092 if (mt_count > 0x3fffff) {1093 DBF_EXCEPTION(6, "xsee parm\n");1094 return -EINVAL;1095 }1096 request = tape_alloc_request(3, 4);1097 if (IS_ERR(request))1098 return PTR_ERR(request);1099 1100 /* setup ccws */1101 request->op = TO_LBL;1102 bid = (struct tape_34xx_block_id *) request->cpdata;1103 bid->format = (*device->modeset_byte & 0x08) ?1104 TAPE34XX_FMT_3480_XF : TAPE34XX_FMT_3480;1105 bid->block = mt_count;1106 tape_34xx_merge_sbid(device, bid);1107 1108 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);1109 tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata);1110 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);1111 1112 /* execute it */1113 return tape_do_io_free(device, request);1114}1115 1116/*1117 * List of 3480/3490 magnetic tape commands.1118 */1119static tape_mtop_fn tape_34xx_mtop[TAPE_NR_MTOPS] = {1120 [MTRESET] = tape_std_mtreset,1121 [MTFSF] = tape_std_mtfsf,1122 [MTBSF] = tape_std_mtbsf,1123 [MTFSR] = tape_std_mtfsr,1124 [MTBSR] = tape_std_mtbsr,1125 [MTWEOF] = tape_std_mtweof,1126 [MTREW] = tape_std_mtrew,1127 [MTOFFL] = tape_std_mtoffl,1128 [MTNOP] = tape_std_mtnop,1129 [MTRETEN] = tape_std_mtreten,1130 [MTBSFM] = tape_std_mtbsfm,1131 [MTFSFM] = tape_std_mtfsfm,1132 [MTEOM] = tape_std_mteom,1133 [MTERASE] = tape_std_mterase,1134 [MTRAS1] = NULL,1135 [MTRAS2] = NULL,1136 [MTRAS3] = NULL,1137 [MTSETBLK] = tape_std_mtsetblk,1138 [MTSETDENSITY] = NULL,1139 [MTSEEK] = tape_34xx_mtseek,1140 [MTTELL] = tape_34xx_mttell,1141 [MTSETDRVBUFFER] = NULL,1142 [MTFSS] = NULL,1143 [MTBSS] = NULL,1144 [MTWSM] = NULL,1145 [MTLOCK] = NULL,1146 [MTUNLOCK] = NULL,1147 [MTLOAD] = tape_std_mtload,1148 [MTUNLOAD] = tape_std_mtunload,1149 [MTCOMPRESSION] = tape_std_mtcompression,1150 [MTSETPART] = NULL,1151 [MTMKPART] = NULL1152};1153 1154/*1155 * Tape discipline structure for 3480 and 3490.1156 */1157static struct tape_discipline tape_discipline_34xx = {1158 .owner = THIS_MODULE,1159 .setup_device = tape_34xx_setup_device,1160 .cleanup_device = tape_34xx_cleanup_device,1161 .process_eov = tape_std_process_eov,1162 .irq = tape_34xx_irq,1163 .read_block = tape_std_read_block,1164 .write_block = tape_std_write_block,1165 .ioctl_fn = tape_34xx_ioctl,1166 .mtop_array = tape_34xx_mtop1167};1168 1169static struct ccw_device_id tape_34xx_ids[] = {1170 { CCW_DEVICE_DEVTYPE(0x3480, 0, 0x3480, 0), .driver_info = tape_3480},1171 { CCW_DEVICE_DEVTYPE(0x3490, 0, 0x3490, 0), .driver_info = tape_3490},1172 { /* end of list */ },1173};1174 1175static int1176tape_34xx_online(struct ccw_device *cdev)1177{1178 return tape_generic_online(1179 dev_get_drvdata(&cdev->dev),1180 &tape_discipline_34xx1181 );1182}1183 1184static struct ccw_driver tape_34xx_driver = {1185 .driver = {1186 .name = "tape_34xx",1187 .owner = THIS_MODULE,1188 },1189 .ids = tape_34xx_ids,1190 .probe = tape_generic_probe,1191 .remove = tape_generic_remove,1192 .set_online = tape_34xx_online,1193 .set_offline = tape_generic_offline,1194 .int_class = IRQIO_TAP,1195};1196 1197static int1198tape_34xx_init (void)1199{1200 int rc;1201 1202 TAPE_DBF_AREA = debug_register ( "tape_34xx", 2, 2, 4*sizeof(long));1203 debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);1204#ifdef DBF_LIKE_HELL1205 debug_set_level(TAPE_DBF_AREA, 6);1206#endif1207 1208 DBF_EVENT(3, "34xx init\n");1209 /* Register driver for 3480/3490 tapes. */1210 rc = ccw_driver_register(&tape_34xx_driver);1211 if (rc)1212 DBF_EVENT(3, "34xx init failed\n");1213 else1214 DBF_EVENT(3, "34xx registered\n");1215 return rc;1216}1217 1218static void1219tape_34xx_exit(void)1220{1221 ccw_driver_unregister(&tape_34xx_driver);1222 1223 debug_unregister(TAPE_DBF_AREA);1224}1225 1226MODULE_DEVICE_TABLE(ccw, tape_34xx_ids);1227MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH");1228MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape device driver");1229MODULE_LICENSE("GPL");1230 1231module_init(tape_34xx_init);1232module_exit(tape_34xx_exit);1233