[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>
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index 70a008c..cdc6c04 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -755,11 +755,11 @@
 {
 	/* If pos == device then device is already locked! */
 	if (pos == device) {
-		pos->stopped |= DASD_STOPPED_SU;
+		dasd_device_set_stop_bits(pos, DASD_STOPPED_SU);
 		return;
 	}
 	spin_lock(get_ccwdev_lock(pos->cdev));
-	pos->stopped |= DASD_STOPPED_SU;
+	dasd_device_set_stop_bits(pos, DASD_STOPPED_SU);
 	spin_unlock(get_ccwdev_lock(pos->cdev));
 }
 
@@ -793,26 +793,26 @@
 
 	list_for_each_entry(device, &lcu->active_devices, alias_list) {
 		spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-		device->stopped &= ~DASD_STOPPED_SU;
+		dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 		spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	}
 
 	list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
 		spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-		device->stopped &= ~DASD_STOPPED_SU;
+		dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 		spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	}
 
 	list_for_each_entry(pavgroup, &lcu->grouplist, group) {
 		list_for_each_entry(device, &pavgroup->baselist, alias_list) {
 			spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-			device->stopped &= ~DASD_STOPPED_SU;
+			dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 			spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
 					       flags);
 		}
 		list_for_each_entry(device, &pavgroup->aliaslist, alias_list) {
 			spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-			device->stopped &= ~DASD_STOPPED_SU;
+			dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 			spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
 					       flags);
 		}
@@ -836,7 +836,8 @@
 
 	/* 2. reset summary unit check */
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-	device->stopped &= ~(DASD_STOPPED_SU | DASD_STOPPED_PENDING);
+	dasd_device_remove_stop_bits(device,
+				     (DASD_STOPPED_SU | DASD_STOPPED_PENDING));
 	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	reset_summary_unit_check(lcu, device, suc_data->reason);