aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorStefan Haberland <stefan.haberland@de.ibm.com>2011-10-30 10:16:57 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2011-10-30 10:16:44 -0400
commit5915a873fcb1cea5260940be519f2cdf898f7be3 (patch)
treeca7ce2f06e46f74ed771d93ed97ce55b113dadb3 /drivers/s390
parent214b8ffc205bcf2ca5b04b3903be13a9257c3fbd (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')
-rw-r--r--drivers/s390/block/dasd.c7
-rw-r--r--drivers/s390/block/dasd_eckd.c26
-rw-r--r--drivers/s390/block/dasd_int.h1
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 */
2062static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data) 2062void 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}
2069EXPORT_SYMBOL_GPL(dasd_wakeup_cb);
2069 2070
2070static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) 2071static 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 */
853static 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
847static int dasd_eckd_read_conf_immediately(struct dasd_device *device, 871static 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 *
643dasd_smalloc_request(int , int, int, struct dasd_device *); 643dasd_smalloc_request(int , int, int, struct dasd_device *);
644void dasd_kfree_request(struct dasd_ccw_req *, struct dasd_device *); 644void dasd_kfree_request(struct dasd_ccw_req *, struct dasd_device *);
645void dasd_sfree_request(struct dasd_ccw_req *, struct dasd_device *); 645void dasd_sfree_request(struct dasd_ccw_req *, struct dasd_device *);
646void dasd_wakeup_cb(struct dasd_ccw_req *, void *);
646 647
647static inline int 648static inline int
648dasd_kmalloc_set_cda(struct ccw1 *ccw, void *cda, struct dasd_device *device) 649dasd_kmalloc_set_cda(struct ccw1 *ccw, void *cda, struct dasd_device *device)