diff options
author | Stefan Haberland <stefan.haberland@de.ibm.com> | 2011-10-30 10:16:57 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-10-30 10:16:44 -0400 |
commit | 5915a873fcb1cea5260940be519f2cdf898f7be3 (patch) | |
tree | ca7ce2f06e46f74ed771d93ed97ce55b113dadb3 /drivers/s390/block | |
parent | 214b8ffc205bcf2ca5b04b3903be13a9257c3fbd (diff) |
[S390] dasd: re-initialize read_conf buffer for retries
The buffer for read configuration data has to be initialized with an
EBCDIC string to show support for extended UIDs to z/VM.
If this read configuration data CQR needs to be retried, the buffer
may have changed in between. So re-initialize the buffer to get a
correct extended UID under z/VM.
Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block')
-rw-r--r-- | drivers/s390/block/dasd.c | 7 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 26 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 1 |
3 files changed, 32 insertions, 2 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 3b94b6542fc..ce2a780a9ea 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -2059,13 +2059,14 @@ void dasd_add_request_tail(struct dasd_ccw_req *cqr) | |||
2059 | /* | 2059 | /* |
2060 | * Wakeup helper for the 'sleep_on' functions. | 2060 | * Wakeup helper for the 'sleep_on' functions. |
2061 | */ | 2061 | */ |
2062 | static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data) | 2062 | void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data) |
2063 | { | 2063 | { |
2064 | spin_lock_irq(get_ccwdev_lock(cqr->startdev->cdev)); | 2064 | spin_lock_irq(get_ccwdev_lock(cqr->startdev->cdev)); |
2065 | cqr->callback_data = DASD_SLEEPON_END_TAG; | 2065 | cqr->callback_data = DASD_SLEEPON_END_TAG; |
2066 | spin_unlock_irq(get_ccwdev_lock(cqr->startdev->cdev)); | 2066 | spin_unlock_irq(get_ccwdev_lock(cqr->startdev->cdev)); |
2067 | wake_up(&generic_waitq); | 2067 | wake_up(&generic_waitq); |
2068 | } | 2068 | } |
2069 | EXPORT_SYMBOL_GPL(dasd_wakeup_cb); | ||
2069 | 2070 | ||
2070 | static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) | 2071 | static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) |
2071 | { | 2072 | { |
@@ -2165,7 +2166,9 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible) | |||
2165 | } else | 2166 | } else |
2166 | wait_event(generic_waitq, !(device->stopped)); | 2167 | wait_event(generic_waitq, !(device->stopped)); |
2167 | 2168 | ||
2168 | cqr->callback = dasd_wakeup_cb; | 2169 | if (!cqr->callback) |
2170 | cqr->callback = dasd_wakeup_cb; | ||
2171 | |||
2169 | cqr->callback_data = DASD_SLEEPON_START_TAG; | 2172 | cqr->callback_data = DASD_SLEEPON_START_TAG; |
2170 | dasd_add_request_tail(cqr); | 2173 | dasd_add_request_tail(cqr); |
2171 | if (interruptible) { | 2174 | if (interruptible) { |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 0e9c4dcf145..cb1bbc2947e 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -844,6 +844,30 @@ static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device, | |||
844 | set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags); | 844 | set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags); |
845 | } | 845 | } |
846 | 846 | ||
847 | /* | ||
848 | * Wakeup helper for read_conf | ||
849 | * if the cqr is not done and needs some error recovery | ||
850 | * the buffer has to be re-initialized with the EBCDIC "V1.0" | ||
851 | * to show support for virtual device SNEQ | ||
852 | */ | ||
853 | static void read_conf_cb(struct dasd_ccw_req *cqr, void *data) | ||
854 | { | ||
855 | struct ccw1 *ccw; | ||
856 | __u8 *rcd_buffer; | ||
857 | |||
858 | if (cqr->status != DASD_CQR_DONE) { | ||
859 | ccw = cqr->cpaddr; | ||
860 | rcd_buffer = (__u8 *)((addr_t) ccw->cda); | ||
861 | memset(rcd_buffer, 0, sizeof(*rcd_buffer)); | ||
862 | |||
863 | rcd_buffer[0] = 0xE5; | ||
864 | rcd_buffer[1] = 0xF1; | ||
865 | rcd_buffer[2] = 0x4B; | ||
866 | rcd_buffer[3] = 0xF0; | ||
867 | } | ||
868 | dasd_wakeup_cb(cqr, data); | ||
869 | } | ||
870 | |||
847 | static int dasd_eckd_read_conf_immediately(struct dasd_device *device, | 871 | static int dasd_eckd_read_conf_immediately(struct dasd_device *device, |
848 | struct dasd_ccw_req *cqr, | 872 | struct dasd_ccw_req *cqr, |
849 | __u8 *rcd_buffer, | 873 | __u8 *rcd_buffer, |
@@ -863,6 +887,7 @@ static int dasd_eckd_read_conf_immediately(struct dasd_device *device, | |||
863 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 887 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); |
864 | set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags); | 888 | set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags); |
865 | cqr->retries = 5; | 889 | cqr->retries = 5; |
890 | cqr->callback = read_conf_cb; | ||
866 | rc = dasd_sleep_on_immediatly(cqr); | 891 | rc = dasd_sleep_on_immediatly(cqr); |
867 | return rc; | 892 | return rc; |
868 | } | 893 | } |
@@ -900,6 +925,7 @@ static int dasd_eckd_read_conf_lpm(struct dasd_device *device, | |||
900 | goto out_error; | 925 | goto out_error; |
901 | } | 926 | } |
902 | dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buf, lpm); | 927 | dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buf, lpm); |
928 | cqr->callback = read_conf_cb; | ||
903 | ret = dasd_sleep_on(cqr); | 929 | ret = dasd_sleep_on(cqr); |
904 | /* | 930 | /* |
905 | * on success we update the user input parms | 931 | * on success we update the user input parms |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 1dd12bd85a6..563bf8a25dc 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -643,6 +643,7 @@ struct dasd_ccw_req * | |||
643 | dasd_smalloc_request(int , int, int, struct dasd_device *); | 643 | dasd_smalloc_request(int , int, int, struct dasd_device *); |
644 | void dasd_kfree_request(struct dasd_ccw_req *, struct dasd_device *); | 644 | void dasd_kfree_request(struct dasd_ccw_req *, struct dasd_device *); |
645 | void dasd_sfree_request(struct dasd_ccw_req *, struct dasd_device *); | 645 | void dasd_sfree_request(struct dasd_ccw_req *, struct dasd_device *); |
646 | void dasd_wakeup_cb(struct dasd_ccw_req *, void *); | ||
646 | 647 | ||
647 | static inline int | 648 | static inline int |
648 | dasd_kmalloc_set_cda(struct ccw1 *ccw, void *cda, struct dasd_device *device) | 649 | dasd_kmalloc_set_cda(struct ccw1 *ccw, void *cda, struct dasd_device *device) |