diff options
Diffstat (limited to 'drivers/s390/block/dasd_eckd.c')
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index a41c94053e64..cf0cfdba1244 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1097,20 +1097,20 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1097 | { | 1097 | { |
1098 | struct dasd_eckd_private *private; | 1098 | struct dasd_eckd_private *private; |
1099 | struct dasd_block *block; | 1099 | struct dasd_block *block; |
1100 | void *rdc_data; | ||
1101 | int is_known, rc; | 1100 | int is_known, rc; |
1102 | 1101 | ||
1103 | private = (struct dasd_eckd_private *) device->private; | 1102 | private = (struct dasd_eckd_private *) device->private; |
1104 | if (private == NULL) { | 1103 | if (!private) { |
1105 | private = kzalloc(sizeof(struct dasd_eckd_private), | 1104 | private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA); |
1106 | GFP_KERNEL | GFP_DMA); | 1105 | if (!private) { |
1107 | if (private == NULL) { | ||
1108 | dev_warn(&device->cdev->dev, | 1106 | dev_warn(&device->cdev->dev, |
1109 | "Allocating memory for private DASD data " | 1107 | "Allocating memory for private DASD data " |
1110 | "failed\n"); | 1108 | "failed\n"); |
1111 | return -ENOMEM; | 1109 | return -ENOMEM; |
1112 | } | 1110 | } |
1113 | device->private = (void *) private; | 1111 | device->private = (void *) private; |
1112 | } else { | ||
1113 | memset(private, 0, sizeof(*private)); | ||
1114 | } | 1114 | } |
1115 | /* Invalidate status of initial analysis. */ | 1115 | /* Invalidate status of initial analysis. */ |
1116 | private->init_cqr_status = -1; | 1116 | private->init_cqr_status = -1; |
@@ -1161,9 +1161,8 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1161 | goto out_err3; | 1161 | goto out_err3; |
1162 | 1162 | ||
1163 | /* Read Device Characteristics */ | 1163 | /* Read Device Characteristics */ |
1164 | rdc_data = (void *) &(private->rdc_data); | 1164 | rc = dasd_generic_read_dev_chars(device, "ECKD", &private->rdc_data, |
1165 | memset(rdc_data, 0, sizeof(rdc_data)); | 1165 | 64); |
1166 | rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64); | ||
1167 | if (rc) { | 1166 | if (rc) { |
1168 | DBF_EVENT(DBF_WARNING, | 1167 | DBF_EVENT(DBF_WARNING, |
1169 | "Read device characteristics failed, rc=%d for " | 1168 | "Read device characteristics failed, rc=%d for " |
@@ -1183,7 +1182,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1183 | private->rdc_data.dev_model, | 1182 | private->rdc_data.dev_model, |
1184 | private->rdc_data.cu_type, | 1183 | private->rdc_data.cu_type, |
1185 | private->rdc_data.cu_model.model, | 1184 | private->rdc_data.cu_model.model, |
1186 | private->real_cyl, | 1185 | private->real_cyl, |
1187 | private->rdc_data.trk_per_cyl, | 1186 | private->rdc_data.trk_per_cyl, |
1188 | private->rdc_data.sec_per_trk); | 1187 | private->rdc_data.sec_per_trk); |
1189 | return 0; | 1188 | return 0; |
@@ -2336,9 +2335,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, | |||
2336 | { | 2335 | { |
2337 | int tpm, cmdrtd, cmdwtd; | 2336 | int tpm, cmdrtd, cmdwtd; |
2338 | int use_prefix; | 2337 | int use_prefix; |
2339 | 2338 | #if defined(CONFIG_64BIT) | |
2340 | struct dasd_eckd_private *private; | ||
2341 | int fcx_in_css, fcx_in_gneq, fcx_in_features; | 2339 | int fcx_in_css, fcx_in_gneq, fcx_in_features; |
2340 | #endif | ||
2341 | struct dasd_eckd_private *private; | ||
2342 | struct dasd_device *basedev; | 2342 | struct dasd_device *basedev; |
2343 | sector_t first_rec, last_rec; | 2343 | sector_t first_rec, last_rec; |
2344 | sector_t first_trk, last_trk; | 2344 | sector_t first_trk, last_trk; |
@@ -2361,11 +2361,15 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, | |||
2361 | last_offs = sector_div(last_trk, blk_per_trk); | 2361 | last_offs = sector_div(last_trk, blk_per_trk); |
2362 | cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk); | 2362 | cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk); |
2363 | 2363 | ||
2364 | /* is transport mode supported ? */ | 2364 | /* is transport mode supported? */ |
2365 | #if defined(CONFIG_64BIT) | ||
2365 | fcx_in_css = css_general_characteristics.fcx; | 2366 | fcx_in_css = css_general_characteristics.fcx; |
2366 | fcx_in_gneq = private->gneq->reserved2[7] & 0x04; | 2367 | fcx_in_gneq = private->gneq->reserved2[7] & 0x04; |
2367 | fcx_in_features = private->features.feature[40] & 0x80; | 2368 | fcx_in_features = private->features.feature[40] & 0x80; |
2368 | tpm = fcx_in_css && fcx_in_gneq && fcx_in_features; | 2369 | tpm = fcx_in_css && fcx_in_gneq && fcx_in_features; |
2370 | #else | ||
2371 | tpm = 0; | ||
2372 | #endif | ||
2369 | 2373 | ||
2370 | /* is read track data and write track data in command mode supported? */ | 2374 | /* is read track data and write track data in command mode supported? */ |
2371 | cmdrtd = private->features.feature[9] & 0x20; | 2375 | cmdrtd = private->features.feature[9] & 0x20; |
@@ -3013,8 +3017,9 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device, | |||
3013 | " I/O status report for device %s:\n", | 3017 | " I/O status report for device %s:\n", |
3014 | dev_name(&device->cdev->dev)); | 3018 | dev_name(&device->cdev->dev)); |
3015 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 3019 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER |
3016 | " in req: %p CS: 0x%02X DS: 0x%02X\n", req, | 3020 | " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n", |
3017 | scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw)); | 3021 | req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw), |
3022 | scsw_cc(&irb->scsw), req->intrc); | ||
3018 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 3023 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER |
3019 | " device %s: Failing CCW: %p\n", | 3024 | " device %s: Failing CCW: %p\n", |
3020 | dev_name(&device->cdev->dev), | 3025 | dev_name(&device->cdev->dev), |
@@ -3115,9 +3120,10 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device, | |||
3115 | " I/O status report for device %s:\n", | 3120 | " I/O status report for device %s:\n", |
3116 | dev_name(&device->cdev->dev)); | 3121 | dev_name(&device->cdev->dev)); |
3117 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 3122 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER |
3118 | " in req: %p CS: 0x%02X DS: 0x%02X " | 3123 | " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d " |
3119 | "fcxs: 0x%02X schxs: 0x%02X\n", req, | 3124 | "fcxs: 0x%02X schxs: 0x%02X\n", req, |
3120 | scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw), | 3125 | scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw), |
3126 | scsw_cc(&irb->scsw), req->intrc, | ||
3121 | irb->scsw.tm.fcxs, irb->scsw.tm.schxs); | 3127 | irb->scsw.tm.fcxs, irb->scsw.tm.schxs); |
3122 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 3128 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER |
3123 | " device %s: Failing TCW: %p\n", | 3129 | " device %s: Failing TCW: %p\n", |
@@ -3273,8 +3279,14 @@ static struct dasd_discipline dasd_eckd_discipline = { | |||
3273 | static int __init | 3279 | static int __init |
3274 | dasd_eckd_init(void) | 3280 | dasd_eckd_init(void) |
3275 | { | 3281 | { |
3282 | int ret; | ||
3283 | |||
3276 | ASCEBC(dasd_eckd_discipline.ebcname, 4); | 3284 | ASCEBC(dasd_eckd_discipline.ebcname, 4); |
3277 | return ccw_driver_register(&dasd_eckd_driver); | 3285 | ret = ccw_driver_register(&dasd_eckd_driver); |
3286 | if (!ret) | ||
3287 | wait_for_device_probe(); | ||
3288 | |||
3289 | return ret; | ||
3278 | } | 3290 | } |
3279 | 3291 | ||
3280 | static void __exit | 3292 | static void __exit |