aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_alias.c
diff options
context:
space:
mode:
authorStefan Weinhuber <wein@de.ibm.com>2009-12-07 06:51:51 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2009-12-07 06:51:34 -0500
commiteb6e199bef288611157b8198c25d12b32bf058d0 (patch)
tree80737a2703a9f4d09cee2410342aeccb281413ae /drivers/s390/block/dasd_alias.c
parent626350b63ef2cd447023d3dc2a34eaa7ca01bfff (diff)
[S390] dasd: improve error recovery for internal I/O
Most of the error conditions reported by a FICON storage server indicate situations which can be recovered. Sometimes the host just needs to retry an I/O request, but sometimes the recovery is more complex and requires the device driver to wait, choose a different path, etc. The DASD device driver has a fully featured error recovery for normal block layer I/O, but not for internal I/O request which are for example used during the device bring up. This can lead to situations where the IPL of a system fails because DASD devices are not properly recognized. This patch will extend the internal I/O handling to use the existing error recovery procedures. Signed-off-by: Stefan Weinhuber <wein@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd_alias.c')
-rw-r--r--drivers/s390/block/dasd_alias.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index 70a008c00522..cdc6c049c353 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -755,11 +755,11 @@ static void __stop_device_on_lcu(struct dasd_device *device,
755{ 755{
756 /* If pos == device then device is already locked! */ 756 /* If pos == device then device is already locked! */
757 if (pos == device) { 757 if (pos == device) {
758 pos->stopped |= DASD_STOPPED_SU; 758 dasd_device_set_stop_bits(pos, DASD_STOPPED_SU);
759 return; 759 return;
760 } 760 }
761 spin_lock(get_ccwdev_lock(pos->cdev)); 761 spin_lock(get_ccwdev_lock(pos->cdev));
762 pos->stopped |= DASD_STOPPED_SU; 762 dasd_device_set_stop_bits(pos, DASD_STOPPED_SU);
763 spin_unlock(get_ccwdev_lock(pos->cdev)); 763 spin_unlock(get_ccwdev_lock(pos->cdev));
764} 764}
765 765
@@ -793,26 +793,26 @@ static void _unstop_all_devices_on_lcu(struct alias_lcu *lcu)
793 793
794 list_for_each_entry(device, &lcu->active_devices, alias_list) { 794 list_for_each_entry(device, &lcu->active_devices, alias_list) {
795 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 795 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
796 device->stopped &= ~DASD_STOPPED_SU; 796 dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
797 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 797 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
798 } 798 }
799 799
800 list_for_each_entry(device, &lcu->inactive_devices, alias_list) { 800 list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
801 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 801 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
802 device->stopped &= ~DASD_STOPPED_SU; 802 dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
803 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 803 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
804 } 804 }
805 805
806 list_for_each_entry(pavgroup, &lcu->grouplist, group) { 806 list_for_each_entry(pavgroup, &lcu->grouplist, group) {
807 list_for_each_entry(device, &pavgroup->baselist, alias_list) { 807 list_for_each_entry(device, &pavgroup->baselist, alias_list) {
808 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 808 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
809 device->stopped &= ~DASD_STOPPED_SU; 809 dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
810 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), 810 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
811 flags); 811 flags);
812 } 812 }
813 list_for_each_entry(device, &pavgroup->aliaslist, alias_list) { 813 list_for_each_entry(device, &pavgroup->aliaslist, alias_list) {
814 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 814 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
815 device->stopped &= ~DASD_STOPPED_SU; 815 dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
816 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), 816 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
817 flags); 817 flags);
818 } 818 }
@@ -836,7 +836,8 @@ static void summary_unit_check_handling_work(struct work_struct *work)
836 836
837 /* 2. reset summary unit check */ 837 /* 2. reset summary unit check */
838 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 838 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
839 device->stopped &= ~(DASD_STOPPED_SU | DASD_STOPPED_PENDING); 839 dasd_device_remove_stop_bits(device,
840 (DASD_STOPPED_SU | DASD_STOPPED_PENDING));
840 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 841 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
841 reset_summary_unit_check(lcu, device, suc_data->reason); 842 reset_summary_unit_check(lcu, device, suc_data->reason);
842 843