[S390] dasd: New read device characteristics and read configuration data.
Instead of the deprecated read_dev_chars() and read_conf_data_lpm(), implement dasd_generic_read_dev_chars() and dasd_eckd_read_conf_lpm(). These should even recover better from error than the original cio functions. Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
52706ec903
commit
17283b56ec
|
@ -2174,6 +2174,51 @@ dasd_generic_notify(struct ccw_device *cdev, int event)
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct dasd_ccw_req * dasd_generic_build_rdc(struct dasd_device *device,
|
||||
void *rdc_buffer,
|
||||
int rdc_buffer_size, char *magic)
|
||||
{
|
||||
struct dasd_ccw_req *cqr;
|
||||
struct ccw1 *ccw;
|
||||
|
||||
cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device);
|
||||
|
||||
if (IS_ERR(cqr)) {
|
||||
DEV_MESSAGE(KERN_WARNING, device, "%s",
|
||||
"Could not allocate RDC request");
|
||||
return cqr;
|
||||
}
|
||||
|
||||
ccw = cqr->cpaddr;
|
||||
ccw->cmd_code = CCW_CMD_RDC;
|
||||
ccw->cda = (__u32)(addr_t)rdc_buffer;
|
||||
ccw->count = rdc_buffer_size;
|
||||
|
||||
cqr->device = device;
|
||||
cqr->expires = 10*HZ;
|
||||
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
|
||||
cqr->retries = 2;
|
||||
cqr->buildclk = get_clock();
|
||||
cqr->status = DASD_CQR_FILLED;
|
||||
return cqr;
|
||||
}
|
||||
|
||||
|
||||
int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic,
|
||||
void **rdc_buffer, int rdc_buffer_size)
|
||||
{
|
||||
int ret;
|
||||
struct dasd_ccw_req *cqr;
|
||||
|
||||
cqr = dasd_generic_build_rdc(device, *rdc_buffer, rdc_buffer_size,
|
||||
magic);
|
||||
if (IS_ERR(cqr))
|
||||
return PTR_ERR(cqr);
|
||||
|
||||
ret = dasd_sleep_on(cqr);
|
||||
dasd_sfree_request(cqr, cqr->device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init
|
||||
dasd_init(void)
|
||||
|
|
|
@ -450,6 +450,81 @@ dasd_eckd_generate_uid(struct dasd_device *device, struct dasd_uid *uid)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct dasd_ccw_req * dasd_eckd_build_rcd_lpm(struct dasd_device *device,
|
||||
void *rcd_buffer,
|
||||
struct ciw *ciw, __u8 lpm)
|
||||
{
|
||||
struct dasd_ccw_req *cqr;
|
||||
struct ccw1 *ccw;
|
||||
|
||||
cqr = dasd_smalloc_request("ECKD", 1 /* RCD */, ciw->count, device);
|
||||
|
||||
if (IS_ERR(cqr)) {
|
||||
DEV_MESSAGE(KERN_WARNING, device, "%s",
|
||||
"Could not allocate RCD request");
|
||||
return cqr;
|
||||
}
|
||||
|
||||
ccw = cqr->cpaddr;
|
||||
ccw->cmd_code = ciw->cmd;
|
||||
ccw->cda = (__u32)(addr_t)rcd_buffer;
|
||||
ccw->count = ciw->count;
|
||||
|
||||
cqr->device = device;
|
||||
cqr->expires = 10*HZ;
|
||||
cqr->lpm = lpm;
|
||||
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
|
||||
cqr->retries = 2;
|
||||
cqr->buildclk = get_clock();
|
||||
cqr->status = DASD_CQR_FILLED;
|
||||
return cqr;
|
||||
}
|
||||
|
||||
static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
|
||||
void **rcd_buffer,
|
||||
int *rcd_buffer_size, __u8 lpm)
|
||||
{
|
||||
struct ciw *ciw;
|
||||
char *rcd_buf = NULL;
|
||||
int ret;
|
||||
struct dasd_ccw_req *cqr;
|
||||
|
||||
/*
|
||||
* scan for RCD command in extended SenseID data
|
||||
*/
|
||||
ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD);
|
||||
if (!ciw || ciw->cmd == 0) {
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out_error;
|
||||
}
|
||||
rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA);
|
||||
if (!rcd_buf) {
|
||||
ret = -ENOMEM;
|
||||
goto out_error;
|
||||
}
|
||||
cqr = dasd_eckd_build_rcd_lpm(device, rcd_buf, ciw, lpm);
|
||||
if (IS_ERR(cqr)) {
|
||||
ret = PTR_ERR(cqr);
|
||||
goto out_error;
|
||||
}
|
||||
ret = dasd_sleep_on(cqr);
|
||||
/*
|
||||
* on success we update the user input parms
|
||||
*/
|
||||
dasd_sfree_request(cqr, cqr->device);
|
||||
if (ret)
|
||||
goto out_error;
|
||||
|
||||
*rcd_buffer_size = ciw->count;
|
||||
*rcd_buffer = rcd_buf;
|
||||
return 0;
|
||||
out_error:
|
||||
kfree(rcd_buf);
|
||||
*rcd_buffer = NULL;
|
||||
*rcd_buffer_size = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
dasd_eckd_read_conf(struct dasd_device *device)
|
||||
{
|
||||
|
@ -469,7 +544,7 @@ dasd_eckd_read_conf(struct dasd_device *device)
|
|||
/* get configuration data per operational path */
|
||||
for (lpm = 0x80; lpm; lpm>>= 1) {
|
||||
if (lpm & path_data->opm){
|
||||
rc = read_conf_data_lpm(device->cdev, &conf_data,
|
||||
rc = dasd_eckd_read_conf_lpm(device, &conf_data,
|
||||
&conf_len, lpm);
|
||||
if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */
|
||||
MESSAGE(KERN_WARNING,
|
||||
|
@ -639,7 +714,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
|
|||
/* Read Device Characteristics */
|
||||
rdc_data = (void *) &(private->rdc_data);
|
||||
memset(rdc_data, 0, sizeof(rdc_data));
|
||||
rc = read_dev_chars(device->cdev, &rdc_data, 64);
|
||||
rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64);
|
||||
if (rc)
|
||||
DEV_MESSAGE(KERN_WARNING, device,
|
||||
"Read device characteristics returned "
|
||||
|
|
|
@ -135,7 +135,7 @@ dasd_fba_check_characteristics(struct dasd_device *device)
|
|||
}
|
||||
/* Read Device Characteristics */
|
||||
rdc_data = (void *) &(private->rdc_data);
|
||||
rc = read_dev_chars(device->cdev, &rdc_data, 32);
|
||||
rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32);
|
||||
if (rc) {
|
||||
DEV_MESSAGE(KERN_WARNING, device,
|
||||
"Read device characteristics returned error %d",
|
||||
|
|
|
@ -509,6 +509,8 @@ int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *);
|
|||
int dasd_generic_set_offline (struct ccw_device *cdev);
|
||||
int dasd_generic_notify(struct ccw_device *, int);
|
||||
|
||||
int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int);
|
||||
|
||||
/* externals in dasd_devmap.c */
|
||||
extern int dasd_max_devindex;
|
||||
extern int dasd_probeonly;
|
||||
|
|
Loading…
Reference in New Issue