diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/ipr.c | 78 |
1 files changed, 72 insertions, 6 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index d4e6dbfac7d1..d9f208343a24 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -953,6 +953,53 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd) | |||
953 | } | 953 | } |
954 | 954 | ||
955 | /** | 955 | /** |
956 | * strip_and_pad_whitespace - Strip and pad trailing whitespace. | ||
957 | * @i: index into buffer | ||
958 | * @buf: string to modify | ||
959 | * | ||
960 | * This function will strip all trailing whitespace, pad the end | ||
961 | * of the string with a single space, and NULL terminate the string. | ||
962 | * | ||
963 | * Return value: | ||
964 | * new length of string | ||
965 | **/ | ||
966 | static int strip_and_pad_whitespace(int i, char *buf) | ||
967 | { | ||
968 | while (i && buf[i] == ' ') | ||
969 | i--; | ||
970 | buf[i+1] = ' '; | ||
971 | buf[i+2] = '\0'; | ||
972 | return i + 2; | ||
973 | } | ||
974 | |||
975 | /** | ||
976 | * ipr_log_vpd_compact - Log the passed extended VPD compactly. | ||
977 | * @prefix: string to print at start of printk | ||
978 | * @hostrcb: hostrcb pointer | ||
979 | * @vpd: vendor/product id/sn struct | ||
980 | * | ||
981 | * Return value: | ||
982 | * none | ||
983 | **/ | ||
984 | static void ipr_log_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb, | ||
985 | struct ipr_vpd *vpd) | ||
986 | { | ||
987 | char buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN + IPR_SERIAL_NUM_LEN + 3]; | ||
988 | int i = 0; | ||
989 | |||
990 | memcpy(buffer, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN); | ||
991 | i = strip_and_pad_whitespace(IPR_VENDOR_ID_LEN - 1, buffer); | ||
992 | |||
993 | memcpy(&buffer[i], vpd->vpids.product_id, IPR_PROD_ID_LEN); | ||
994 | i = strip_and_pad_whitespace(i + IPR_PROD_ID_LEN - 1, buffer); | ||
995 | |||
996 | memcpy(&buffer[i], vpd->sn, IPR_SERIAL_NUM_LEN); | ||
997 | buffer[IPR_SERIAL_NUM_LEN + i] = '\0'; | ||
998 | |||
999 | ipr_hcam_err(hostrcb, "%s VPID/SN: %s\n", prefix, buffer); | ||
1000 | } | ||
1001 | |||
1002 | /** | ||
956 | * ipr_log_vpd - Log the passed VPD to the error log. | 1003 | * ipr_log_vpd - Log the passed VPD to the error log. |
957 | * @vpd: vendor/product id/sn struct | 1004 | * @vpd: vendor/product id/sn struct |
958 | * | 1005 | * |
@@ -976,6 +1023,23 @@ static void ipr_log_vpd(struct ipr_vpd *vpd) | |||
976 | } | 1023 | } |
977 | 1024 | ||
978 | /** | 1025 | /** |
1026 | * ipr_log_ext_vpd_compact - Log the passed extended VPD compactly. | ||
1027 | * @prefix: string to print at start of printk | ||
1028 | * @hostrcb: hostrcb pointer | ||
1029 | * @vpd: vendor/product id/sn/wwn struct | ||
1030 | * | ||
1031 | * Return value: | ||
1032 | * none | ||
1033 | **/ | ||
1034 | static void ipr_log_ext_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb, | ||
1035 | struct ipr_ext_vpd *vpd) | ||
1036 | { | ||
1037 | ipr_log_vpd_compact(prefix, hostrcb, &vpd->vpd); | ||
1038 | ipr_hcam_err(hostrcb, "%s WWN: %08X%08X\n", prefix, | ||
1039 | be32_to_cpu(vpd->wwid[0]), be32_to_cpu(vpd->wwid[1])); | ||
1040 | } | ||
1041 | |||
1042 | /** | ||
979 | * ipr_log_ext_vpd - Log the passed extended VPD to the error log. | 1043 | * ipr_log_ext_vpd - Log the passed extended VPD to the error log. |
980 | * @vpd: vendor/product id/sn/wwn struct | 1044 | * @vpd: vendor/product id/sn/wwn struct |
981 | * | 1045 | * |
@@ -1289,10 +1353,11 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1289 | 1353 | ||
1290 | error = &hostrcb->hcam.u.error.u.type_17_error; | 1354 | error = &hostrcb->hcam.u.error.u.type_17_error; |
1291 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; | 1355 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; |
1356 | strstrip(error->failure_reason); | ||
1292 | 1357 | ||
1293 | ipr_err("%s\n", error->failure_reason); | 1358 | ipr_hcam_err(hostrcb, "%s [PRC: %08X]\n", error->failure_reason, |
1294 | ipr_err("Remote Adapter VPD:\n"); | 1359 | be32_to_cpu(hostrcb->hcam.u.error.prc)); |
1295 | ipr_log_ext_vpd(&error->vpd); | 1360 | ipr_log_ext_vpd_compact("Remote IOA", hostrcb, &error->vpd); |
1296 | ipr_log_hex_data(ioa_cfg, error->data, | 1361 | ipr_log_hex_data(ioa_cfg, error->data, |
1297 | be32_to_cpu(hostrcb->hcam.length) - | 1362 | be32_to_cpu(hostrcb->hcam.length) - |
1298 | (offsetof(struct ipr_hostrcb_error, u) + | 1363 | (offsetof(struct ipr_hostrcb_error, u) + |
@@ -1314,10 +1379,11 @@ static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1314 | 1379 | ||
1315 | error = &hostrcb->hcam.u.error.u.type_07_error; | 1380 | error = &hostrcb->hcam.u.error.u.type_07_error; |
1316 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; | 1381 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; |
1382 | strstrip(error->failure_reason); | ||
1317 | 1383 | ||
1318 | ipr_err("%s\n", error->failure_reason); | 1384 | ipr_hcam_err(hostrcb, "%s [PRC: %08X]\n", error->failure_reason, |
1319 | ipr_err("Remote Adapter VPD:\n"); | 1385 | be32_to_cpu(hostrcb->hcam.u.error.prc)); |
1320 | ipr_log_vpd(&error->vpd); | 1386 | ipr_log_vpd_compact("Remote IOA", hostrcb, &error->vpd); |
1321 | ipr_log_hex_data(ioa_cfg, error->data, | 1387 | ipr_log_hex_data(ioa_cfg, error->data, |
1322 | be32_to_cpu(hostrcb->hcam.length) - | 1388 | be32_to_cpu(hostrcb->hcam.length) - |
1323 | (offsetof(struct ipr_hostrcb_error, u) + | 1389 | (offsetof(struct ipr_hostrcb_error, u) + |