aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block')
-rw-r--r--drivers/s390/block/dasd.c45
-rw-r--r--drivers/s390/block/dasd_eckd.c81
-rw-r--r--drivers/s390/block/dasd_fba.c2
-rw-r--r--drivers/s390/block/dasd_int.h2
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
2177struct 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
2207int 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
2178static int __init 2223static int __init
2179dasd_init(void) 2224dasd_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
453struct 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
483static 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;
521out_error:
522 kfree(rcd_buf);
523 *rcd_buffer = NULL;
524 *rcd_buffer_size = 0;
525 return ret;
526}
527
453static int 528static int
454dasd_eckd_read_conf(struct dasd_device *device) 529dasd_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 *);
509int dasd_generic_set_offline (struct ccw_device *cdev); 509int dasd_generic_set_offline (struct ccw_device *cdev);
510int dasd_generic_notify(struct ccw_device *, int); 510int dasd_generic_notify(struct ccw_device *, int);
511 511
512int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int);
513
512/* externals in dasd_devmap.c */ 514/* externals in dasd_devmap.c */
513extern int dasd_max_devindex; 515extern int dasd_max_devindex;
514extern int dasd_probeonly; 516extern int dasd_probeonly;