Skip to content

Commit

Permalink
[S390] dasd: re-initialize read_conf buffer for retries
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stefan Haberland authored and Martin Schwidefsky committed Oct 30, 2011
1 parent 214b8ff commit 5915a87
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
7 changes: 5 additions & 2 deletions drivers/s390/block/dasd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2059,13 +2059,14 @@ void dasd_add_request_tail(struct dasd_ccw_req *cqr)
/*
* Wakeup helper for the 'sleep_on' functions.
*/
static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data)
void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data)
{
spin_lock_irq(get_ccwdev_lock(cqr->startdev->cdev));
cqr->callback_data = DASD_SLEEPON_END_TAG;
spin_unlock_irq(get_ccwdev_lock(cqr->startdev->cdev));
wake_up(&generic_waitq);
}
EXPORT_SYMBOL_GPL(dasd_wakeup_cb);

static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr)
{
Expand Down Expand Up @@ -2165,7 +2166,9 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
} else
wait_event(generic_waitq, !(device->stopped));

cqr->callback = dasd_wakeup_cb;
if (!cqr->callback)
cqr->callback = dasd_wakeup_cb;

cqr->callback_data = DASD_SLEEPON_START_TAG;
dasd_add_request_tail(cqr);
if (interruptible) {
Expand Down
26 changes: 26 additions & 0 deletions drivers/s390/block/dasd_eckd.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,30 @@ static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device,
set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags);
}

/*
* Wakeup helper for read_conf
* if the cqr is not done and needs some error recovery
* the buffer has to be re-initialized with the EBCDIC "V1.0"
* to show support for virtual device SNEQ
*/
static void read_conf_cb(struct dasd_ccw_req *cqr, void *data)
{
struct ccw1 *ccw;
__u8 *rcd_buffer;

if (cqr->status != DASD_CQR_DONE) {
ccw = cqr->cpaddr;
rcd_buffer = (__u8 *)((addr_t) ccw->cda);
memset(rcd_buffer, 0, sizeof(*rcd_buffer));

rcd_buffer[0] = 0xE5;
rcd_buffer[1] = 0xF1;
rcd_buffer[2] = 0x4B;
rcd_buffer[3] = 0xF0;
}
dasd_wakeup_cb(cqr, data);
}

static int dasd_eckd_read_conf_immediately(struct dasd_device *device,
struct dasd_ccw_req *cqr,
__u8 *rcd_buffer,
Expand All @@ -863,6 +887,7 @@ static int dasd_eckd_read_conf_immediately(struct dasd_device *device,
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
cqr->retries = 5;
cqr->callback = read_conf_cb;
rc = dasd_sleep_on_immediatly(cqr);
return rc;
}
Expand Down Expand Up @@ -900,6 +925,7 @@ static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
goto out_error;
}
dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buf, lpm);
cqr->callback = read_conf_cb;
ret = dasd_sleep_on(cqr);
/*
* on success we update the user input parms
Expand Down
1 change: 1 addition & 0 deletions drivers/s390/block/dasd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,7 @@ struct dasd_ccw_req *
dasd_smalloc_request(int , int, int, struct dasd_device *);
void dasd_kfree_request(struct dasd_ccw_req *, struct dasd_device *);
void dasd_sfree_request(struct dasd_ccw_req *, struct dasd_device *);
void dasd_wakeup_cb(struct dasd_ccw_req *, void *);

static inline int
dasd_kmalloc_set_cda(struct ccw1 *ccw, void *cda, struct dasd_device *device)
Expand Down

0 comments on commit 5915a87

Please sign in to comment.