diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2007-05-04 12:47:51 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-05-04 12:48:26 -0400 |
commit | 17283b56eceb6b7d9cc48dc74759a2450699c22a (patch) | |
tree | ded19dee693d1b712c0f5117610b21eb4761d017 /drivers/s390 | |
parent | 52706ec903dcc7679acf5b93400d68fbc5384553 (diff) |
[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>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd.c | 45 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 81 | ||||
-rw-r--r-- | drivers/s390/block/dasd_fba.c | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 2 |
4 files changed, 126 insertions, 4 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index e71929db8b06..977521013fe8 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -2174,6 +2174,51 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
2174 | return ret; | 2174 | return ret; |
2175 | } | 2175 | } |
2176 | 2176 | ||
2177 | struct dasd_ccw_req * dasd_generic_build_rdc(struct dasd_device *device, | ||
2178 | void *rdc_buffer, | ||
2179 | int rdc_buffer_size, char *magic) | ||
2180 | { | ||
2181 | struct dasd_ccw_req *cqr; | ||
2182 | struct ccw1 *ccw; | ||
2183 | |||
2184 | cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device); | ||
2185 | |||
2186 | if (IS_ERR(cqr)) { | ||
2187 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
2188 | "Could not allocate RDC request"); | ||
2189 | return cqr; | ||
2190 | } | ||
2191 | |||
2192 | ccw = cqr->cpaddr; | ||
2193 | ccw->cmd_code = CCW_CMD_RDC; | ||
2194 | ccw->cda = (__u32)(addr_t)rdc_buffer; | ||
2195 | ccw->count = rdc_buffer_size; | ||
2196 | |||
2197 | cqr->device = device; | ||
2198 | cqr->expires = 10*HZ; | ||
2199 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | ||
2200 | cqr->retries = 2; | ||
2201 | cqr->buildclk = get_clock(); | ||
2202 | cqr->status = DASD_CQR_FILLED; | ||
2203 | return cqr; | ||
2204 | } | ||
2205 | |||
2206 | |||
2207 | int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic, | ||
2208 | void **rdc_buffer, int rdc_buffer_size) | ||
2209 | { | ||
2210 | int ret; | ||
2211 | struct dasd_ccw_req *cqr; | ||
2212 | |||
2213 | cqr = dasd_generic_build_rdc(device, *rdc_buffer, rdc_buffer_size, | ||
2214 | magic); | ||
2215 | if (IS_ERR(cqr)) | ||
2216 | return PTR_ERR(cqr); | ||
2217 | |||
2218 | ret = dasd_sleep_on(cqr); | ||
2219 | dasd_sfree_request(cqr, cqr->device); | ||
2220 | return ret; | ||
2221 | } | ||
2177 | 2222 | ||
2178 | static int __init | 2223 | static int __init |
2179 | dasd_init(void) | 2224 | dasd_init(void) |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index cecab2274a6e..c9583fbc2a7d 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -450,6 +450,81 @@ dasd_eckd_generate_uid(struct dasd_device *device, struct dasd_uid *uid) | |||
450 | return 0; | 450 | return 0; |
451 | } | 451 | } |
452 | 452 | ||
453 | struct dasd_ccw_req * dasd_eckd_build_rcd_lpm(struct dasd_device *device, | ||
454 | void *rcd_buffer, | ||
455 | struct ciw *ciw, __u8 lpm) | ||
456 | { | ||
457 | struct dasd_ccw_req *cqr; | ||
458 | struct ccw1 *ccw; | ||
459 | |||
460 | cqr = dasd_smalloc_request("ECKD", 1 /* RCD */, ciw->count, device); | ||
461 | |||
462 | if (IS_ERR(cqr)) { | ||
463 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
464 | "Could not allocate RCD request"); | ||
465 | return cqr; | ||
466 | } | ||
467 | |||
468 | ccw = cqr->cpaddr; | ||
469 | ccw->cmd_code = ciw->cmd; | ||
470 | ccw->cda = (__u32)(addr_t)rcd_buffer; | ||
471 | ccw->count = ciw->count; | ||
472 | |||
473 | cqr->device = device; | ||
474 | cqr->expires = 10*HZ; | ||
475 | cqr->lpm = lpm; | ||
476 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | ||
477 | cqr->retries = 2; | ||
478 | cqr->buildclk = get_clock(); | ||
479 | cqr->status = DASD_CQR_FILLED; | ||
480 | return cqr; | ||
481 | } | ||
482 | |||
483 | static int dasd_eckd_read_conf_lpm(struct dasd_device *device, | ||
484 | void **rcd_buffer, | ||
485 | int *rcd_buffer_size, __u8 lpm) | ||
486 | { | ||
487 | struct ciw *ciw; | ||
488 | char *rcd_buf = NULL; | ||
489 | int ret; | ||
490 | struct dasd_ccw_req *cqr; | ||
491 | |||
492 | /* | ||
493 | * scan for RCD command in extended SenseID data | ||
494 | */ | ||
495 | ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD); | ||
496 | if (!ciw || ciw->cmd == 0) { | ||
497 | ret = -EOPNOTSUPP; | ||
498 | goto out_error; | ||
499 | } | ||
500 | rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA); | ||
501 | if (!rcd_buf) { | ||
502 | ret = -ENOMEM; | ||
503 | goto out_error; | ||
504 | } | ||
505 | cqr = dasd_eckd_build_rcd_lpm(device, rcd_buf, ciw, lpm); | ||
506 | if (IS_ERR(cqr)) { | ||
507 | ret = PTR_ERR(cqr); | ||
508 | goto out_error; | ||
509 | } | ||
510 | ret = dasd_sleep_on(cqr); | ||
511 | /* | ||
512 | * on success we update the user input parms | ||
513 | */ | ||
514 | dasd_sfree_request(cqr, cqr->device); | ||
515 | if (ret) | ||
516 | goto out_error; | ||
517 | |||
518 | *rcd_buffer_size = ciw->count; | ||
519 | *rcd_buffer = rcd_buf; | ||
520 | return 0; | ||
521 | out_error: | ||
522 | kfree(rcd_buf); | ||
523 | *rcd_buffer = NULL; | ||
524 | *rcd_buffer_size = 0; | ||
525 | return ret; | ||
526 | } | ||
527 | |||
453 | static int | 528 | static int |
454 | dasd_eckd_read_conf(struct dasd_device *device) | 529 | dasd_eckd_read_conf(struct dasd_device *device) |
455 | { | 530 | { |
@@ -469,8 +544,8 @@ dasd_eckd_read_conf(struct dasd_device *device) | |||
469 | /* get configuration data per operational path */ | 544 | /* get configuration data per operational path */ |
470 | for (lpm = 0x80; lpm; lpm>>= 1) { | 545 | for (lpm = 0x80; lpm; lpm>>= 1) { |
471 | if (lpm & path_data->opm){ | 546 | if (lpm & path_data->opm){ |
472 | rc = read_conf_data_lpm(device->cdev, &conf_data, | 547 | rc = dasd_eckd_read_conf_lpm(device, &conf_data, |
473 | &conf_len, lpm); | 548 | &conf_len, lpm); |
474 | if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */ | 549 | if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */ |
475 | MESSAGE(KERN_WARNING, | 550 | MESSAGE(KERN_WARNING, |
476 | "Read configuration data returned " | 551 | "Read configuration data returned " |
@@ -639,7 +714,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
639 | /* Read Device Characteristics */ | 714 | /* Read Device Characteristics */ |
640 | rdc_data = (void *) &(private->rdc_data); | 715 | rdc_data = (void *) &(private->rdc_data); |
641 | memset(rdc_data, 0, sizeof(rdc_data)); | 716 | memset(rdc_data, 0, sizeof(rdc_data)); |
642 | rc = read_dev_chars(device->cdev, &rdc_data, 64); | 717 | rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64); |
643 | if (rc) | 718 | if (rc) |
644 | DEV_MESSAGE(KERN_WARNING, device, | 719 | DEV_MESSAGE(KERN_WARNING, device, |
645 | "Read device characteristics returned " | 720 | "Read device characteristics returned " |
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index be0909e39226..da16ead8aff2 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
@@ -135,7 +135,7 @@ dasd_fba_check_characteristics(struct dasd_device *device) | |||
135 | } | 135 | } |
136 | /* Read Device Characteristics */ | 136 | /* Read Device Characteristics */ |
137 | rdc_data = (void *) &(private->rdc_data); | 137 | rdc_data = (void *) &(private->rdc_data); |
138 | rc = read_dev_chars(device->cdev, &rdc_data, 32); | 138 | rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32); |
139 | if (rc) { | 139 | if (rc) { |
140 | DEV_MESSAGE(KERN_WARNING, device, | 140 | DEV_MESSAGE(KERN_WARNING, device, |
141 | "Read device characteristics returned error %d", | 141 | "Read device characteristics returned error %d", |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index a2cc69e11410..241294cba415 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -509,6 +509,8 @@ int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); | |||
509 | int dasd_generic_set_offline (struct ccw_device *cdev); | 509 | int dasd_generic_set_offline (struct ccw_device *cdev); |
510 | int dasd_generic_notify(struct ccw_device *, int); | 510 | int dasd_generic_notify(struct ccw_device *, int); |
511 | 511 | ||
512 | int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int); | ||
513 | |||
512 | /* externals in dasd_devmap.c */ | 514 | /* externals in dasd_devmap.c */ |
513 | extern int dasd_max_devindex; | 515 | extern int dasd_max_devindex; |
514 | extern int dasd_probeonly; | 516 | extern int dasd_probeonly; |