diff options
Diffstat (limited to 'drivers/s390/block/dasd_eckd.c')
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 170 |
1 files changed, 111 insertions, 59 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 417b97cd3f94..5819dc02a143 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <asm/idals.h> | 24 | #include <asm/idals.h> |
25 | #include <asm/ebcdic.h> | 25 | #include <asm/ebcdic.h> |
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <asm/todclk.h> | ||
28 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
29 | #include <asm/cio.h> | 28 | #include <asm/cio.h> |
30 | #include <asm/ccwdev.h> | 29 | #include <asm/ccwdev.h> |
@@ -78,6 +77,11 @@ MODULE_DEVICE_TABLE(ccw, dasd_eckd_ids); | |||
78 | 77 | ||
79 | static struct ccw_driver dasd_eckd_driver; /* see below */ | 78 | static struct ccw_driver dasd_eckd_driver; /* see below */ |
80 | 79 | ||
80 | #define INIT_CQR_OK 0 | ||
81 | #define INIT_CQR_UNFORMATTED 1 | ||
82 | #define INIT_CQR_ERROR 2 | ||
83 | |||
84 | |||
81 | /* initial attempt at a probe function. this can be simplified once | 85 | /* initial attempt at a probe function. this can be simplified once |
82 | * the other detection code is gone */ | 86 | * the other detection code is gone */ |
83 | static int | 87 | static int |
@@ -86,11 +90,12 @@ dasd_eckd_probe (struct ccw_device *cdev) | |||
86 | int ret; | 90 | int ret; |
87 | 91 | ||
88 | /* set ECKD specific ccw-device options */ | 92 | /* set ECKD specific ccw-device options */ |
89 | ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE); | 93 | ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE | |
94 | CCWDEV_DO_PATHGROUP | CCWDEV_DO_MULTIPATH); | ||
90 | if (ret) { | 95 | if (ret) { |
91 | DBF_EVENT(DBF_WARNING, | 96 | DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s", |
92 | "dasd_eckd_probe: could not set ccw-device options " | 97 | "dasd_eckd_probe: could not set " |
93 | "for %s\n", dev_name(&cdev->dev)); | 98 | "ccw-device options"); |
94 | return ret; | 99 | return ret; |
95 | } | 100 | } |
96 | ret = dasd_generic_probe(cdev, &dasd_eckd_discipline); | 101 | ret = dasd_generic_probe(cdev, &dasd_eckd_discipline); |
@@ -749,8 +754,7 @@ static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device, | |||
749 | cqr->block = NULL; | 754 | cqr->block = NULL; |
750 | cqr->expires = 10*HZ; | 755 | cqr->expires = 10*HZ; |
751 | cqr->lpm = lpm; | 756 | cqr->lpm = lpm; |
752 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 757 | cqr->retries = 256; |
753 | cqr->retries = 2; | ||
754 | cqr->buildclk = get_clock(); | 758 | cqr->buildclk = get_clock(); |
755 | cqr->status = DASD_CQR_FILLED; | 759 | cqr->status = DASD_CQR_FILLED; |
756 | return cqr; | 760 | return cqr; |
@@ -885,16 +889,15 @@ static int dasd_eckd_read_conf(struct dasd_device *device) | |||
885 | rc = dasd_eckd_read_conf_lpm(device, &conf_data, | 889 | rc = dasd_eckd_read_conf_lpm(device, &conf_data, |
886 | &conf_len, lpm); | 890 | &conf_len, lpm); |
887 | if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */ | 891 | if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */ |
888 | DBF_EVENT(DBF_WARNING, | 892 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, |
889 | "Read configuration data returned " | 893 | "Read configuration data returned " |
890 | "error %d for device: %s", rc, | 894 | "error %d", rc); |
891 | dev_name(&device->cdev->dev)); | ||
892 | return rc; | 895 | return rc; |
893 | } | 896 | } |
894 | if (conf_data == NULL) { | 897 | if (conf_data == NULL) { |
895 | DBF_EVENT(DBF_WARNING, "No configuration " | 898 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", |
896 | "data retrieved for device: %s", | 899 | "No configuration data " |
897 | dev_name(&device->cdev->dev)); | 900 | "retrieved"); |
898 | continue; /* no error */ | 901 | continue; /* no error */ |
899 | } | 902 | } |
900 | /* save first valid configuration data */ | 903 | /* save first valid configuration data */ |
@@ -941,16 +944,14 @@ static int dasd_eckd_read_features(struct dasd_device *device) | |||
941 | sizeof(struct dasd_rssd_features)), | 944 | sizeof(struct dasd_rssd_features)), |
942 | device); | 945 | device); |
943 | if (IS_ERR(cqr)) { | 946 | if (IS_ERR(cqr)) { |
944 | DBF_EVENT(DBF_WARNING, "Could not allocate initialization " | 947 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", "Could not " |
945 | "request for device: %s", | 948 | "allocate initialization request"); |
946 | dev_name(&device->cdev->dev)); | ||
947 | return PTR_ERR(cqr); | 949 | return PTR_ERR(cqr); |
948 | } | 950 | } |
949 | cqr->startdev = device; | 951 | cqr->startdev = device; |
950 | cqr->memdev = device; | 952 | cqr->memdev = device; |
951 | cqr->block = NULL; | 953 | cqr->block = NULL; |
952 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 954 | cqr->retries = 256; |
953 | cqr->retries = 5; | ||
954 | cqr->expires = 10 * HZ; | 955 | cqr->expires = 10 * HZ; |
955 | 956 | ||
956 | /* Prepare for Read Subsystem Data */ | 957 | /* Prepare for Read Subsystem Data */ |
@@ -1012,9 +1013,9 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device, | |||
1012 | } | 1013 | } |
1013 | psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data; | 1014 | psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data; |
1014 | psf_ssc_data->order = PSF_ORDER_SSC; | 1015 | psf_ssc_data->order = PSF_ORDER_SSC; |
1015 | psf_ssc_data->suborder = 0x40; | 1016 | psf_ssc_data->suborder = 0xc0; |
1016 | if (enable_pav) { | 1017 | if (enable_pav) { |
1017 | psf_ssc_data->suborder |= 0x88; | 1018 | psf_ssc_data->suborder |= 0x08; |
1018 | psf_ssc_data->reserved[0] = 0x88; | 1019 | psf_ssc_data->reserved[0] = 0x88; |
1019 | } | 1020 | } |
1020 | ccw = cqr->cpaddr; | 1021 | ccw = cqr->cpaddr; |
@@ -1025,6 +1026,7 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device, | |||
1025 | cqr->startdev = device; | 1026 | cqr->startdev = device; |
1026 | cqr->memdev = device; | 1027 | cqr->memdev = device; |
1027 | cqr->block = NULL; | 1028 | cqr->block = NULL; |
1029 | cqr->retries = 256; | ||
1028 | cqr->expires = 10*HZ; | 1030 | cqr->expires = 10*HZ; |
1029 | cqr->buildclk = get_clock(); | 1031 | cqr->buildclk = get_clock(); |
1030 | cqr->status = DASD_CQR_FILLED; | 1032 | cqr->status = DASD_CQR_FILLED; |
@@ -1057,7 +1059,7 @@ dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav) | |||
1057 | /* | 1059 | /* |
1058 | * Valide storage server of current device. | 1060 | * Valide storage server of current device. |
1059 | */ | 1061 | */ |
1060 | static int dasd_eckd_validate_server(struct dasd_device *device) | 1062 | static void dasd_eckd_validate_server(struct dasd_device *device) |
1061 | { | 1063 | { |
1062 | int rc; | 1064 | int rc; |
1063 | struct dasd_eckd_private *private; | 1065 | struct dasd_eckd_private *private; |
@@ -1068,15 +1070,12 @@ static int dasd_eckd_validate_server(struct dasd_device *device) | |||
1068 | else | 1070 | else |
1069 | enable_pav = 1; | 1071 | enable_pav = 1; |
1070 | rc = dasd_eckd_psf_ssc(device, enable_pav); | 1072 | rc = dasd_eckd_psf_ssc(device, enable_pav); |
1073 | |||
1071 | /* may be requested feature is not available on server, | 1074 | /* may be requested feature is not available on server, |
1072 | * therefore just report error and go ahead */ | 1075 | * therefore just report error and go ahead */ |
1073 | private = (struct dasd_eckd_private *) device->private; | 1076 | private = (struct dasd_eckd_private *) device->private; |
1074 | DBF_EVENT(DBF_WARNING, "PSF-SSC on storage subsystem %s.%s.%04x " | 1077 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x " |
1075 | "returned rc=%d for device: %s", | 1078 | "returned rc=%d", private->uid.ssid, rc); |
1076 | private->uid.vendor, private->uid.serial, | ||
1077 | private->uid.ssid, rc, dev_name(&device->cdev->dev)); | ||
1078 | /* RE-Read Configuration Data */ | ||
1079 | return dasd_eckd_read_conf(device); | ||
1080 | } | 1079 | } |
1081 | 1080 | ||
1082 | /* | 1081 | /* |
@@ -1090,6 +1089,15 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1090 | struct dasd_block *block; | 1089 | struct dasd_block *block; |
1091 | int is_known, rc; | 1090 | int is_known, rc; |
1092 | 1091 | ||
1092 | if (!ccw_device_is_pathgroup(device->cdev)) { | ||
1093 | dev_warn(&device->cdev->dev, | ||
1094 | "A channel path group could not be established\n"); | ||
1095 | return -EIO; | ||
1096 | } | ||
1097 | if (!ccw_device_is_multipath(device->cdev)) { | ||
1098 | dev_info(&device->cdev->dev, | ||
1099 | "The DASD is not operating in multipath mode\n"); | ||
1100 | } | ||
1093 | private = (struct dasd_eckd_private *) device->private; | 1101 | private = (struct dasd_eckd_private *) device->private; |
1094 | if (!private) { | 1102 | if (!private) { |
1095 | private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA); | 1103 | private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA); |
@@ -1123,9 +1131,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1123 | if (private->uid.type == UA_BASE_DEVICE) { | 1131 | if (private->uid.type == UA_BASE_DEVICE) { |
1124 | block = dasd_alloc_block(); | 1132 | block = dasd_alloc_block(); |
1125 | if (IS_ERR(block)) { | 1133 | if (IS_ERR(block)) { |
1126 | DBF_EVENT(DBF_WARNING, "could not allocate dasd " | 1134 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", |
1127 | "block structure for device: %s", | 1135 | "could not allocate dasd " |
1128 | dev_name(&device->cdev->dev)); | 1136 | "block structure"); |
1129 | rc = PTR_ERR(block); | 1137 | rc = PTR_ERR(block); |
1130 | goto out_err1; | 1138 | goto out_err1; |
1131 | } | 1139 | } |
@@ -1139,12 +1147,21 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1139 | rc = is_known; | 1147 | rc = is_known; |
1140 | goto out_err2; | 1148 | goto out_err2; |
1141 | } | 1149 | } |
1150 | /* | ||
1151 | * dasd_eckd_vaildate_server is done on the first device that | ||
1152 | * is found for an LCU. All later other devices have to wait | ||
1153 | * for it, so they will read the correct feature codes. | ||
1154 | */ | ||
1142 | if (!is_known) { | 1155 | if (!is_known) { |
1143 | /* new lcu found */ | 1156 | dasd_eckd_validate_server(device); |
1144 | rc = dasd_eckd_validate_server(device); /* will switch pav on */ | 1157 | dasd_alias_lcu_setup_complete(device); |
1145 | if (rc) | 1158 | } else |
1146 | goto out_err3; | 1159 | dasd_alias_wait_for_lcu_setup(device); |
1147 | } | 1160 | |
1161 | /* device may report different configuration data after LCU setup */ | ||
1162 | rc = dasd_eckd_read_conf(device); | ||
1163 | if (rc) | ||
1164 | goto out_err3; | ||
1148 | 1165 | ||
1149 | /* Read Feature Codes */ | 1166 | /* Read Feature Codes */ |
1150 | dasd_eckd_read_features(device); | 1167 | dasd_eckd_read_features(device); |
@@ -1153,9 +1170,8 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1153 | rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, | 1170 | rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, |
1154 | &private->rdc_data, 64); | 1171 | &private->rdc_data, 64); |
1155 | if (rc) { | 1172 | if (rc) { |
1156 | DBF_EVENT(DBF_WARNING, | 1173 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, |
1157 | "Read device characteristics failed, rc=%d for " | 1174 | "Read device characteristic failed, rc=%d", rc); |
1158 | "device: %s", rc, dev_name(&device->cdev->dev)); | ||
1159 | goto out_err3; | 1175 | goto out_err3; |
1160 | } | 1176 | } |
1161 | /* find the vaild cylinder size */ | 1177 | /* find the vaild cylinder size */ |
@@ -1256,12 +1272,29 @@ dasd_eckd_analysis_ccw(struct dasd_device *device) | |||
1256 | cqr->block = NULL; | 1272 | cqr->block = NULL; |
1257 | cqr->startdev = device; | 1273 | cqr->startdev = device; |
1258 | cqr->memdev = device; | 1274 | cqr->memdev = device; |
1259 | cqr->retries = 0; | 1275 | cqr->retries = 255; |
1260 | cqr->buildclk = get_clock(); | 1276 | cqr->buildclk = get_clock(); |
1261 | cqr->status = DASD_CQR_FILLED; | 1277 | cqr->status = DASD_CQR_FILLED; |
1262 | return cqr; | 1278 | return cqr; |
1263 | } | 1279 | } |
1264 | 1280 | ||
1281 | /* differentiate between 'no record found' and any other error */ | ||
1282 | static int dasd_eckd_analysis_evaluation(struct dasd_ccw_req *init_cqr) | ||
1283 | { | ||
1284 | char *sense; | ||
1285 | if (init_cqr->status == DASD_CQR_DONE) | ||
1286 | return INIT_CQR_OK; | ||
1287 | else if (init_cqr->status == DASD_CQR_NEED_ERP || | ||
1288 | init_cqr->status == DASD_CQR_FAILED) { | ||
1289 | sense = dasd_get_sense(&init_cqr->irb); | ||
1290 | if (sense && (sense[1] & SNS1_NO_REC_FOUND)) | ||
1291 | return INIT_CQR_UNFORMATTED; | ||
1292 | else | ||
1293 | return INIT_CQR_ERROR; | ||
1294 | } else | ||
1295 | return INIT_CQR_ERROR; | ||
1296 | } | ||
1297 | |||
1265 | /* | 1298 | /* |
1266 | * This is the callback function for the init_analysis cqr. It saves | 1299 | * This is the callback function for the init_analysis cqr. It saves |
1267 | * the status of the initial analysis ccw before it frees it and kicks | 1300 | * the status of the initial analysis ccw before it frees it and kicks |
@@ -1269,21 +1302,20 @@ dasd_eckd_analysis_ccw(struct dasd_device *device) | |||
1269 | * dasd_eckd_do_analysis again (if the devices has not been marked | 1302 | * dasd_eckd_do_analysis again (if the devices has not been marked |
1270 | * for deletion in the meantime). | 1303 | * for deletion in the meantime). |
1271 | */ | 1304 | */ |
1272 | static void | 1305 | static void dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr, |
1273 | dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr, void *data) | 1306 | void *data) |
1274 | { | 1307 | { |
1275 | struct dasd_eckd_private *private; | 1308 | struct dasd_eckd_private *private; |
1276 | struct dasd_device *device; | 1309 | struct dasd_device *device; |
1277 | 1310 | ||
1278 | device = init_cqr->startdev; | 1311 | device = init_cqr->startdev; |
1279 | private = (struct dasd_eckd_private *) device->private; | 1312 | private = (struct dasd_eckd_private *) device->private; |
1280 | private->init_cqr_status = init_cqr->status; | 1313 | private->init_cqr_status = dasd_eckd_analysis_evaluation(init_cqr); |
1281 | dasd_sfree_request(init_cqr, device); | 1314 | dasd_sfree_request(init_cqr, device); |
1282 | dasd_kick_device(device); | 1315 | dasd_kick_device(device); |
1283 | } | 1316 | } |
1284 | 1317 | ||
1285 | static int | 1318 | static int dasd_eckd_start_analysis(struct dasd_block *block) |
1286 | dasd_eckd_start_analysis(struct dasd_block *block) | ||
1287 | { | 1319 | { |
1288 | struct dasd_eckd_private *private; | 1320 | struct dasd_eckd_private *private; |
1289 | struct dasd_ccw_req *init_cqr; | 1321 | struct dasd_ccw_req *init_cqr; |
@@ -1295,27 +1327,44 @@ dasd_eckd_start_analysis(struct dasd_block *block) | |||
1295 | init_cqr->callback = dasd_eckd_analysis_callback; | 1327 | init_cqr->callback = dasd_eckd_analysis_callback; |
1296 | init_cqr->callback_data = NULL; | 1328 | init_cqr->callback_data = NULL; |
1297 | init_cqr->expires = 5*HZ; | 1329 | init_cqr->expires = 5*HZ; |
1330 | /* first try without ERP, so we can later handle unformatted | ||
1331 | * devices as special case | ||
1332 | */ | ||
1333 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &init_cqr->flags); | ||
1334 | init_cqr->retries = 0; | ||
1298 | dasd_add_request_head(init_cqr); | 1335 | dasd_add_request_head(init_cqr); |
1299 | return -EAGAIN; | 1336 | return -EAGAIN; |
1300 | } | 1337 | } |
1301 | 1338 | ||
1302 | static int | 1339 | static int dasd_eckd_end_analysis(struct dasd_block *block) |
1303 | dasd_eckd_end_analysis(struct dasd_block *block) | ||
1304 | { | 1340 | { |
1305 | struct dasd_device *device; | 1341 | struct dasd_device *device; |
1306 | struct dasd_eckd_private *private; | 1342 | struct dasd_eckd_private *private; |
1307 | struct eckd_count *count_area; | 1343 | struct eckd_count *count_area; |
1308 | unsigned int sb, blk_per_trk; | 1344 | unsigned int sb, blk_per_trk; |
1309 | int status, i; | 1345 | int status, i; |
1346 | struct dasd_ccw_req *init_cqr; | ||
1310 | 1347 | ||
1311 | device = block->base; | 1348 | device = block->base; |
1312 | private = (struct dasd_eckd_private *) device->private; | 1349 | private = (struct dasd_eckd_private *) device->private; |
1313 | status = private->init_cqr_status; | 1350 | status = private->init_cqr_status; |
1314 | private->init_cqr_status = -1; | 1351 | private->init_cqr_status = -1; |
1315 | if (status != DASD_CQR_DONE) { | 1352 | if (status == INIT_CQR_ERROR) { |
1316 | dev_warn(&device->cdev->dev, | 1353 | /* try again, this time with full ERP */ |
1317 | "The DASD is not formatted\n"); | 1354 | init_cqr = dasd_eckd_analysis_ccw(device); |
1355 | dasd_sleep_on(init_cqr); | ||
1356 | status = dasd_eckd_analysis_evaluation(init_cqr); | ||
1357 | dasd_sfree_request(init_cqr, device); | ||
1358 | } | ||
1359 | |||
1360 | if (status == INIT_CQR_UNFORMATTED) { | ||
1361 | dev_warn(&device->cdev->dev, "The DASD is not formatted\n"); | ||
1318 | return -EMEDIUMTYPE; | 1362 | return -EMEDIUMTYPE; |
1363 | } else if (status == INIT_CQR_ERROR) { | ||
1364 | dev_err(&device->cdev->dev, | ||
1365 | "Detecting the DASD disk layout failed because " | ||
1366 | "of an I/O error\n"); | ||
1367 | return -EIO; | ||
1319 | } | 1368 | } |
1320 | 1369 | ||
1321 | private->uses_cdl = 1; | 1370 | private->uses_cdl = 1; |
@@ -1607,8 +1656,7 @@ dasd_eckd_format_device(struct dasd_device * device, | |||
1607 | } | 1656 | } |
1608 | fcp->startdev = device; | 1657 | fcp->startdev = device; |
1609 | fcp->memdev = device; | 1658 | fcp->memdev = device; |
1610 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &fcp->flags); | 1659 | fcp->retries = 256; |
1611 | fcp->retries = 5; /* set retry counter to enable default ERP */ | ||
1612 | fcp->buildclk = get_clock(); | 1660 | fcp->buildclk = get_clock(); |
1613 | fcp->status = DASD_CQR_FILLED; | 1661 | fcp->status = DASD_CQR_FILLED; |
1614 | return fcp; | 1662 | return fcp; |
@@ -2690,6 +2738,7 @@ dasd_eckd_performance(struct dasd_device *device, void __user *argp) | |||
2690 | cqr->startdev = device; | 2738 | cqr->startdev = device; |
2691 | cqr->memdev = device; | 2739 | cqr->memdev = device; |
2692 | cqr->retries = 0; | 2740 | cqr->retries = 0; |
2741 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | ||
2693 | cqr->expires = 10 * HZ; | 2742 | cqr->expires = 10 * HZ; |
2694 | 2743 | ||
2695 | /* Prepare for Read Subsystem Data */ | 2744 | /* Prepare for Read Subsystem Data */ |
@@ -3240,11 +3289,15 @@ int dasd_eckd_restore_device(struct dasd_device *device) | |||
3240 | if (is_known < 0) | 3289 | if (is_known < 0) |
3241 | return is_known; | 3290 | return is_known; |
3242 | if (!is_known) { | 3291 | if (!is_known) { |
3243 | /* new lcu found */ | 3292 | dasd_eckd_validate_server(device); |
3244 | rc = dasd_eckd_validate_server(device); /* will switch pav on */ | 3293 | dasd_alias_lcu_setup_complete(device); |
3245 | if (rc) | 3294 | } else |
3246 | goto out_err; | 3295 | dasd_alias_wait_for_lcu_setup(device); |
3247 | } | 3296 | |
3297 | /* RE-Read Configuration Data */ | ||
3298 | rc = dasd_eckd_read_conf(device); | ||
3299 | if (rc) | ||
3300 | goto out_err; | ||
3248 | 3301 | ||
3249 | /* Read Feature Codes */ | 3302 | /* Read Feature Codes */ |
3250 | dasd_eckd_read_features(device); | 3303 | dasd_eckd_read_features(device); |
@@ -3253,9 +3306,8 @@ int dasd_eckd_restore_device(struct dasd_device *device) | |||
3253 | rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, | 3306 | rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, |
3254 | &temp_rdc_data, 64); | 3307 | &temp_rdc_data, 64); |
3255 | if (rc) { | 3308 | if (rc) { |
3256 | DBF_EVENT(DBF_WARNING, | 3309 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, |
3257 | "Read device characteristics failed, rc=%d for " | 3310 | "Read device characteristic failed, rc=%d", rc); |
3258 | "device: %s", rc, dev_name(&device->cdev->dev)); | ||
3259 | goto out_err; | 3311 | goto out_err; |
3260 | } | 3312 | } |
3261 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 3313 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |