aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ipr.c
diff options
context:
space:
mode:
authorWayne Boyer <wayneb@linux.vnet.ibm.com>2010-02-19 16:24:07 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-03-03 05:34:59 -0500
commit4565e3706329f65b5e64328b5369c53b6ab2715c (patch)
tree08a226d36be5ba667bbd2e0224e77021338774b9 /drivers/scsi/ipr.c
parent3e7ebdfa58ddaef361f9538219e66a7226fb1e5d (diff)
[SCSI] ipr: add error handling updates for the next generation chip
Add support for the new log data notification and overlay IDs. Signed-off-by: Wayne Boyer <wayneb@linux.vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r--drivers/scsi/ipr.c257
1 files changed, 247 insertions, 10 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 91e330a12721..b2e60bd4a0c6 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -1079,7 +1079,7 @@ static char *ipr_format_resource_path(u8 *res_path, char *buffer)
1079 1079
1080 sprintf(buffer, "%02X", res_path[0]); 1080 sprintf(buffer, "%02X", res_path[0]);
1081 for (i=1; res_path[i] != 0xff; i++) 1081 for (i=1; res_path[i] != 0xff; i++)
1082 sprintf(buffer, "%s:%02X", buffer, res_path[i]); 1082 sprintf(buffer, "%s-%02X", buffer, res_path[i]);
1083 1083
1084 return buffer; 1084 return buffer;
1085} 1085}
@@ -1385,8 +1385,12 @@ static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd)
1385static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg, 1385static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg,
1386 struct ipr_hostrcb *hostrcb) 1386 struct ipr_hostrcb *hostrcb)
1387{ 1387{
1388 struct ipr_hostrcb_type_12_error *error = 1388 struct ipr_hostrcb_type_12_error *error;
1389 &hostrcb->hcam.u.error.u.type_12_error; 1389
1390 if (ioa_cfg->sis64)
1391 error = &hostrcb->hcam.u.error64.u.type_12_error;
1392 else
1393 error = &hostrcb->hcam.u.error.u.type_12_error;
1390 1394
1391 ipr_err("-----Current Configuration-----\n"); 1395 ipr_err("-----Current Configuration-----\n");
1392 ipr_err("Cache Directory Card Information:\n"); 1396 ipr_err("Cache Directory Card Information:\n");
@@ -1479,6 +1483,48 @@ static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg,
1479} 1483}
1480 1484
1481/** 1485/**
1486 * ipr_log_sis64_config_error - Log a device error.
1487 * @ioa_cfg: ioa config struct
1488 * @hostrcb: hostrcb struct
1489 *
1490 * Return value:
1491 * none
1492 **/
1493static void ipr_log_sis64_config_error(struct ipr_ioa_cfg *ioa_cfg,
1494 struct ipr_hostrcb *hostrcb)
1495{
1496 int errors_logged, i;
1497 struct ipr_hostrcb64_device_data_entry_enhanced *dev_entry;
1498 struct ipr_hostrcb_type_23_error *error;
1499 char buffer[IPR_MAX_RES_PATH_LENGTH];
1500
1501 error = &hostrcb->hcam.u.error64.u.type_23_error;
1502 errors_logged = be32_to_cpu(error->errors_logged);
1503
1504 ipr_err("Device Errors Detected/Logged: %d/%d\n",
1505 be32_to_cpu(error->errors_detected), errors_logged);
1506
1507 dev_entry = error->dev;
1508
1509 for (i = 0; i < errors_logged; i++, dev_entry++) {
1510 ipr_err_separator;
1511
1512 ipr_err("Device %d : %s", i + 1,
1513 ipr_format_resource_path(&dev_entry->res_path[0], &buffer[0]));
1514 ipr_log_ext_vpd(&dev_entry->vpd);
1515
1516 ipr_err("-----New Device Information-----\n");
1517 ipr_log_ext_vpd(&dev_entry->new_vpd);
1518
1519 ipr_err("Cache Directory Card Information:\n");
1520 ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd);
1521
1522 ipr_err("Adapter Card Information:\n");
1523 ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd);
1524 }
1525}
1526
1527/**
1482 * ipr_log_config_error - Log a configuration error. 1528 * ipr_log_config_error - Log a configuration error.
1483 * @ioa_cfg: ioa config struct 1529 * @ioa_cfg: ioa config struct
1484 * @hostrcb: hostrcb struct 1530 * @hostrcb: hostrcb struct
@@ -1672,7 +1718,11 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg,
1672{ 1718{
1673 struct ipr_hostrcb_type_17_error *error; 1719 struct ipr_hostrcb_type_17_error *error;
1674 1720
1675 error = &hostrcb->hcam.u.error.u.type_17_error; 1721 if (ioa_cfg->sis64)
1722 error = &hostrcb->hcam.u.error64.u.type_17_error;
1723 else
1724 error = &hostrcb->hcam.u.error.u.type_17_error;
1725
1676 error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; 1726 error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
1677 strim(error->failure_reason); 1727 strim(error->failure_reason);
1678 1728
@@ -1779,6 +1829,42 @@ static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb,
1779 fabric->ioa_port, fabric->cascaded_expander, fabric->phy); 1829 fabric->ioa_port, fabric->cascaded_expander, fabric->phy);
1780} 1830}
1781 1831
1832/**
1833 * ipr_log64_fabric_path - Log a fabric path error
1834 * @hostrcb: hostrcb struct
1835 * @fabric: fabric descriptor
1836 *
1837 * Return value:
1838 * none
1839 **/
1840static void ipr_log64_fabric_path(struct ipr_hostrcb *hostrcb,
1841 struct ipr_hostrcb64_fabric_desc *fabric)
1842{
1843 int i, j;
1844 u8 path_state = fabric->path_state;
1845 u8 active = path_state & IPR_PATH_ACTIVE_MASK;
1846 u8 state = path_state & IPR_PATH_STATE_MASK;
1847 char buffer[IPR_MAX_RES_PATH_LENGTH];
1848
1849 for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) {
1850 if (path_active_desc[i].active != active)
1851 continue;
1852
1853 for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) {
1854 if (path_state_desc[j].state != state)
1855 continue;
1856
1857 ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s\n",
1858 path_active_desc[i].desc, path_state_desc[j].desc,
1859 ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
1860 return;
1861 }
1862 }
1863
1864 ipr_err("Path state=%02X Resource Path=%s\n", path_state,
1865 ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
1866}
1867
1782static const struct { 1868static const struct {
1783 u8 type; 1869 u8 type;
1784 char *desc; 1870 char *desc;
@@ -1888,6 +1974,49 @@ static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb,
1888} 1974}
1889 1975
1890/** 1976/**
1977 * ipr_log64_path_elem - Log a fabric path element.
1978 * @hostrcb: hostrcb struct
1979 * @cfg: fabric path element struct
1980 *
1981 * Return value:
1982 * none
1983 **/
1984static void ipr_log64_path_elem(struct ipr_hostrcb *hostrcb,
1985 struct ipr_hostrcb64_config_element *cfg)
1986{
1987 int i, j;
1988 u8 desc_id = cfg->descriptor_id & IPR_DESCRIPTOR_MASK;
1989 u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK;
1990 u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK;
1991 char buffer[IPR_MAX_RES_PATH_LENGTH];
1992
1993 if (type == IPR_PATH_CFG_NOT_EXIST || desc_id != IPR_DESCRIPTOR_SIS64)
1994 return;
1995
1996 for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) {
1997 if (path_type_desc[i].type != type)
1998 continue;
1999
2000 for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) {
2001 if (path_status_desc[j].status != status)
2002 continue;
2003
2004 ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s, Link rate=%s, WWN=%08X%08X\n",
2005 path_status_desc[j].desc, path_type_desc[i].desc,
2006 ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
2007 link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
2008 be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
2009 return;
2010 }
2011 }
2012 ipr_hcam_err(hostrcb, "Path element=%02X: Resource Path=%s, Link rate=%s "
2013 "WWN=%08X%08X\n", cfg->type_status,
2014 ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
2015 link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
2016 be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
2017}
2018
2019/**
1891 * ipr_log_fabric_error - Log a fabric error. 2020 * ipr_log_fabric_error - Log a fabric error.
1892 * @ioa_cfg: ioa config struct 2021 * @ioa_cfg: ioa config struct
1893 * @hostrcb: hostrcb struct 2022 * @hostrcb: hostrcb struct
@@ -1925,6 +2054,96 @@ static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg,
1925} 2054}
1926 2055
1927/** 2056/**
2057 * ipr_log_sis64_array_error - Log a sis64 array error.
2058 * @ioa_cfg: ioa config struct
2059 * @hostrcb: hostrcb struct
2060 *
2061 * Return value:
2062 * none
2063 **/
2064static void ipr_log_sis64_array_error(struct ipr_ioa_cfg *ioa_cfg,
2065 struct ipr_hostrcb *hostrcb)
2066{
2067 int i, num_entries;
2068 struct ipr_hostrcb_type_24_error *error;
2069 struct ipr_hostrcb64_array_data_entry *array_entry;
2070 char buffer[IPR_MAX_RES_PATH_LENGTH];
2071 const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' };
2072
2073 error = &hostrcb->hcam.u.error64.u.type_24_error;
2074
2075 ipr_err_separator;
2076
2077 ipr_err("RAID %s Array Configuration: %s\n",
2078 error->protection_level,
2079 ipr_format_resource_path(&error->last_res_path[0], &buffer[0]));
2080
2081 ipr_err_separator;
2082
2083 array_entry = error->array_member;
2084 num_entries = min_t(u32, be32_to_cpu(error->num_entries),
2085 sizeof(error->array_member));
2086
2087 for (i = 0; i < num_entries; i++, array_entry++) {
2088
2089 if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN))
2090 continue;
2091
2092 if (error->exposed_mode_adn == i)
2093 ipr_err("Exposed Array Member %d:\n", i);
2094 else
2095 ipr_err("Array Member %d:\n", i);
2096
2097 ipr_err("Array Member %d:\n", i);
2098 ipr_log_ext_vpd(&array_entry->vpd);
2099 ipr_err("Current Location: %s",
2100 ipr_format_resource_path(&array_entry->res_path[0], &buffer[0]));
2101 ipr_err("Expected Location: %s",
2102 ipr_format_resource_path(&array_entry->expected_res_path[0], &buffer[0]));
2103
2104 ipr_err_separator;
2105 }
2106}
2107
2108/**
2109 * ipr_log_sis64_fabric_error - Log a sis64 fabric error.
2110 * @ioa_cfg: ioa config struct
2111 * @hostrcb: hostrcb struct
2112 *
2113 * Return value:
2114 * none
2115 **/
2116static void ipr_log_sis64_fabric_error(struct ipr_ioa_cfg *ioa_cfg,
2117 struct ipr_hostrcb *hostrcb)
2118{
2119 struct ipr_hostrcb_type_30_error *error;
2120 struct ipr_hostrcb64_fabric_desc *fabric;
2121 struct ipr_hostrcb64_config_element *cfg;
2122 int i, add_len;
2123
2124 error = &hostrcb->hcam.u.error64.u.type_30_error;
2125
2126 error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
2127 ipr_hcam_err(hostrcb, "%s\n", error->failure_reason);
2128
2129 add_len = be32_to_cpu(hostrcb->hcam.length) -
2130 (offsetof(struct ipr_hostrcb64_error, u) +
2131 offsetof(struct ipr_hostrcb_type_30_error, desc));
2132
2133 for (i = 0, fabric = error->desc; i < error->num_entries; i++) {
2134 ipr_log64_fabric_path(hostrcb, fabric);
2135 for_each_fabric_cfg(fabric, cfg)
2136 ipr_log64_path_elem(hostrcb, cfg);
2137
2138 add_len -= be16_to_cpu(fabric->length);
2139 fabric = (struct ipr_hostrcb64_fabric_desc *)
2140 ((unsigned long)fabric + be16_to_cpu(fabric->length));
2141 }
2142
2143 ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len);
2144}
2145
2146/**
1928 * ipr_log_generic_error - Log an adapter error. 2147 * ipr_log_generic_error - Log an adapter error.
1929 * @ioa_cfg: ioa config struct 2148 * @ioa_cfg: ioa config struct
1930 * @hostrcb: hostrcb struct 2149 * @hostrcb: hostrcb struct
@@ -1983,13 +2202,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
1983 if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST) 2202 if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST)
1984 dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n"); 2203 dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n");
1985 2204
1986 ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); 2205 if (ioa_cfg->sis64)
2206 ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc);
2207 else
2208 ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
1987 2209
1988 if (ioasc == IPR_IOASC_BUS_WAS_RESET || 2210 if (!ioa_cfg->sis64 && (ioasc == IPR_IOASC_BUS_WAS_RESET ||
1989 ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER) { 2211 ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER)) {
1990 /* Tell the midlayer we had a bus reset so it will handle the UA properly */ 2212 /* Tell the midlayer we had a bus reset so it will handle the UA properly */
1991 scsi_report_bus_reset(ioa_cfg->host, 2213 scsi_report_bus_reset(ioa_cfg->host,
1992 hostrcb->hcam.u.error.failing_dev_res_addr.bus); 2214 hostrcb->hcam.u.error.fd_res_addr.bus);
1993 } 2215 }
1994 2216
1995 error_index = ipr_get_error(ioasc); 2217 error_index = ipr_get_error(ioasc);
@@ -2037,6 +2259,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
2037 case IPR_HOST_RCB_OVERLAY_ID_20: 2259 case IPR_HOST_RCB_OVERLAY_ID_20:
2038 ipr_log_fabric_error(ioa_cfg, hostrcb); 2260 ipr_log_fabric_error(ioa_cfg, hostrcb);
2039 break; 2261 break;
2262 case IPR_HOST_RCB_OVERLAY_ID_23:
2263 ipr_log_sis64_config_error(ioa_cfg, hostrcb);
2264 break;
2265 case IPR_HOST_RCB_OVERLAY_ID_24:
2266 case IPR_HOST_RCB_OVERLAY_ID_26:
2267 ipr_log_sis64_array_error(ioa_cfg, hostrcb);
2268 break;
2269 case IPR_HOST_RCB_OVERLAY_ID_30:
2270 ipr_log_sis64_fabric_error(ioa_cfg, hostrcb);
2271 break;
2040 case IPR_HOST_RCB_OVERLAY_ID_1: 2272 case IPR_HOST_RCB_OVERLAY_ID_1:
2041 case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: 2273 case IPR_HOST_RCB_OVERLAY_ID_DEFAULT:
2042 default: 2274 default:
@@ -2061,7 +2293,12 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd)
2061 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; 2293 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
2062 struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; 2294 struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb;
2063 u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); 2295 u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
2064 u32 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); 2296 u32 fd_ioasc;
2297
2298 if (ioa_cfg->sis64)
2299 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc);
2300 else
2301 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
2065 2302
2066 list_del(&hostrcb->queue); 2303 list_del(&hostrcb->queue);
2067 list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); 2304 list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
@@ -6996,7 +7233,7 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
6996 7233
6997 if (!rc) { 7234 if (!rc) {
6998 ipr_handle_log_data(ioa_cfg, hostrcb); 7235 ipr_handle_log_data(ioa_cfg, hostrcb);
6999 ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); 7236 ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
7000 if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED && 7237 if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED &&
7001 ioa_cfg->sdt_state == GET_DUMP) 7238 ioa_cfg->sdt_state == GET_DUMP)
7002 ioa_cfg->sdt_state = WAIT_FOR_DUMP; 7239 ioa_cfg->sdt_state = WAIT_FOR_DUMP;