diff options
Diffstat (limited to 'drivers/s390/block/dasd.c')
| -rw-r--r-- | drivers/s390/block/dasd.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 1aec8ff0b587..f73d2f579a7e 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
| @@ -1863,6 +1863,33 @@ static void __dasd_device_check_expire(struct dasd_device *device) | |||
| 1863 | } | 1863 | } |
| 1864 | 1864 | ||
| 1865 | /* | 1865 | /* |
| 1866 | * return 1 when device is not eligible for IO | ||
| 1867 | */ | ||
| 1868 | static int __dasd_device_is_unusable(struct dasd_device *device, | ||
| 1869 | struct dasd_ccw_req *cqr) | ||
| 1870 | { | ||
| 1871 | int mask = ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM); | ||
| 1872 | |||
| 1873 | if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) { | ||
| 1874 | /* dasd is being set offline. */ | ||
| 1875 | return 1; | ||
| 1876 | } | ||
| 1877 | if (device->stopped) { | ||
| 1878 | if (device->stopped & mask) { | ||
| 1879 | /* stopped and CQR will not change that. */ | ||
| 1880 | return 1; | ||
| 1881 | } | ||
| 1882 | if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags)) { | ||
| 1883 | /* CQR is not able to change device to | ||
| 1884 | * operational. */ | ||
| 1885 | return 1; | ||
| 1886 | } | ||
| 1887 | /* CQR required to get device operational. */ | ||
| 1888 | } | ||
| 1889 | return 0; | ||
| 1890 | } | ||
| 1891 | |||
| 1892 | /* | ||
| 1866 | * Take a look at the first request on the ccw queue and check | 1893 | * Take a look at the first request on the ccw queue and check |
| 1867 | * if it needs to be started. | 1894 | * if it needs to be started. |
| 1868 | */ | 1895 | */ |
| @@ -1876,13 +1903,8 @@ static void __dasd_device_start_head(struct dasd_device *device) | |||
| 1876 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); | 1903 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); |
| 1877 | if (cqr->status != DASD_CQR_QUEUED) | 1904 | if (cqr->status != DASD_CQR_QUEUED) |
| 1878 | return; | 1905 | return; |
| 1879 | /* when device is stopped, return request to previous layer | 1906 | /* if device is not usable return request to upper layer */ |
| 1880 | * exception: only the disconnect or unresumed bits are set and the | 1907 | if (__dasd_device_is_unusable(device, cqr)) { |
| 1881 | * cqr is a path verification request | ||
| 1882 | */ | ||
| 1883 | if (device->stopped && | ||
| 1884 | !(!(device->stopped & ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM)) | ||
| 1885 | && test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))) { | ||
| 1886 | cqr->intrc = -EAGAIN; | 1908 | cqr->intrc = -EAGAIN; |
| 1887 | cqr->status = DASD_CQR_CLEARED; | 1909 | cqr->status = DASD_CQR_CLEARED; |
| 1888 | dasd_schedule_device_bh(device); | 1910 | dasd_schedule_device_bh(device); |
