Lines Matching +full:mode +full:- +full:recovery

1 // SPDX-License-Identifier: GPL-2.0
7 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
59 struct tape_device *device = request->device; in __tape_34xx_medium_sense()
62 if (request->rc == 0) { in __tape_34xx_medium_sense()
63 sense = request->cpdata; in __tape_34xx_medium_sense()
67 * means that the drive is 'neither ready nor on-line' it is in __tape_34xx_medium_sense()
77 device->tape_generic_status |= GMT_WR_PROT(~0); in __tape_34xx_medium_sense()
79 device->tape_generic_status &= ~GMT_WR_PROT(~0); in __tape_34xx_medium_sense()
82 request->rc); in __tape_34xx_medium_sense()
97 request->op = TO_MSEN; in tape_34xx_medium_sense()
98 tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); in tape_34xx_medium_sense()
114 request->op = TO_MSEN; in tape_34xx_medium_sense_async()
115 tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); in tape_34xx_medium_sense_async()
116 request->callback = (void *) __tape_34xx_medium_sense; in tape_34xx_medium_sense_async()
117 request->callback_data = NULL; in tape_34xx_medium_sense_async()
142 struct tape_device *device = p->device; in tape_34xx_work_handler()
144 switch(p->op) { in tape_34xx_work_handler()
161 return -ENOMEM; in tape_34xx_schedule_work()
163 INIT_WORK(&p->work, tape_34xx_work_handler); in tape_34xx_schedule_work()
165 p->device = tape_get_device(device); in tape_34xx_schedule_work()
166 p->op = op; in tape_34xx_schedule_work()
168 schedule_work(&p->work); in tape_34xx_schedule_work()
173 * Done Handler is called when dev stat = DEVICE-END (successful operation)
178 DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]); in tape_34xx_done()
180 switch (request->op) { in tape_34xx_done()
187 tape_34xx_delete_sbid_from(request->device, 0); in tape_34xx_done()
198 DBF_EVENT(3, "Error recovery failed for %s (RC=%d)\n", in tape_34xx_erp_failed()
199 tape_op_verbose[request->op], rc); in tape_34xx_erp_failed()
206 DBF_EVENT(3, "Error Recovery successful for %s\n", in tape_34xx_erp_succeeded()
207 tape_op_verbose[request->op]); in tape_34xx_erp_succeeded()
214 DBF_EVENT(3, "xerp retr %s\n", tape_op_verbose[request->op]); in tape_34xx_erp_retry()
225 if (irb->scsw.cmd.dstat == 0x85) { /* READY */ in tape_34xx_unsolicited_irq()
231 DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id); in tape_34xx_unsolicited_irq()
238 * Read Opposite Error Recovery Function:
245 if (request->op == TO_RFO) { in tape_34xx_erp_read_opposite()
257 * success -> failed. in tape_34xx_erp_read_opposite()
259 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_erp_read_opposite()
266 if (request->op != TO_ASSIGN) { in tape_34xx_erp_bug()
267 dev_err(&device->cdev->dev, "An unexpected condition %d " in tape_34xx_erp_bug()
268 "occurred in tape error recovery\n", no); in tape_34xx_erp_bug()
271 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_erp_bug()
282 if (irb->ecw[3] == 0x40) { in tape_34xx_erp_overrun()
283 dev_warn (&device->cdev->dev, "A data overrun occurred between" in tape_34xx_erp_overrun()
285 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_erp_overrun()
287 return tape_34xx_erp_bug(device, request, irb, -1); in tape_34xx_erp_overrun()
297 if (irb->ecw[3] == 0x41) { in tape_34xx_erp_sequence()
299 * cu detected incorrect block-id sequence on tape. in tape_34xx_erp_sequence()
301 dev_warn (&device->cdev->dev, "The block ID sequence on the " in tape_34xx_erp_sequence()
303 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_erp_sequence()
309 return tape_34xx_erp_bug(device, request, irb, -2); in tape_34xx_erp_sequence()
313 * This function analyses the tape's sense-data in case of a unit-check.
324 inhibit_cu_recovery = (*device->modeset_byte & 0x80) ? 1 : 0; in tape_34xx_unit_check()
325 sense = irb->ecw; in tape_34xx_unit_check()
332 request->op == TO_DSE || in tape_34xx_unit_check()
333 request->op == TO_WRI || in tape_34xx_unit_check()
334 request->op == TO_WTM in tape_34xx_unit_check()
337 return tape_34xx_erp_failed(request, -EACCES); in tape_34xx_unit_check()
339 return tape_34xx_erp_bug(device, request, irb, -3); in tape_34xx_unit_check()
344 * Special cases for various tape-states when reaching in tape_34xx_unit_check()
363 switch (request->op) { in tape_34xx_unit_check()
374 return tape_34xx_erp_failed(request, -ENOSPC); in tape_34xx_unit_check()
386 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
389 /* Read beyond end of recorded area -> 0 bytes read */ in tape_34xx_unit_check()
399 return tape_34xx_erp_failed(request, -ENOSPC); in tape_34xx_unit_check()
420 // recovered. We always use async-mode with in tape_34xx_unit_check()
421 // cu-recovery, so this should *never* happen. in tape_34xx_unit_check()
423 irb, -4); in tape_34xx_unit_check()
425 /* data check is permanent, CU recovery has failed */ in tape_34xx_unit_check()
426 dev_warn (&device->cdev->dev, "A read error occurred " in tape_34xx_unit_check()
428 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
434 // recovered. We always use async-mode with in tape_34xx_unit_check()
435 // cu-recovery, so this should *never* happen. in tape_34xx_unit_check()
437 irb, -5); in tape_34xx_unit_check()
439 // data check is permanent, cu-recovery has failed in tape_34xx_unit_check()
440 dev_warn (&device->cdev->dev, "A write error on the " in tape_34xx_unit_check()
442 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
447 /* ID-Mark at tape start couldn't be written */ in tape_34xx_unit_check()
448 dev_warn (&device->cdev->dev, "Writing the ID-mark " in tape_34xx_unit_check()
450 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
453 dev_warn (&device->cdev->dev, "Reading the tape beyond" in tape_34xx_unit_check()
455 return tape_34xx_erp_failed(request, -ENOSPC); in tape_34xx_unit_check()
458 dev_warn (&device->cdev->dev, "The tape contains an " in tape_34xx_unit_check()
460 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
463 * the above erpa-codes. For 3490, other data-check in tape_34xx_unit_check()
465 if (device->cdev->id.driver_info == tape_3480) in tape_34xx_unit_check()
467 irb, -6); in tape_34xx_unit_check()
485 * interlock mode. Reissue the command. in tape_34xx_unit_check()
494 dev_warn (&device->cdev->dev, "A path equipment check occurred" in tape_34xx_unit_check()
496 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
516 * subsystem func is issued and the CU is not on-line. in tape_34xx_unit_check()
518 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
530 if (request->op == TO_RUN) { in tape_34xx_unit_check()
539 * Permanent equipment check. CU has tried recovery, but in tape_34xx_unit_check()
542 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
545 if (request->op == TO_DSE) in tape_34xx_unit_check()
546 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
555 dev_warn (&device->cdev->dev, "The tape unit cannot process " in tape_34xx_unit_check()
557 return tape_34xx_erp_failed(request, -EMEDIUMTYPE); in tape_34xx_unit_check()
560 dev_warn (&device->cdev->dev, "The tape medium is write-" in tape_34xx_unit_check()
562 return tape_34xx_erp_failed(request, -EACCES); in tape_34xx_unit_check()
565 dev_warn (&device->cdev->dev, "The tape does not have the " in tape_34xx_unit_check()
567 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
573 dev_warn (&device->cdev->dev, "The tape unit failed to load" in tape_34xx_unit_check()
576 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
582 dev_warn (&device->cdev->dev, "Automatic unloading of the tape" in tape_34xx_unit_check()
584 if (request->op == TO_RUN) in tape_34xx_unit_check()
585 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
590 * - cu cannot recover from a drive detected error in tape_34xx_unit_check()
591 * - a check code message is shown on drive display in tape_34xx_unit_check()
592 * - the cartridge loader does not respond correctly in tape_34xx_unit_check()
593 * - a failure occurs during an index, load, or unload cycle in tape_34xx_unit_check()
595 dev_warn (&device->cdev->dev, "An equipment check has occurred" in tape_34xx_unit_check()
597 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
599 if (device->cdev->id.driver_info == tape_3490) in tape_34xx_unit_check()
601 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
607 * the beginning-of-tape data. in tape_34xx_unit_check()
609 dev_warn (&device->cdev->dev, "The tape information states an" in tape_34xx_unit_check()
611 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
617 if (request->op==TO_WRI || in tape_34xx_unit_check()
618 request->op==TO_DSE || in tape_34xx_unit_check()
619 request->op==TO_WTM) in tape_34xx_unit_check()
620 return tape_34xx_erp_failed(request, -ENOSPC); in tape_34xx_unit_check()
621 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
624 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
627 dev_warn (&device->cdev->dev, "The tape unit is not ready\n"); in tape_34xx_unit_check()
628 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
631 dev_warn (&device->cdev->dev, "The tape medium has been " in tape_34xx_unit_check()
634 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
637 * Degraded mode. A condition that can cause degraded in tape_34xx_unit_check()
640 dev_warn (&device->cdev->dev, "The tape subsystem is running " in tape_34xx_unit_check()
641 "in degraded mode\n"); in tape_34xx_unit_check()
649 switch(request->op) { in tape_34xx_unit_check()
660 return tape_34xx_erp_failed(request, -ENOMEDIUM); in tape_34xx_unit_check()
663 if (request->op != TO_BLOCK && request->op != TO_LBL) in tape_34xx_unit_check()
667 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
670 dev_warn (&device->cdev->dev, "The tape unit is already " in tape_34xx_unit_check()
672 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
675 * Drive not on-line. Drive may be switched offline, in tape_34xx_unit_check()
679 dev_warn (&device->cdev->dev, "The tape unit is not online\n"); in tape_34xx_unit_check()
680 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
683 dev_warn (&device->cdev->dev, "The control unit has fenced " in tape_34xx_unit_check()
686 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
692 dev_warn (&device->cdev->dev, "A parity error occurred on the " in tape_34xx_unit_check()
694 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
697 dev_warn (&device->cdev->dev, "I/O error recovery failed on " in tape_34xx_unit_check()
699 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
702 * CU and drive incompatible. The drive requests micro-program in tape_34xx_unit_check()
705 dev_warn (&device->cdev->dev, "The tape unit requires a " in tape_34xx_unit_check()
707 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
710 * Recovered Check-One failure. Cu develops a hardware error, in tape_34xx_unit_check()
715 if (device->cdev->id.driver_info == tape_3490) in tape_34xx_unit_check()
718 * not support resetting event recovery (which has to in tape_34xx_unit_check()
725 if (device->cdev->id.driver_info == tape_3490) { in tape_34xx_unit_check()
729 * buffered mode. in tape_34xx_unit_check()
731 dev_warn (&device->cdev->dev, "The maximum block size" in tape_34xx_unit_check()
732 " for buffered mode is exceeded\n"); in tape_34xx_unit_check()
733 return tape_34xx_erp_failed(request, -ENOBUFS); in tape_34xx_unit_check()
740 * buffered log mode, and a counter overflows. This should in tape_34xx_unit_check()
742 * buffered log mode. in tape_34xx_unit_check()
748 * CU is in extended buffered log mode. This should never in tape_34xx_unit_check()
750 * log mode. in tape_34xx_unit_check()
755 if (request->op == TO_RUN) { in tape_34xx_unit_check()
765 /* Channel interface recovery (temporary). */ in tape_34xx_unit_check()
768 /* Channel interface recovery (permanent). */ in tape_34xx_unit_check()
769 dev_warn (&device->cdev->dev, "A channel interface error cannot be" in tape_34xx_unit_check()
771 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
774 dev_warn (&device->cdev->dev, "A channel protocol error " in tape_34xx_unit_check()
776 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
788 dev_warn (&device->cdev->dev, "The tape unit does not support " in tape_34xx_unit_check()
790 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
796 dev_warn (&device->cdev->dev, "The tape unit does not support" in tape_34xx_unit_check()
798 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
800 /* Format 3480-2 XF incompatible */ in tape_34xx_unit_check()
801 dev_warn (&device->cdev->dev, "The tape unit does not support tape " in tape_34xx_unit_check()
802 "format 3480-2 XF\n"); in tape_34xx_unit_check()
803 return tape_34xx_erp_failed(request, -EIO); in tape_34xx_unit_check()
806 dev_warn (&device->cdev->dev, "The tape unit does not support" in tape_34xx_unit_check()
808 return tape_34xx_erp_failed(request, -EMEDIUMTYPE); in tape_34xx_unit_check()
811 dev_warn (&device->cdev->dev, "The tape unit does not support" in tape_34xx_unit_check()
813 return tape_34xx_erp_failed(request, -EMEDIUMTYPE); in tape_34xx_unit_check()
839 if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) && in tape_34xx_irq()
840 (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) && in tape_34xx_irq()
841 (request->op == TO_WRI)) { in tape_34xx_irq()
843 return tape_34xx_erp_failed(request, -ENOSPC); in tape_34xx_irq()
846 if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) in tape_34xx_irq()
849 if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) { in tape_34xx_irq()
853 if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) { in tape_34xx_irq()
854 if (request->op == TO_BSB || request->op == TO_FSB) in tape_34xx_irq()
855 request->rescnt++; in tape_34xx_irq()
877 return -EFAULT; in tape_34xx_ioctl()
881 return -EINVAL; in tape_34xx_ioctl()
893 new_sbid->bid = bid; in tape_34xx_append_new_sbid()
894 list_add(&new_sbid->list, l); in tape_34xx_append_new_sbid()
914 sbid_list = (struct list_head *) device->discdata; in tape_34xx_add_sbid()
922 * If there is a block with a lower number but the same hard- in tape_34xx_add_sbid()
930 (sbid->bid.segment == bid.segment) && in tape_34xx_add_sbid()
931 (sbid->bid.wrap == bid.wrap) in tape_34xx_add_sbid()
933 if (bid.block < sbid->bid.block) in tape_34xx_add_sbid()
934 sbid->bid = bid; in tape_34xx_add_sbid()
940 if (bid.block < sbid->bid.block) { in tape_34xx_add_sbid()
941 tape_34xx_append_new_sbid(bid, l->prev); in tape_34xx_add_sbid()
947 tape_34xx_append_new_sbid(bid, l->prev); in tape_34xx_add_sbid()
953 sbid->bid.wrap, in tape_34xx_add_sbid()
954 sbid->bid.segment, in tape_34xx_add_sbid()
955 sbid->bid.block in tape_34xx_add_sbid()
972 sbid_list = (struct list_head *) device->discdata; in tape_34xx_delete_sbid_from()
978 if (sbid->bid.block >= from) { in tape_34xx_delete_sbid_from()
980 sbid->bid.wrap, in tape_34xx_delete_sbid_from()
981 sbid->bid.segment, in tape_34xx_delete_sbid_from()
982 sbid->bid.block in tape_34xx_delete_sbid_from()
1003 sbid_list = (struct list_head *) device->discdata; in tape_34xx_merge_sbid()
1004 bid->wrap = 0; in tape_34xx_merge_sbid()
1005 bid->segment = 1; in tape_34xx_merge_sbid()
1014 if (sbid->bid.block >= bid->block) in tape_34xx_merge_sbid()
1019 bid->wrap = sbid_to_use->bid.wrap; in tape_34xx_merge_sbid()
1020 bid->segment = sbid_to_use->bid.segment; in tape_34xx_merge_sbid()
1022 sbid_to_use->bid.wrap, in tape_34xx_merge_sbid()
1023 sbid_to_use->bid.segment, in tape_34xx_merge_sbid()
1024 sbid_to_use->bid.block, in tape_34xx_merge_sbid()
1025 bid->block in tape_34xx_merge_sbid()
1045 device->discdata = discdata; in tape_34xx_setup_device()
1056 if (device->discdata) { in tape_34xx_cleanup_device()
1058 kfree(device->discdata); in tape_34xx_cleanup_device()
1059 device->discdata = NULL; in tape_34xx_cleanup_device()
1095 return -EINVAL; in tape_34xx_mtseek()
1102 request->op = TO_LBL; in tape_34xx_mtseek()
1103 bid = (struct tape_34xx_block_id *) request->cpdata; in tape_34xx_mtseek()
1104 bid->format = (*device->modeset_byte & 0x08) ? in tape_34xx_mtseek()
1106 bid->block = mt_count; in tape_34xx_mtseek()
1109 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); in tape_34xx_mtseek()
1110 tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata); in tape_34xx_mtseek()
1111 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); in tape_34xx_mtseek()
1180 dev_get_drvdata(&cdev->dev), in tape_34xx_online()
1228 MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH");