aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2.h5
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h274
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_ioc.h18
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_raid.h14
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_tool.h16
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c152
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h37
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c197
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.h4
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c819
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c86
11 files changed, 1206 insertions, 416 deletions
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h
index f9f6c0839276..914168105297 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2.h
@@ -8,7 +8,7 @@
8 * scatter/gather formats. 8 * scatter/gather formats.
9 * Creation Date: June 21, 2006 9 * Creation Date: June 21, 2006
10 * 10 *
11 * mpi2.h Version: 02.00.12 11 * mpi2.h Version: 02.00.13
12 * 12 *
13 * Version History 13 * Version History
14 * --------------- 14 * ---------------
@@ -52,6 +52,7 @@
52 * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those 52 * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those
53 * bytes reserved. 53 * bytes reserved.
54 * Added RAID Accelerator functionality. 54 * Added RAID Accelerator functionality.
55 * 07-30-09 02.00.13 Bumped MPI2_HEADER_VERSION_UNIT.
55 * -------------------------------------------------------------------------- 56 * --------------------------------------------------------------------------
56 */ 57 */
57 58
@@ -77,7 +78,7 @@
77#define MPI2_VERSION_02_00 (0x0200) 78#define MPI2_VERSION_02_00 (0x0200)
78 79
79/* versioning for this MPI header set */ 80/* versioning for this MPI header set */
80#define MPI2_HEADER_VERSION_UNIT (0x0C) 81#define MPI2_HEADER_VERSION_UNIT (0x0D)
81#define MPI2_HEADER_VERSION_DEV (0x00) 82#define MPI2_HEADER_VERSION_DEV (0x00)
82#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) 83#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
83#define MPI2_HEADER_VERSION_UNIT_SHIFT (8) 84#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
index ab47c4679640..1611c57a6fdf 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
@@ -6,7 +6,7 @@
6 * Title: MPI Configuration messages and pages 6 * Title: MPI Configuration messages and pages
7 * Creation Date: November 10, 2006 7 * Creation Date: November 10, 2006
8 * 8 *
9 * mpi2_cnfg.h Version: 02.00.11 9 * mpi2_cnfg.h Version: 02.00.12
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -100,6 +100,13 @@
100 * Added expander reduced functionality data to SAS 100 * Added expander reduced functionality data to SAS
101 * Expander Page 0. 101 * Expander Page 0.
102 * Added SAS PHY Page 2 and SAS PHY Page 3. 102 * Added SAS PHY Page 2 and SAS PHY Page 3.
103 * 07-30-09 02.00.12 Added IO Unit Page 7.
104 * Added new device ids.
105 * Added SAS IO Unit Page 5.
106 * Added partial and slumber power management capable flags
107 * to SAS Device Page 0 Flags field.
108 * Added PhyInfo defines for power condition.
109 * Added Ethernet configuration pages.
103 * -------------------------------------------------------------------------- 110 * --------------------------------------------------------------------------
104 */ 111 */
105 112
@@ -182,6 +189,7 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION
182#define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG (0x16) 189#define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG (0x16)
183#define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING (0x17) 190#define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING (0x17)
184#define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT (0x18) 191#define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT (0x18)
192#define MPI2_CONFIG_EXTPAGETYPE_ETHERNET (0x19)
185 193
186 194
187/***************************************************************************** 195/*****************************************************************************
@@ -268,6 +276,14 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION
268#define MPI2_DPM_PGAD_START_ENTRY_MASK (0x0000FFFF) 276#define MPI2_DPM_PGAD_START_ENTRY_MASK (0x0000FFFF)
269 277
270 278
279/* Ethernet PageAddress format */
280#define MPI2_ETHERNET_PGAD_FORM_MASK (0xF0000000)
281#define MPI2_ETHERNET_PGAD_FORM_IF_NUM (0x00000000)
282
283#define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK (0x000000FF)
284
285
286
271/**************************************************************************** 287/****************************************************************************
272* Configuration messages 288* Configuration messages
273****************************************************************************/ 289****************************************************************************/
@@ -349,6 +365,15 @@ typedef struct _MPI2_CONFIG_REPLY
349#define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064) 365#define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064)
350#define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065) 366#define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065)
351 367
368#define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080)
369#define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081)
370#define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082)
371#define MPI2_MFGPAGE_DEVID_SAS2208_4 (0x0083)
372#define MPI2_MFGPAGE_DEVID_SAS2208_5 (0x0084)
373#define MPI2_MFGPAGE_DEVID_SAS2208_6 (0x0085)
374#define MPI2_MFGPAGE_DEVID_SAS2208_7 (0x0086)
375#define MPI2_MFGPAGE_DEVID_SAS2208_8 (0x0087)
376
352 377
353/* Manufacturing Page 0 */ 378/* Manufacturing Page 0 */
354 379
@@ -787,6 +812,56 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_6 {
787#define MPI2_IOUNITPAGE6_FLAGS_ENABLE_RAID_ACCELERATOR (0x0001) 812#define MPI2_IOUNITPAGE6_FLAGS_ENABLE_RAID_ACCELERATOR (0x0001)
788 813
789 814
815/* IO Unit Page 7 */
816
817typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
818 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
819 U16 Reserved1; /* 0x04 */
820 U8 PCIeWidth; /* 0x06 */
821 U8 PCIeSpeed; /* 0x07 */
822 U32 ProcessorState; /* 0x08 */
823 U32 Reserved2; /* 0x0C */
824 U16 IOCTemperature; /* 0x10 */
825 U8 IOCTemperatureUnits; /* 0x12 */
826 U8 IOCSpeed; /* 0x13 */
827 U32 Reserved3; /* 0x14 */
828} MPI2_CONFIG_PAGE_IO_UNIT_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_7,
829 Mpi2IOUnitPage7_t, MPI2_POINTER pMpi2IOUnitPage7_t;
830
831#define MPI2_IOUNITPAGE7_PAGEVERSION (0x00)
832
833/* defines for IO Unit Page 7 PCIeWidth field */
834#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X1 (0x01)
835#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X2 (0x02)
836#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X4 (0x04)
837#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X8 (0x08)
838
839/* defines for IO Unit Page 7 PCIeSpeed field */
840#define MPI2_IOUNITPAGE7_PCIE_SPEED_2_5_GBPS (0x00)
841#define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS (0x01)
842#define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS (0x02)
843
844/* defines for IO Unit Page 7 ProcessorState field */
845#define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND (0x0000000F)
846#define MPI2_IOUNITPAGE7_PSTATE_SHIFT_SECOND (0)
847
848#define MPI2_IOUNITPAGE7_PSTATE_NOT_PRESENT (0x00)
849#define MPI2_IOUNITPAGE7_PSTATE_DISABLED (0x01)
850#define MPI2_IOUNITPAGE7_PSTATE_ENABLED (0x02)
851
852/* defines for IO Unit Page 7 IOCTemperatureUnits field */
853#define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT (0x00)
854#define MPI2_IOUNITPAGE7_IOC_TEMP_FAHRENHEIT (0x01)
855#define MPI2_IOUNITPAGE7_IOC_TEMP_CELSIUS (0x02)
856
857/* defines for IO Unit Page 7 IOCSpeed field */
858#define MPI2_IOUNITPAGE7_IOC_SPEED_FULL (0x01)
859#define MPI2_IOUNITPAGE7_IOC_SPEED_HALF (0x02)
860#define MPI2_IOUNITPAGE7_IOC_SPEED_QUARTER (0x04)
861#define MPI2_IOUNITPAGE7_IOC_SPEED_EIGHTH (0x08)
862
863
864
790/**************************************************************************** 865/****************************************************************************
791* IOC Config Pages 866* IOC Config Pages
792****************************************************************************/ 867****************************************************************************/
@@ -1470,6 +1545,12 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
1470 1545
1471/* values for PhyInfo fields */ 1546/* values for PhyInfo fields */
1472#define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000) 1547#define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000)
1548
1549#define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK (0x18000000)
1550#define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE (0x00000000)
1551#define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL (0x08000000)
1552#define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER (0x10000000)
1553
1473#define MPI2_SAS_PHYINFO_CHANGED_REQ_INSIDE_ZPSDS (0x04000000) 1554#define MPI2_SAS_PHYINFO_CHANGED_REQ_INSIDE_ZPSDS (0x04000000)
1474#define MPI2_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT (0x02000000) 1555#define MPI2_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT (0x02000000)
1475#define MPI2_SAS_PHYINFO_REQ_INSIDE_ZPSDS (0x01000000) 1556#define MPI2_SAS_PHYINFO_REQ_INSIDE_ZPSDS (0x01000000)
@@ -1682,11 +1763,11 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1
1682/* values for SAS IO Unit Page 1 PortFlags */ 1763/* values for SAS IO Unit Page 1 PortFlags */
1683#define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01) 1764#define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01)
1684 1765
1685/* values for SAS IO Unit Page 2 PhyFlags */ 1766/* values for SAS IO Unit Page 1 PhyFlags */
1686#define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE (0x10) 1767#define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE (0x10)
1687#define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE (0x08) 1768#define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE (0x08)
1688 1769
1689/* values for SAS IO Unit Page 0 MaxMinLinkRate */ 1770/* values for SAS IO Unit Page 1 MaxMinLinkRate */
1690#define MPI2_SASIOUNIT1_MAX_RATE_MASK (0xF0) 1771#define MPI2_SASIOUNIT1_MAX_RATE_MASK (0xF0)
1691#define MPI2_SASIOUNIT1_MAX_RATE_1_5 (0x80) 1772#define MPI2_SASIOUNIT1_MAX_RATE_1_5 (0x80)
1692#define MPI2_SASIOUNIT1_MAX_RATE_3_0 (0x90) 1773#define MPI2_SASIOUNIT1_MAX_RATE_3_0 (0x90)
@@ -1745,6 +1826,74 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_4
1745#define MPI2_SASIOUNIT4_PHY_SPINUP_GROUP_MASK (0x03) 1826#define MPI2_SASIOUNIT4_PHY_SPINUP_GROUP_MASK (0x03)
1746 1827
1747 1828
1829/* SAS IO Unit Page 5 */
1830
1831typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS {
1832 U8 ControlFlags; /* 0x00 */
1833 U8 Reserved1; /* 0x01 */
1834 U16 InactivityTimerExponent; /* 0x02 */
1835 U8 SATAPartialTimeout; /* 0x04 */
1836 U8 Reserved2; /* 0x05 */
1837 U8 SATASlumberTimeout; /* 0x06 */
1838 U8 Reserved3; /* 0x07 */
1839 U8 SASPartialTimeout; /* 0x08 */
1840 U8 Reserved4; /* 0x09 */
1841 U8 SASSlumberTimeout; /* 0x0A */
1842 U8 Reserved5; /* 0x0B */
1843} MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS,
1844 MPI2_POINTER PTR_MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS,
1845 Mpi2SasIOUnit5PhyPmSettings_t, MPI2_POINTER pMpi2SasIOUnit5PhyPmSettings_t;
1846
1847/* defines for ControlFlags field */
1848#define MPI2_SASIOUNIT5_CONTROL_SAS_SLUMBER_ENABLE (0x08)
1849#define MPI2_SASIOUNIT5_CONTROL_SAS_PARTIAL_ENABLE (0x04)
1850#define MPI2_SASIOUNIT5_CONTROL_SATA_SLUMBER_ENABLE (0x02)
1851#define MPI2_SASIOUNIT5_CONTROL_SATA_PARTIAL_ENABLE (0x01)
1852
1853/* defines for InactivityTimerExponent field */
1854#define MPI2_SASIOUNIT5_ITE_MASK_SAS_SLUMBER (0x7000)
1855#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_SLUMBER (12)
1856#define MPI2_SASIOUNIT5_ITE_MASK_SAS_PARTIAL (0x0700)
1857#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_PARTIAL (8)
1858#define MPI2_SASIOUNIT5_ITE_MASK_SATA_SLUMBER (0x0070)
1859#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_SLUMBER (4)
1860#define MPI2_SASIOUNIT5_ITE_MASK_SATA_PARTIAL (0x0007)
1861#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_PARTIAL (0)
1862
1863#define MPI2_SASIOUNIT5_ITE_TEN_SECONDS (7)
1864#define MPI2_SASIOUNIT5_ITE_ONE_SECOND (6)
1865#define MPI2_SASIOUNIT5_ITE_HUNDRED_MILLISECONDS (5)
1866#define MPI2_SASIOUNIT5_ITE_TEN_MILLISECONDS (4)
1867#define MPI2_SASIOUNIT5_ITE_ONE_MILLISECOND (3)
1868#define MPI2_SASIOUNIT5_ITE_HUNDRED_MICROSECONDS (2)
1869#define MPI2_SASIOUNIT5_ITE_TEN_MICROSECONDS (1)
1870#define MPI2_SASIOUNIT5_ITE_ONE_MICROSECOND (0)
1871
1872/*
1873 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1874 * one and check Header.ExtPageLength or NumPhys at runtime.
1875 */
1876#ifndef MPI2_SAS_IOUNIT5_PHY_MAX
1877#define MPI2_SAS_IOUNIT5_PHY_MAX (1)
1878#endif
1879
1880typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_5 {
1881 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1882 U8 NumPhys; /* 0x08 */
1883 U8 Reserved1; /* 0x09 */
1884 U16 Reserved2; /* 0x0A */
1885 U32 Reserved3; /* 0x0C */
1886 MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS SASPhyPowerManagementSettings
1887 [MPI2_SAS_IOUNIT5_PHY_MAX]; /* 0x10 */
1888} MPI2_CONFIG_PAGE_SASIOUNIT_5,
1889 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_5,
1890 Mpi2SasIOUnitPage5_t, MPI2_POINTER pMpi2SasIOUnitPage5_t;
1891
1892#define MPI2_SASIOUNITPAGE5_PAGEVERSION (0x00)
1893
1894
1895
1896
1748/**************************************************************************** 1897/****************************************************************************
1749* SAS Expander Config Pages 1898* SAS Expander Config Pages
1750****************************************************************************/ 1899****************************************************************************/
@@ -1927,6 +2076,8 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0
1927/* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */ 2076/* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */
1928 2077
1929/* values for SAS Device Page 0 Flags field */ 2078/* values for SAS Device Page 0 Flags field */
2079#define MPI2_SAS_DEVICE0_FLAGS_SLUMBER_PM_CAPABLE (0x1000)
2080#define MPI2_SAS_DEVICE0_FLAGS_PARTIAL_PM_CAPABLE (0x0800)
1930#define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400) 2081#define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400)
1931#define MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200) 2082#define MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200)
1932#define MPI2_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100) 2083#define MPI2_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100)
@@ -2343,5 +2494,122 @@ typedef struct _MPI2_CONFIG_PAGE_DRIVER_MAPPING_0
2343#define MPI2_DRVMAP0_MAPINFO_MISSING_MASK (0x000F) 2494#define MPI2_DRVMAP0_MAPINFO_MISSING_MASK (0x000F)
2344 2495
2345 2496
2497/****************************************************************************
2498* Ethernet Config Pages
2499****************************************************************************/
2500
2501/* Ethernet Page 0 */
2502
2503/* IP address (union of IPv4 and IPv6) */
2504typedef union _MPI2_ETHERNET_IP_ADDR {
2505 U32 IPv4Addr;
2506 U32 IPv6Addr[4];
2507} MPI2_ETHERNET_IP_ADDR, MPI2_POINTER PTR_MPI2_ETHERNET_IP_ADDR,
2508 Mpi2EthernetIpAddr_t, MPI2_POINTER pMpi2EthernetIpAddr_t;
2509
2510#define MPI2_ETHERNET_HOST_NAME_LENGTH (32)
2511
2512typedef struct _MPI2_CONFIG_PAGE_ETHERNET_0 {
2513 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
2514 U8 NumInterfaces; /* 0x08 */
2515 U8 Reserved0; /* 0x09 */
2516 U16 Reserved1; /* 0x0A */
2517 U32 Status; /* 0x0C */
2518 U8 MediaState; /* 0x10 */
2519 U8 Reserved2; /* 0x11 */
2520 U16 Reserved3; /* 0x12 */
2521 U8 MacAddress[6]; /* 0x14 */
2522 U8 Reserved4; /* 0x1A */
2523 U8 Reserved5; /* 0x1B */
2524 MPI2_ETHERNET_IP_ADDR IpAddress; /* 0x1C */
2525 MPI2_ETHERNET_IP_ADDR SubnetMask; /* 0x2C */
2526 MPI2_ETHERNET_IP_ADDR GatewayIpAddress; /* 0x3C */
2527 MPI2_ETHERNET_IP_ADDR DNS1IpAddress; /* 0x4C */
2528 MPI2_ETHERNET_IP_ADDR DNS2IpAddress; /* 0x5C */
2529 MPI2_ETHERNET_IP_ADDR DhcpIpAddress; /* 0x6C */
2530 U8 HostName
2531 [MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */
2532} MPI2_CONFIG_PAGE_ETHERNET_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_0,
2533 Mpi2EthernetPage0_t, MPI2_POINTER pMpi2EthernetPage0_t;
2534
2535#define MPI2_ETHERNETPAGE0_PAGEVERSION (0x00)
2536
2537/* values for Ethernet Page 0 Status field */
2538#define MPI2_ETHPG0_STATUS_IPV6_CAPABLE (0x80000000)
2539#define MPI2_ETHPG0_STATUS_IPV4_CAPABLE (0x40000000)
2540#define MPI2_ETHPG0_STATUS_CONSOLE_CONNECTED (0x20000000)
2541#define MPI2_ETHPG0_STATUS_DEFAULT_IF (0x00000100)
2542#define MPI2_ETHPG0_STATUS_FW_DWNLD_ENABLED (0x00000080)
2543#define MPI2_ETHPG0_STATUS_TELNET_ENABLED (0x00000040)
2544#define MPI2_ETHPG0_STATUS_SSH2_ENABLED (0x00000020)
2545#define MPI2_ETHPG0_STATUS_DHCP_CLIENT_ENABLED (0x00000010)
2546#define MPI2_ETHPG0_STATUS_IPV6_ENABLED (0x00000008)
2547#define MPI2_ETHPG0_STATUS_IPV4_ENABLED (0x00000004)
2548#define MPI2_ETHPG0_STATUS_IPV6_ADDRESSES (0x00000002)
2549#define MPI2_ETHPG0_STATUS_ETH_IF_ENABLED (0x00000001)
2550
2551/* values for Ethernet Page 0 MediaState field */
2552#define MPI2_ETHPG0_MS_DUPLEX_MASK (0x80)
2553#define MPI2_ETHPG0_MS_HALF_DUPLEX (0x00)
2554#define MPI2_ETHPG0_MS_FULL_DUPLEX (0x80)
2555
2556#define MPI2_ETHPG0_MS_CONNECT_SPEED_MASK (0x07)
2557#define MPI2_ETHPG0_MS_NOT_CONNECTED (0x00)
2558#define MPI2_ETHPG0_MS_10MBIT (0x01)
2559#define MPI2_ETHPG0_MS_100MBIT (0x02)
2560#define MPI2_ETHPG0_MS_1GBIT (0x03)
2561
2562
2563/* Ethernet Page 1 */
2564
2565typedef struct _MPI2_CONFIG_PAGE_ETHERNET_1 {
2566 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
2567 U32 Reserved0; /* 0x08 */
2568 U32 Flags; /* 0x0C */
2569 U8 MediaState; /* 0x10 */
2570 U8 Reserved1; /* 0x11 */
2571 U16 Reserved2; /* 0x12 */
2572 U8 MacAddress[6]; /* 0x14 */
2573 U8 Reserved3; /* 0x1A */
2574 U8 Reserved4; /* 0x1B */
2575 MPI2_ETHERNET_IP_ADDR StaticIpAddress; /* 0x1C */
2576 MPI2_ETHERNET_IP_ADDR StaticSubnetMask; /* 0x2C */
2577 MPI2_ETHERNET_IP_ADDR StaticGatewayIpAddress; /* 0x3C */
2578 MPI2_ETHERNET_IP_ADDR StaticDNS1IpAddress; /* 0x4C */
2579 MPI2_ETHERNET_IP_ADDR StaticDNS2IpAddress; /* 0x5C */
2580 U32 Reserved5; /* 0x6C */
2581 U32 Reserved6; /* 0x70 */
2582 U32 Reserved7; /* 0x74 */
2583 U32 Reserved8; /* 0x78 */
2584 U8 HostName
2585 [MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */
2586} MPI2_CONFIG_PAGE_ETHERNET_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_1,
2587 Mpi2EthernetPage1_t, MPI2_POINTER pMpi2EthernetPage1_t;
2588
2589#define MPI2_ETHERNETPAGE1_PAGEVERSION (0x00)
2590
2591/* values for Ethernet Page 1 Flags field */
2592#define MPI2_ETHPG1_FLAG_SET_DEFAULT_IF (0x00000100)
2593#define MPI2_ETHPG1_FLAG_ENABLE_FW_DOWNLOAD (0x00000080)
2594#define MPI2_ETHPG1_FLAG_ENABLE_TELNET (0x00000040)
2595#define MPI2_ETHPG1_FLAG_ENABLE_SSH2 (0x00000020)
2596#define MPI2_ETHPG1_FLAG_ENABLE_DHCP_CLIENT (0x00000010)
2597#define MPI2_ETHPG1_FLAG_ENABLE_IPV6 (0x00000008)
2598#define MPI2_ETHPG1_FLAG_ENABLE_IPV4 (0x00000004)
2599#define MPI2_ETHPG1_FLAG_USE_IPV6_ADDRESSES (0x00000002)
2600#define MPI2_ETHPG1_FLAG_ENABLE_ETH_IF (0x00000001)
2601
2602/* values for Ethernet Page 1 MediaState field */
2603#define MPI2_ETHPG1_MS_DUPLEX_MASK (0x80)
2604#define MPI2_ETHPG1_MS_HALF_DUPLEX (0x00)
2605#define MPI2_ETHPG1_MS_FULL_DUPLEX (0x80)
2606
2607#define MPI2_ETHPG1_MS_DATA_RATE_MASK (0x07)
2608#define MPI2_ETHPG1_MS_DATA_RATE_AUTO (0x00)
2609#define MPI2_ETHPG1_MS_DATA_RATE_10MBIT (0x01)
2610#define MPI2_ETHPG1_MS_DATA_RATE_100MBIT (0x02)
2611#define MPI2_ETHPG1_MS_DATA_RATE_1GBIT (0x03)
2612
2613
2346#endif 2614#endif
2347 2615
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
index c294128bdeb4..ea51ce868690 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
@@ -6,7 +6,7 @@
6 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages 6 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
7 * Creation Date: October 11, 2006 7 * Creation Date: October 11, 2006
8 * 8 *
9 * mpi2_ioc.h Version: 02.00.11 9 * mpi2_ioc.h Version: 02.00.12
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -84,6 +84,9 @@
84 * Added two new reason codes for SAS Device Status Change 84 * Added two new reason codes for SAS Device Status Change
85 * Event. 85 * Event.
86 * Added new event: SAS PHY Counter. 86 * Added new event: SAS PHY Counter.
87 * 07-30-09 02.00.12 Added GPIO Interrupt event define and structure.
88 * Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define.
89 * Added new product id family for 2208.
87 * -------------------------------------------------------------------------- 90 * --------------------------------------------------------------------------
88 */ 91 */
89 92
@@ -274,6 +277,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY
274#define MPI2_IOCFACTS_CAPABILITY_MULTICAST (0x00000100) 277#define MPI2_IOCFACTS_CAPABILITY_MULTICAST (0x00000100)
275#define MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET (0x00000080) 278#define MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET (0x00000080)
276#define MPI2_IOCFACTS_CAPABILITY_EEDP (0x00000040) 279#define MPI2_IOCFACTS_CAPABILITY_EEDP (0x00000040)
280#define MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020)
277#define MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010) 281#define MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010)
278#define MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008) 282#define MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008)
279#define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004) 283#define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004)
@@ -448,6 +452,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
448#define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST (0x0020) 452#define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST (0x0020)
449#define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021) 453#define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021)
450#define MPI2_EVENT_SAS_PHY_COUNTER (0x0022) 454#define MPI2_EVENT_SAS_PHY_COUNTER (0x0022)
455#define MPI2_EVENT_GPIO_INTERRUPT (0x0023)
451 456
452 457
453/* Log Entry Added Event data */ 458/* Log Entry Added Event data */
@@ -469,6 +474,16 @@ typedef struct _MPI2_EVENT_DATA_LOG_ENTRY_ADDED
469 MPI2_POINTER PTR_MPI2_EVENT_DATA_LOG_ENTRY_ADDED, 474 MPI2_POINTER PTR_MPI2_EVENT_DATA_LOG_ENTRY_ADDED,
470 Mpi2EventDataLogEntryAdded_t, MPI2_POINTER pMpi2EventDataLogEntryAdded_t; 475 Mpi2EventDataLogEntryAdded_t, MPI2_POINTER pMpi2EventDataLogEntryAdded_t;
471 476
477/* GPIO Interrupt Event data */
478
479typedef struct _MPI2_EVENT_DATA_GPIO_INTERRUPT {
480 U8 GPIONum; /* 0x00 */
481 U8 Reserved1; /* 0x01 */
482 U16 Reserved2; /* 0x02 */
483} MPI2_EVENT_DATA_GPIO_INTERRUPT,
484 MPI2_POINTER PTR_MPI2_EVENT_DATA_GPIO_INTERRUPT,
485 Mpi2EventDataGpioInterrupt_t, MPI2_POINTER pMpi2EventDataGpioInterrupt_t;
486
472/* Hard Reset Received Event data */ 487/* Hard Reset Received Event data */
473 488
474typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED 489typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED
@@ -1117,6 +1132,7 @@ typedef struct _MPI2_FW_IMAGE_HEADER
1117#define MPI2_FW_HEADER_PID_FAMILY_MASK (0x00FF) 1132#define MPI2_FW_HEADER_PID_FAMILY_MASK (0x00FF)
1118/* SAS */ 1133/* SAS */
1119#define MPI2_FW_HEADER_PID_FAMILY_2108_SAS (0x0010) 1134#define MPI2_FW_HEADER_PID_FAMILY_2108_SAS (0x0010)
1135#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS (0x0011)
1120 1136
1121/* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */ 1137/* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */
1122 1138
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
index 7134816d9046..5160c33d2a00 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
@@ -6,7 +6,7 @@
6 * Title: MPI Integrated RAID messages and structures 6 * Title: MPI Integrated RAID messages and structures
7 * Creation Date: April 26, 2007 7 * Creation Date: April 26, 2007
8 * 8 *
9 * mpi2_raid.h Version: 02.00.03 9 * mpi2_raid.h Version: 02.00.04
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -20,6 +20,8 @@
20 * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that 20 * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that
21 * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT 21 * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT
22 * can be sized by the build environment. 22 * can be sized by the build environment.
23 * 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of
24 * VolumeCreationFlags and marked the old one as obsolete.
23 * -------------------------------------------------------------------------- 25 * --------------------------------------------------------------------------
24 */ 26 */
25 27
@@ -217,10 +219,14 @@ typedef struct _MPI2_RAID_VOLUME_CREATION_STRUCT
217/* use MPI2_RAID_VOL_TYPE_ defines from mpi2_cnfg.h for VolumeType */ 219/* use MPI2_RAID_VOL_TYPE_ defines from mpi2_cnfg.h for VolumeType */
218 220
219/* defines for the VolumeCreationFlags field */ 221/* defines for the VolumeCreationFlags field */
222#define MPI2_RAID_VOL_CREATION_DEFAULT_SETTINGS (0x80000000)
223#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT (0x00000004)
224#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT (0x00000002)
225#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA (0x00000001)
226/* The following is an obsolete define.
227 * It must be shifted left 24 bits in order to set the proper bit.
228 */
220#define MPI2_RAID_VOL_CREATION_USE_DEFAULT_SETTINGS (0x80) 229#define MPI2_RAID_VOL_CREATION_USE_DEFAULT_SETTINGS (0x80)
221#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT (0x04)
222#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT (0x02)
223#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA (0x01)
224 230
225 231
226/* RAID Online Capacity Expansion Structure */ 232/* RAID Online Capacity Expansion Structure */
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
index 007e950f7bfa..73fcdbf92632 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
@@ -6,7 +6,7 @@
6 * Title: MPI diagnostic tool structures and definitions 6 * Title: MPI diagnostic tool structures and definitions
7 * Creation Date: March 26, 2007 7 * Creation Date: March 26, 2007
8 * 8 *
9 * mpi2_tool.h Version: 02.00.03 9 * mpi2_tool.h Version: 02.00.04
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -18,6 +18,10 @@
18 * structures and defines. 18 * structures and defines.
19 * 02-29-08 02.00.02 Modified various names to make them 32-character unique. 19 * 02-29-08 02.00.02 Modified various names to make them 32-character unique.
20 * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool. 20 * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool.
21 * 07-30-09 02.00.04 Added ExtendedType field to DiagnosticBufferPost request
22 * and reply messages.
23 * Added MPI2_DIAG_BUF_TYPE_EXTENDED.
24 * Incremented MPI2_DIAG_BUF_TYPE_COUNT.
21 * -------------------------------------------------------------------------- 25 * --------------------------------------------------------------------------
22 */ 26 */
23 27
@@ -282,7 +286,7 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY {
282 286
283typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST 287typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST
284{ 288{
285 U8 Reserved1; /* 0x00 */ 289 U8 ExtendedType; /* 0x00 */
286 U8 BufferType; /* 0x01 */ 290 U8 BufferType; /* 0x01 */
287 U8 ChainOffset; /* 0x02 */ 291 U8 ChainOffset; /* 0x02 */
288 U8 Function; /* 0x03 */ 292 U8 Function; /* 0x03 */
@@ -301,11 +305,15 @@ typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST
301} MPI2_DIAG_BUFFER_POST_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REQUEST, 305} MPI2_DIAG_BUFFER_POST_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REQUEST,
302 Mpi2DiagBufferPostRequest_t, MPI2_POINTER pMpi2DiagBufferPostRequest_t; 306 Mpi2DiagBufferPostRequest_t, MPI2_POINTER pMpi2DiagBufferPostRequest_t;
303 307
308/* values for the ExtendedType field */
309#define MPI2_DIAG_EXTENDED_TYPE_UTILIZATION (0x02)
310
304/* values for the BufferType field */ 311/* values for the BufferType field */
305#define MPI2_DIAG_BUF_TYPE_TRACE (0x00) 312#define MPI2_DIAG_BUF_TYPE_TRACE (0x00)
306#define MPI2_DIAG_BUF_TYPE_SNAPSHOT (0x01) 313#define MPI2_DIAG_BUF_TYPE_SNAPSHOT (0x01)
314#define MPI2_DIAG_BUF_TYPE_EXTENDED (0x02)
307/* count of the number of buffer types */ 315/* count of the number of buffer types */
308#define MPI2_DIAG_BUF_TYPE_COUNT (0x02) 316#define MPI2_DIAG_BUF_TYPE_COUNT (0x03)
309 317
310 318
311/**************************************************************************** 319/****************************************************************************
@@ -314,7 +322,7 @@ typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST
314 322
315typedef struct _MPI2_DIAG_BUFFER_POST_REPLY 323typedef struct _MPI2_DIAG_BUFFER_POST_REPLY
316{ 324{
317 U8 Reserved1; /* 0x00 */ 325 U8 ExtendedType; /* 0x00 */
318 U8 BufferType; /* 0x01 */ 326 U8 BufferType; /* 0x01 */
319 U8 MsgLength; /* 0x02 */ 327 U8 MsgLength; /* 0x02 */
320 U8 Function; /* 0x03 */ 328 U8 Function; /* 0x03 */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 670241efa4b5..6422e258fd52 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -57,6 +57,7 @@
57#include <linux/dma-mapping.h> 57#include <linux/dma-mapping.h>
58#include <linux/sort.h> 58#include <linux/sort.h>
59#include <linux/io.h> 59#include <linux/io.h>
60#include <linux/time.h>
60 61
61#include "mpt2sas_base.h" 62#include "mpt2sas_base.h"
62 63
@@ -77,6 +78,44 @@ static int msix_disable = -1;
77module_param(msix_disable, int, 0); 78module_param(msix_disable, int, 0);
78MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); 79MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
79 80
81/* diag_buffer_enable is bitwise
82 * bit 0 set = TRACE
83 * bit 1 set = SNAPSHOT
84 * bit 2 set = EXTENDED
85 *
86 * Either bit can be set, or both
87 */
88static int diag_buffer_enable;
89module_param(diag_buffer_enable, int, 0);
90MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
91 "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
92
93int mpt2sas_fwfault_debug;
94MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
95 "and halt firmware - (default=0)");
96
97/**
98 * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
99 *
100 */
101static int
102_scsih_set_fwfault_debug(const char *val, struct kernel_param *kp)
103{
104 int ret = param_set_int(val, kp);
105 struct MPT2SAS_ADAPTER *ioc;
106
107 if (ret)
108 return ret;
109
110 printk(KERN_INFO "setting logging_level(0x%08x)\n",
111 mpt2sas_fwfault_debug);
112 list_for_each_entry(ioc, &mpt2sas_ioc_list, list)
113 ioc->fwfault_debug = mpt2sas_fwfault_debug;
114 return 0;
115}
116module_param_call(mpt2sas_fwfault_debug, _scsih_set_fwfault_debug,
117 param_get_int, &mpt2sas_fwfault_debug, 0644);
118
80/** 119/**
81 * _base_fault_reset_work - workq handling ioc fault conditions 120 * _base_fault_reset_work - workq handling ioc fault conditions
82 * @work: input argument, used to derive ioc 121 * @work: input argument, used to derive ioc
@@ -121,7 +160,7 @@ _base_fault_reset_work(struct work_struct *work)
121 160
122/** 161/**
123 * mpt2sas_base_start_watchdog - start the fault_reset_work_q 162 * mpt2sas_base_start_watchdog - start the fault_reset_work_q
124 * @ioc: pointer to scsi command object 163 * @ioc: per adapter object
125 * Context: sleep. 164 * Context: sleep.
126 * 165 *
127 * Return nothing. 166 * Return nothing.
@@ -155,7 +194,7 @@ mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc)
155 194
156/** 195/**
157 * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q 196 * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q
158 * @ioc: pointer to scsi command object 197 * @ioc: per adapter object
159 * Context: sleep. 198 * Context: sleep.
160 * 199 *
161 * Return nothing. 200 * Return nothing.
@@ -177,10 +216,55 @@ mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc)
177 } 216 }
178} 217}
179 218
219/**
220 * mpt2sas_base_fault_info - verbose translation of firmware FAULT code
221 * @ioc: per adapter object
222 * @fault_code: fault code
223 *
224 * Return nothing.
225 */
226void
227mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code)
228{
229 printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n",
230 ioc->name, fault_code);
231}
232
233/**
234 * mpt2sas_halt_firmware - halt's mpt controller firmware
235 * @ioc: per adapter object
236 *
237 * For debugging timeout related issues. Writing 0xCOFFEE00
238 * to the doorbell register will halt controller firmware. With
239 * the purpose to stop both driver and firmware, the enduser can
240 * obtain a ring buffer from controller UART.
241 */
242void
243mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc)
244{
245 u32 doorbell;
246
247 if (!ioc->fwfault_debug)
248 return;
249
250 dump_stack();
251
252 doorbell = readl(&ioc->chip->Doorbell);
253 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT)
254 mpt2sas_base_fault_info(ioc , doorbell);
255 else {
256 writel(0xC0FFEE00, &ioc->chip->Doorbell);
257 printk(MPT2SAS_ERR_FMT "Firmware is halted due to command "
258 "timeout\n", ioc->name);
259 }
260
261 panic("panic in %s\n", __func__);
262}
263
180#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 264#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
181/** 265/**
182 * _base_sas_ioc_info - verbose translation of the ioc status 266 * _base_sas_ioc_info - verbose translation of the ioc status
183 * @ioc: pointer to scsi command object 267 * @ioc: per adapter object
184 * @mpi_reply: reply mf payload returned from firmware 268 * @mpi_reply: reply mf payload returned from firmware
185 * @request_hdr: request mf 269 * @request_hdr: request mf
186 * 270 *
@@ -394,7 +478,7 @@ _base_sas_ioc_info(struct MPT2SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply,
394 478
395/** 479/**
396 * _base_display_event_data - verbose translation of firmware asyn events 480 * _base_display_event_data - verbose translation of firmware asyn events
397 * @ioc: pointer to scsi command object 481 * @ioc: per adapter object
398 * @mpi_reply: reply mf payload returned from firmware 482 * @mpi_reply: reply mf payload returned from firmware
399 * 483 *
400 * Return nothing. 484 * Return nothing.
@@ -474,7 +558,7 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
474 558
475/** 559/**
476 * _base_sas_log_info - verbose translation of firmware log info 560 * _base_sas_log_info - verbose translation of firmware log info
477 * @ioc: pointer to scsi command object 561 * @ioc: per adapter object
478 * @log_info: log info 562 * @log_info: log info
479 * 563 *
480 * Return nothing. 564 * Return nothing.
@@ -526,22 +610,8 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info)
526} 610}
527 611
528/** 612/**
529 * mpt2sas_base_fault_info - verbose translation of firmware FAULT code
530 * @ioc: pointer to scsi command object
531 * @fault_code: fault code
532 *
533 * Return nothing.
534 */
535void
536mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code)
537{
538 printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n",
539 ioc->name, fault_code);
540}
541
542/**
543 * _base_display_reply_info - 613 * _base_display_reply_info -
544 * @ioc: pointer to scsi command object 614 * @ioc: per adapter object
545 * @smid: system request message index 615 * @smid: system request message index
546 * @msix_index: MSIX table index supplied by the OS 616 * @msix_index: MSIX table index supplied by the OS
547 * @reply: reply message frame(lower 32bit addr) 617 * @reply: reply message frame(lower 32bit addr)
@@ -570,7 +640,7 @@ _base_display_reply_info(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
570 640
571/** 641/**
572 * mpt2sas_base_done - base internal command completion routine 642 * mpt2sas_base_done - base internal command completion routine
573 * @ioc: pointer to scsi command object 643 * @ioc: per adapter object
574 * @smid: system request message index 644 * @smid: system request message index
575 * @msix_index: MSIX table index supplied by the OS 645 * @msix_index: MSIX table index supplied by the OS
576 * @reply: reply message frame(lower 32bit addr) 646 * @reply: reply message frame(lower 32bit addr)
@@ -603,7 +673,7 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
603 673
604/** 674/**
605 * _base_async_event - main callback handler for firmware asyn events 675 * _base_async_event - main callback handler for firmware asyn events
606 * @ioc: pointer to scsi command object 676 * @ioc: per adapter object
607 * @msix_index: MSIX table index supplied by the OS 677 * @msix_index: MSIX table index supplied by the OS
608 * @reply: reply message frame(lower 32bit addr) 678 * @reply: reply message frame(lower 32bit addr)
609 * 679 *
@@ -684,7 +754,7 @@ _base_get_cb_idx(struct MPT2SAS_ADAPTER *ioc, u16 smid)
684 754
685/** 755/**
686 * _base_mask_interrupts - disable interrupts 756 * _base_mask_interrupts - disable interrupts
687 * @ioc: pointer to scsi command object 757 * @ioc: per adapter object
688 * 758 *
689 * Disabling ResetIRQ, Reply and Doorbell Interrupts 759 * Disabling ResetIRQ, Reply and Doorbell Interrupts
690 * 760 *
@@ -704,7 +774,7 @@ _base_mask_interrupts(struct MPT2SAS_ADAPTER *ioc)
704 774
705/** 775/**
706 * _base_unmask_interrupts - enable interrupts 776 * _base_unmask_interrupts - enable interrupts
707 * @ioc: pointer to scsi command object 777 * @ioc: per adapter object
708 * 778 *
709 * Enabling only Reply Interrupts 779 * Enabling only Reply Interrupts
710 * 780 *
@@ -1258,12 +1328,13 @@ mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1258 * @ioc: per adapter object 1328 * @ioc: per adapter object
1259 * @smid: system request message index 1329 * @smid: system request message index
1260 * 1330 *
1261 * Returns phys pointer to sense buffer. 1331 * Returns phys pointer to the low 32bit address of the sense buffer.
1262 */ 1332 */
1263dma_addr_t 1333__le32
1264mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid) 1334mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1265{ 1335{
1266 return ioc->sense_dma + ((smid - 1) * SCSI_SENSE_BUFFERSIZE); 1336 return cpu_to_le32(ioc->sense_dma +
1337 ((smid - 1) * SCSI_SENSE_BUFFERSIZE));
1267} 1338}
1268 1339
1269/** 1340/**
@@ -1697,6 +1768,12 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc)
1697 } 1768 }
1698 1769
1699 if (ioc->facts.IOCCapabilities & 1770 if (ioc->facts.IOCCapabilities &
1771 MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) {
1772 printk(KERN_INFO "%sDiag Extended Buffer", i ? "," : "");
1773 i++;
1774 }
1775
1776 if (ioc->facts.IOCCapabilities &
1700 MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) { 1777 MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) {
1701 printk("%sTask Set Full", i ? "," : ""); 1778 printk("%sTask Set Full", i ? "," : "");
1702 i++; 1779 i++;
@@ -2871,6 +2948,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2871 Mpi2IOCInitRequest_t mpi_request; 2948 Mpi2IOCInitRequest_t mpi_request;
2872 Mpi2IOCInitReply_t mpi_reply; 2949 Mpi2IOCInitReply_t mpi_reply;
2873 int r; 2950 int r;
2951 struct timeval current_time;
2952 u16 ioc_status;
2874 2953
2875 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 2954 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
2876 __func__)); 2955 __func__));
@@ -2921,6 +3000,13 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2921 cpu_to_le32(ioc->reply_post_free_dma); 3000 cpu_to_le32(ioc->reply_post_free_dma);
2922#endif 3001#endif
2923 3002
3003 /* This time stamp specifies number of milliseconds
3004 * since epoch ~ midnight January 1, 1970.
3005 */
3006 do_gettimeofday(&current_time);
3007 mpi_request.TimeStamp = (current_time.tv_sec * 1000) +
3008 (current_time.tv_usec >> 3);
3009
2924 if (ioc->logging_level & MPT_DEBUG_INIT) { 3010 if (ioc->logging_level & MPT_DEBUG_INIT) {
2925 u32 *mfp; 3011 u32 *mfp;
2926 int i; 3012 int i;
@@ -2943,7 +3029,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2943 return r; 3029 return r;
2944 } 3030 }
2945 3031
2946 if (mpi_reply.IOCStatus != MPI2_IOCSTATUS_SUCCESS || 3032 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
3033 if (ioc_status != MPI2_IOCSTATUS_SUCCESS ||
2947 mpi_reply.IOCLogInfo) { 3034 mpi_reply.IOCLogInfo) {
2948 printk(MPT2SAS_ERR_FMT "%s: failed\n", ioc->name, __func__); 3035 printk(MPT2SAS_ERR_FMT "%s: failed\n", ioc->name, __func__);
2949 r = -EIO; 3036 r = -EIO;
@@ -3461,11 +3548,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3461 return r; 3548 return r;
3462 3549
3463 pci_set_drvdata(ioc->pdev, ioc->shost); 3550 pci_set_drvdata(ioc->pdev, ioc->shost);
3464 r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); 3551 r = _base_get_ioc_facts(ioc, CAN_SLEEP);
3465 if (r) 3552 if (r)
3466 goto out_free_resources; 3553 goto out_free_resources;
3467 3554
3468 r = _base_get_ioc_facts(ioc, CAN_SLEEP); 3555 r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
3469 if (r) 3556 if (r)
3470 goto out_free_resources; 3557 goto out_free_resources;
3471 3558
@@ -3531,6 +3618,8 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3531 goto out_free_resources; 3618 goto out_free_resources;
3532 3619
3533 mpt2sas_base_start_watchdog(ioc); 3620 mpt2sas_base_start_watchdog(ioc);
3621 if (diag_buffer_enable != 0)
3622 mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
3534 return 0; 3623 return 0;
3535 3624
3536 out_free_resources: 3625 out_free_resources:
@@ -3684,6 +3773,9 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3684 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 3773 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
3685 __func__)); 3774 __func__));
3686 3775
3776 if (mpt2sas_fwfault_debug)
3777 mpt2sas_halt_firmware(ioc);
3778
3687 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 3779 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3688 if (ioc->shost_recovery) { 3780 if (ioc->shost_recovery) {
3689 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 3781 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 0cf6bc236e4d..bb4f14656afa 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -69,8 +69,8 @@
69#define MPT2SAS_DRIVER_NAME "mpt2sas" 69#define MPT2SAS_DRIVER_NAME "mpt2sas"
70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" 70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" 71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
72#define MPT2SAS_DRIVER_VERSION "02.100.03.00" 72#define MPT2SAS_DRIVER_VERSION "03.100.03.00"
73#define MPT2SAS_MAJOR_VERSION 02 73#define MPT2SAS_MAJOR_VERSION 03
74#define MPT2SAS_MINOR_VERSION 100 74#define MPT2SAS_MINOR_VERSION 100
75#define MPT2SAS_BUILD_VERSION 03 75#define MPT2SAS_BUILD_VERSION 03
76#define MPT2SAS_RELEASE_VERSION 00 76#define MPT2SAS_RELEASE_VERSION 00
@@ -278,7 +278,7 @@ struct _internal_cmd {
278 * @sas_address: device sas address 278 * @sas_address: device sas address
279 * @device_name: retrieved from the SAS IDENTIFY frame. 279 * @device_name: retrieved from the SAS IDENTIFY frame.
280 * @handle: device handle 280 * @handle: device handle
281 * @parent_handle: handle to parent device 281 * @sas_address_parent: sas address of parent expander or sas host
282 * @enclosure_handle: enclosure handle 282 * @enclosure_handle: enclosure handle
283 * @enclosure_logical_id: enclosure logical identifier 283 * @enclosure_logical_id: enclosure logical identifier
284 * @volume_handle: volume handle (valid when hidden raid member) 284 * @volume_handle: volume handle (valid when hidden raid member)
@@ -296,7 +296,7 @@ struct _sas_device {
296 u64 sas_address; 296 u64 sas_address;
297 u64 device_name; 297 u64 device_name;
298 u16 handle; 298 u16 handle;
299 u16 parent_handle; 299 u64 sas_address_parent;
300 u16 enclosure_handle; 300 u16 enclosure_handle;
301 u64 enclosure_logical_id; 301 u64 enclosure_logical_id;
302 u16 volume_handle; 302 u16 volume_handle;
@@ -352,8 +352,6 @@ struct _boot_device {
352/** 352/**
353 * struct _sas_port - wide/narrow sas port information 353 * struct _sas_port - wide/narrow sas port information
354 * @port_list: list of ports belonging to expander 354 * @port_list: list of ports belonging to expander
355 * @handle: device handle for this port
356 * @sas_address: sas address of this port
357 * @num_phys: number of phys belonging to this port 355 * @num_phys: number of phys belonging to this port
358 * @remote_identify: attached device identification 356 * @remote_identify: attached device identification
359 * @rphy: sas transport rphy object 357 * @rphy: sas transport rphy object
@@ -362,8 +360,6 @@ struct _boot_device {
362 */ 360 */
363struct _sas_port { 361struct _sas_port {
364 struct list_head port_list; 362 struct list_head port_list;
365 u16 handle;
366 u64 sas_address;
367 u8 num_phys; 363 u8 num_phys;
368 struct sas_identify remote_identify; 364 struct sas_identify remote_identify;
369 struct sas_rphy *rphy; 365 struct sas_rphy *rphy;
@@ -398,7 +394,7 @@ struct _sas_phy {
398 * @num_phys: number phys belonging to this sas_host/expander 394 * @num_phys: number phys belonging to this sas_host/expander
399 * @sas_address: sas address of this sas_host/expander 395 * @sas_address: sas address of this sas_host/expander
400 * @handle: handle for this sas_host/expander 396 * @handle: handle for this sas_host/expander
401 * @parent_handle: parent handle 397 * @sas_address_parent: sas address of parent expander or sas host
402 * @enclosure_handle: handle for this a member of an enclosure 398 * @enclosure_handle: handle for this a member of an enclosure
403 * @device_info: bitwise defining capabilities of this sas_host/expander 399 * @device_info: bitwise defining capabilities of this sas_host/expander
404 * @responding: used in _scsih_expander_device_mark_responding 400 * @responding: used in _scsih_expander_device_mark_responding
@@ -411,7 +407,7 @@ struct _sas_node {
411 u8 num_phys; 407 u8 num_phys;
412 u64 sas_address; 408 u64 sas_address;
413 u16 handle; 409 u16 handle;
414 u16 parent_handle; 410 u64 sas_address_parent;
415 u16 enclosure_handle; 411 u16 enclosure_handle;
416 u64 enclosure_logical_id; 412 u64 enclosure_logical_id;
417 u8 responding; 413 u8 responding;
@@ -470,6 +466,7 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
470 * @chip_phys: physical addrss prior to mapping 466 * @chip_phys: physical addrss prior to mapping
471 * @pio_chip: I/O mapped register space 467 * @pio_chip: I/O mapped register space
472 * @logging_level: see mpt2sas_debug.h 468 * @logging_level: see mpt2sas_debug.h
469 * @fwfault_debug: debuging FW timeouts
473 * @ir_firmware: IR firmware present 470 * @ir_firmware: IR firmware present
474 * @bars: bitmask of BAR's that must be configured 471 * @bars: bitmask of BAR's that must be configured
475 * @mask_interrupts: ignore interrupt 472 * @mask_interrupts: ignore interrupt
@@ -495,12 +492,14 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
495 * @msix_table_backup: backup msix table 492 * @msix_table_backup: backup msix table
496 * @scsi_io_cb_idx: shost generated commands 493 * @scsi_io_cb_idx: shost generated commands
497 * @tm_cb_idx: task management commands 494 * @tm_cb_idx: task management commands
495 * @scsih_cb_idx: scsih internal commands
498 * @transport_cb_idx: transport internal commands 496 * @transport_cb_idx: transport internal commands
499 * @ctl_cb_idx: clt internal commands 497 * @ctl_cb_idx: clt internal commands
500 * @base_cb_idx: base internal commands 498 * @base_cb_idx: base internal commands
501 * @config_cb_idx: base internal commands 499 * @config_cb_idx: base internal commands
502 * @base_cmds: 500 * @base_cmds:
503 * @transport_cmds: 501 * @transport_cmds:
502 * @scsih_cmds:
504 * @tm_cmds: 503 * @tm_cmds:
505 * @ctl_cmds: 504 * @ctl_cmds:
506 * @config_cmds: 505 * @config_cmds:
@@ -591,6 +590,7 @@ struct MPT2SAS_ADAPTER {
591 unsigned long chip_phys; 590 unsigned long chip_phys;
592 unsigned long pio_chip; 591 unsigned long pio_chip;
593 int logging_level; 592 int logging_level;
593 int fwfault_debug;
594 u8 ir_firmware; 594 u8 ir_firmware;
595 int bars; 595 int bars;
596 u8 mask_interrupts; 596 u8 mask_interrupts;
@@ -626,6 +626,7 @@ struct MPT2SAS_ADAPTER {
626 u8 scsi_io_cb_idx; 626 u8 scsi_io_cb_idx;
627 u8 tm_cb_idx; 627 u8 tm_cb_idx;
628 u8 transport_cb_idx; 628 u8 transport_cb_idx;
629 u8 scsih_cb_idx;
629 u8 ctl_cb_idx; 630 u8 ctl_cb_idx;
630 u8 base_cb_idx; 631 u8 base_cb_idx;
631 u8 config_cb_idx; 632 u8 config_cb_idx;
@@ -633,6 +634,7 @@ struct MPT2SAS_ADAPTER {
633 u8 tm_sas_control_cb_idx; 634 u8 tm_sas_control_cb_idx;
634 struct _internal_cmd base_cmds; 635 struct _internal_cmd base_cmds;
635 struct _internal_cmd transport_cmds; 636 struct _internal_cmd transport_cmds;
637 struct _internal_cmd scsih_cmds;
636 struct _internal_cmd tm_cmds; 638 struct _internal_cmd tm_cmds;
637 struct _internal_cmd ctl_cmds; 639 struct _internal_cmd ctl_cmds;
638 struct _internal_cmd config_cmds; 640 struct _internal_cmd config_cmds;
@@ -773,7 +775,7 @@ int mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
773void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid); 775void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid);
774void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid); 776void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid);
775void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr); 777void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr);
776dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, 778__le32 mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc,
777 u16 smid); 779 u16 smid);
778 780
779/* hi-priority queue */ 781/* hi-priority queue */
@@ -807,6 +809,8 @@ int mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
807 Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request); 809 Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request);
808void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type); 810void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type);
809 811
812void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc);
813
810/* scsih shared API */ 814/* scsih shared API */
811u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, 815u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
812 u32 reply); 816 u32 reply);
@@ -886,19 +890,22 @@ u8 mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
886void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, 890void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
887 Mpi2EventNotificationReply_t *mpi_reply); 891 Mpi2EventNotificationReply_t *mpi_reply);
888 892
893void mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc,
894 u8 bits_to_regsiter);
895
889/* transport shared API */ 896/* transport shared API */
890u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 897u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
891 u32 reply); 898 u32 reply);
892struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, 899struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc,
893 u16 handle, u16 parent_handle); 900 u16 handle, u64 sas_address);
894void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, 901void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
895 u16 parent_handle); 902 u64 sas_address_parent);
896int mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy 903int mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
897 *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev); 904 *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev);
898int mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy 905int mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
899 *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev); 906 *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev);
900void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, u16 handle, 907void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
901 u16 attached_handle, u8 phy_number, u8 link_rate); 908 u64 sas_address, u16 handle, u8 phy_number, u8 link_rate);
902extern struct sas_function_template mpt2sas_transport_functions; 909extern struct sas_function_template mpt2sas_transport_functions;
903extern struct scsi_transport_template *mpt2sas_transport_template; 910extern struct scsi_transport_template *mpt2sas_transport_template;
904extern int scsi_internal_device_block(struct scsi_device *sdev); 911extern int scsi_internal_device_block(struct scsi_device *sdev);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 57d724633906..84a124f8e21f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -740,7 +740,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
740 Mpi2SCSIIORequest_t *scsiio_request = 740 Mpi2SCSIIORequest_t *scsiio_request =
741 (Mpi2SCSIIORequest_t *)mpi_request; 741 (Mpi2SCSIIORequest_t *)mpi_request;
742 scsiio_request->SenseBufferLowAddress = 742 scsiio_request->SenseBufferLowAddress =
743 (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid); 743 mpt2sas_base_get_sense_buffer_dma(ioc, smid);
744 priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid); 744 priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid);
745 memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE); 745 memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE);
746 mpt2sas_base_put_smid_scsi_io(ioc, smid, 746 mpt2sas_base_put_smid_scsi_io(ioc, smid,
@@ -848,8 +848,9 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
848 printk(MPT2SAS_DEBUG_FMT "TASK_MGMT: " 848 printk(MPT2SAS_DEBUG_FMT "TASK_MGMT: "
849 "IOCStatus(0x%04x), IOCLogInfo(0x%08x), " 849 "IOCStatus(0x%04x), IOCLogInfo(0x%08x), "
850 "TerminationCount(0x%08x)\n", ioc->name, 850 "TerminationCount(0x%08x)\n", ioc->name,
851 tm_reply->IOCStatus, tm_reply->IOCLogInfo, 851 le16_to_cpu(tm_reply->IOCStatus),
852 tm_reply->TerminationCount); 852 le32_to_cpu(tm_reply->IOCLogInfo),
853 le32_to_cpu(tm_reply->TerminationCount));
853 } 854 }
854#endif 855#endif
855 /* copy out xdata to user */ 856 /* copy out xdata to user */
@@ -896,6 +897,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
896 printk(MPT2SAS_INFO_FMT "issue target reset: handle " 897 printk(MPT2SAS_INFO_FMT "issue target reset: handle "
897 "= (0x%04x)\n", ioc->name, 898 "= (0x%04x)\n", ioc->name,
898 mpi_request->FunctionDependent1); 899 mpi_request->FunctionDependent1);
900 mpt2sas_halt_firmware(ioc);
899 mutex_lock(&ioc->tm_cmds.mutex); 901 mutex_lock(&ioc->tm_cmds.mutex);
900 mpt2sas_scsih_issue_tm(ioc, 902 mpt2sas_scsih_issue_tm(ioc,
901 mpi_request->FunctionDependent1, 0, 903 mpi_request->FunctionDependent1, 0,
@@ -1229,7 +1231,7 @@ _ctl_btdh_mapping(void __user *arg)
1229/** 1231/**
1230 * _ctl_diag_capability - return diag buffer capability 1232 * _ctl_diag_capability - return diag buffer capability
1231 * @ioc: per adapter object 1233 * @ioc: per adapter object
1232 * @buffer_type: specifies either TRACE or SNAPSHOT 1234 * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED
1233 * 1235 *
1234 * returns 1 when diag buffer support is enabled in firmware 1236 * returns 1 when diag buffer support is enabled in firmware
1235 */ 1237 */
@@ -1249,24 +1251,25 @@ _ctl_diag_capability(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type)
1249 MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) 1251 MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER)
1250 rc = 1; 1252 rc = 1;
1251 break; 1253 break;
1254 case MPI2_DIAG_BUF_TYPE_EXTENDED:
1255 if (ioc->facts.IOCCapabilities &
1256 MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER)
1257 rc = 1;
1252 } 1258 }
1253 1259
1254 return rc; 1260 return rc;
1255} 1261}
1256 1262
1257/** 1263/**
1258 * _ctl_diag_register - application register with driver 1264 * _ctl_diag_register_2 - wrapper for registering diag buffer support
1259 * @arg - user space buffer containing ioctl content 1265 * @ioc: per adapter object
1260 * @state - NON_BLOCKING or BLOCKING 1266 * @diag_register: the diag_register struct passed in from user space
1261 * 1267 *
1262 * This will allow the driver to setup any required buffers that will be
1263 * needed by firmware to communicate with the driver.
1264 */ 1268 */
1265static long 1269static long
1266_ctl_diag_register(void __user *arg, enum block_state state) 1270_ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
1271 struct mpt2_diag_register *diag_register)
1267{ 1272{
1268 struct mpt2_diag_register karg;
1269 struct MPT2SAS_ADAPTER *ioc;
1270 int rc, i; 1273 int rc, i;
1271 void *request_data = NULL; 1274 void *request_data = NULL;
1272 dma_addr_t request_data_dma; 1275 dma_addr_t request_data_dma;
@@ -1279,18 +1282,17 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1279 u16 ioc_status; 1282 u16 ioc_status;
1280 u8 issue_reset = 0; 1283 u8 issue_reset = 0;
1281 1284
1282 if (copy_from_user(&karg, arg, sizeof(karg))) {
1283 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1284 __FILE__, __LINE__, __func__);
1285 return -EFAULT;
1286 }
1287 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1288 return -ENODEV;
1289
1290 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1285 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
1291 __func__)); 1286 __func__));
1292 1287
1293 buffer_type = karg.buffer_type; 1288 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
1289 printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
1290 ioc->name, __func__);
1291 rc = -EAGAIN;
1292 goto out;
1293 }
1294
1295 buffer_type = diag_register->buffer_type;
1294 if (!_ctl_diag_capability(ioc, buffer_type)) { 1296 if (!_ctl_diag_capability(ioc, buffer_type)) {
1295 printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for " 1297 printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
1296 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type); 1298 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
@@ -1305,24 +1307,12 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1305 return -EINVAL; 1307 return -EINVAL;
1306 } 1308 }
1307 1309
1308 if (karg.requested_buffer_size % 4) { 1310 if (diag_register->requested_buffer_size % 4) {
1309 printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size " 1311 printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size "
1310 "is not 4 byte aligned\n", ioc->name, __func__); 1312 "is not 4 byte aligned\n", ioc->name, __func__);
1311 return -EINVAL; 1313 return -EINVAL;
1312 } 1314 }
1313 1315
1314 if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
1315 return -EAGAIN;
1316 else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
1317 return -ERESTARTSYS;
1318
1319 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
1320 printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
1321 ioc->name, __func__);
1322 rc = -EAGAIN;
1323 goto out;
1324 }
1325
1326 smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx); 1316 smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
1327 if (!smid) { 1317 if (!smid) {
1328 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 1318 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
@@ -1338,12 +1328,12 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1338 ioc->ctl_cmds.smid = smid; 1328 ioc->ctl_cmds.smid = smid;
1339 1329
1340 request_data = ioc->diag_buffer[buffer_type]; 1330 request_data = ioc->diag_buffer[buffer_type];
1341 request_data_sz = karg.requested_buffer_size; 1331 request_data_sz = diag_register->requested_buffer_size;
1342 ioc->unique_id[buffer_type] = karg.unique_id; 1332 ioc->unique_id[buffer_type] = diag_register->unique_id;
1343 ioc->diag_buffer_status[buffer_type] = 0; 1333 ioc->diag_buffer_status[buffer_type] = 0;
1344 memcpy(ioc->product_specific[buffer_type], karg.product_specific, 1334 memcpy(ioc->product_specific[buffer_type],
1345 MPT2_PRODUCT_SPECIFIC_DWORDS); 1335 diag_register->product_specific, MPT2_PRODUCT_SPECIFIC_DWORDS);
1346 ioc->diagnostic_flags[buffer_type] = karg.diagnostic_flags; 1336 ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags;
1347 1337
1348 if (request_data) { 1338 if (request_data) {
1349 request_data_dma = ioc->diag_buffer_dma[buffer_type]; 1339 request_data_dma = ioc->diag_buffer_dma[buffer_type];
@@ -1373,8 +1363,8 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1373 } 1363 }
1374 1364
1375 mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST; 1365 mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;
1376 mpi_request->BufferType = karg.buffer_type; 1366 mpi_request->BufferType = diag_register->buffer_type;
1377 mpi_request->Flags = cpu_to_le32(karg.diagnostic_flags); 1367 mpi_request->Flags = cpu_to_le32(diag_register->diagnostic_flags);
1378 mpi_request->BufferAddress = cpu_to_le64(request_data_dma); 1368 mpi_request->BufferAddress = cpu_to_le64(request_data_dma);
1379 mpi_request->BufferLength = cpu_to_le32(request_data_sz); 1369 mpi_request->BufferLength = cpu_to_le32(request_data_sz);
1380 mpi_request->VF_ID = 0; /* TODO */ 1370 mpi_request->VF_ID = 0; /* TODO */
@@ -1422,7 +1412,7 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1422 } else { 1412 } else {
1423 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 1413 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
1424 "log_info(0x%08x)\n", ioc->name, __func__, 1414 "log_info(0x%08x)\n", ioc->name, __func__,
1425 ioc_status, mpi_reply->IOCLogInfo); 1415 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
1426 rc = -EFAULT; 1416 rc = -EFAULT;
1427 } 1417 }
1428 1418
@@ -1438,6 +1428,83 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1438 request_data, request_data_dma); 1428 request_data, request_data_dma);
1439 1429
1440 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; 1430 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
1431 return rc;
1432}
1433
1434/**
1435 * mpt2sas_enable_diag_buffer - enabling diag_buffers support driver load time
1436 * @ioc: per adapter object
1437 * @bits_to_register: bitwise field where trace is bit 0, and snapshot is bit 1
1438 *
1439 * This is called when command line option diag_buffer_enable is enabled
1440 * at driver load time.
1441 */
1442void
1443mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, u8 bits_to_register)
1444{
1445 struct mpt2_diag_register diag_register;
1446
1447 memset(&diag_register, 0, sizeof(struct mpt2_diag_register));
1448
1449 if (bits_to_register & 1) {
1450 printk(MPT2SAS_INFO_FMT "registering trace buffer support\n",
1451 ioc->name);
1452 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
1453 /* register for 1MB buffers */
1454 diag_register.requested_buffer_size = (1024 * 1024);
1455 diag_register.unique_id = 0x7075900;
1456 _ctl_diag_register_2(ioc, &diag_register);
1457 }
1458
1459 if (bits_to_register & 2) {
1460 printk(MPT2SAS_INFO_FMT "registering snapshot buffer support\n",
1461 ioc->name);
1462 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_SNAPSHOT;
1463 /* register for 2MB buffers */
1464 diag_register.requested_buffer_size = 2 * (1024 * 1024);
1465 diag_register.unique_id = 0x7075901;
1466 _ctl_diag_register_2(ioc, &diag_register);
1467 }
1468
1469 if (bits_to_register & 4) {
1470 printk(MPT2SAS_INFO_FMT "registering extended buffer support\n",
1471 ioc->name);
1472 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_EXTENDED;
1473 /* register for 2MB buffers */
1474 diag_register.requested_buffer_size = 2 * (1024 * 1024);
1475 diag_register.unique_id = 0x7075901;
1476 _ctl_diag_register_2(ioc, &diag_register);
1477 }
1478}
1479
1480/**
1481 * _ctl_diag_register - application register with driver
1482 * @arg - user space buffer containing ioctl content
1483 * @state - NON_BLOCKING or BLOCKING
1484 *
1485 * This will allow the driver to setup any required buffers that will be
1486 * needed by firmware to communicate with the driver.
1487 */
1488static long
1489_ctl_diag_register(void __user *arg, enum block_state state)
1490{
1491 struct mpt2_diag_register karg;
1492 struct MPT2SAS_ADAPTER *ioc;
1493 long rc;
1494
1495 if (copy_from_user(&karg, arg, sizeof(karg))) {
1496 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1497 __FILE__, __LINE__, __func__);
1498 return -EFAULT;
1499 }
1500 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1501 return -ENODEV;
1502
1503 if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
1504 return -EAGAIN;
1505 else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
1506 return -ERESTARTSYS;
1507 rc = _ctl_diag_register_2(ioc, &karg);
1441 mutex_unlock(&ioc->ctl_cmds.mutex); 1508 mutex_unlock(&ioc->ctl_cmds.mutex);
1442 return rc; 1509 return rc;
1443} 1510}
@@ -1600,7 +1667,7 @@ _ctl_diag_query(void __user *arg)
1600/** 1667/**
1601 * _ctl_send_release - Diag Release Message 1668 * _ctl_send_release - Diag Release Message
1602 * @ioc: per adapter object 1669 * @ioc: per adapter object
1603 * @buffer_type - specifies either TRACE or SNAPSHOT 1670 * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
1604 * @issue_reset - specifies whether host reset is required. 1671 * @issue_reset - specifies whether host reset is required.
1605 * 1672 *
1606 */ 1673 */
@@ -1690,7 +1757,7 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
1690 } else { 1757 } else {
1691 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 1758 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
1692 "log_info(0x%08x)\n", ioc->name, __func__, 1759 "log_info(0x%08x)\n", ioc->name, __func__,
1693 ioc_status, mpi_reply->IOCLogInfo); 1760 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
1694 rc = -EFAULT; 1761 rc = -EFAULT;
1695 } 1762 }
1696 1763
@@ -1951,7 +2018,7 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
1951 } else { 2018 } else {
1952 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 2019 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
1953 "log_info(0x%08x)\n", ioc->name, __func__, 2020 "log_info(0x%08x)\n", ioc->name, __func__,
1954 ioc_status, mpi_reply->IOCLogInfo); 2021 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
1955 rc = -EFAULT; 2022 rc = -EFAULT;
1956 } 2023 }
1957 2024
@@ -2474,6 +2541,43 @@ _ctl_logging_level_store(struct device *cdev, struct device_attribute *attr,
2474static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR, 2541static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR,
2475 _ctl_logging_level_show, _ctl_logging_level_store); 2542 _ctl_logging_level_show, _ctl_logging_level_store);
2476 2543
2544/* device attributes */
2545/*
2546 * _ctl_fwfault_debug_show - show/store fwfault_debug
2547 * @cdev - pointer to embedded class device
2548 * @buf - the buffer returned
2549 *
2550 * mpt2sas_fwfault_debug is command line option
2551 * A sysfs 'read/write' shost attribute.
2552 */
2553static ssize_t
2554_ctl_fwfault_debug_show(struct device *cdev,
2555 struct device_attribute *attr, char *buf)
2556{
2557 struct Scsi_Host *shost = class_to_shost(cdev);
2558 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2559
2560 return snprintf(buf, PAGE_SIZE, "%d\n", ioc->fwfault_debug);
2561}
2562static ssize_t
2563_ctl_fwfault_debug_store(struct device *cdev,
2564 struct device_attribute *attr, const char *buf, size_t count)
2565{
2566 struct Scsi_Host *shost = class_to_shost(cdev);
2567 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2568 int val = 0;
2569
2570 if (sscanf(buf, "%d", &val) != 1)
2571 return -EINVAL;
2572
2573 ioc->fwfault_debug = val;
2574 printk(MPT2SAS_INFO_FMT "fwfault_debug=%d\n", ioc->name,
2575 ioc->fwfault_debug);
2576 return strlen(buf);
2577}
2578static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR,
2579 _ctl_fwfault_debug_show, _ctl_fwfault_debug_store);
2580
2477struct device_attribute *mpt2sas_host_attrs[] = { 2581struct device_attribute *mpt2sas_host_attrs[] = {
2478 &dev_attr_version_fw, 2582 &dev_attr_version_fw,
2479 &dev_attr_version_bios, 2583 &dev_attr_version_bios,
@@ -2487,13 +2591,12 @@ struct device_attribute *mpt2sas_host_attrs[] = {
2487 &dev_attr_io_delay, 2591 &dev_attr_io_delay,
2488 &dev_attr_device_delay, 2592 &dev_attr_device_delay,
2489 &dev_attr_logging_level, 2593 &dev_attr_logging_level,
2594 &dev_attr_fwfault_debug,
2490 &dev_attr_fw_queue_depth, 2595 &dev_attr_fw_queue_depth,
2491 &dev_attr_host_sas_address, 2596 &dev_attr_host_sas_address,
2492 NULL, 2597 NULL,
2493}; 2598};
2494 2599
2495/* device attributes */
2496
2497/** 2600/**
2498 * _ctl_device_sas_address_show - sas address 2601 * _ctl_device_sas_address_show - sas address
2499 * @cdev - pointer to embedded class device 2602 * @cdev - pointer to embedded class device
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
index 211f296dd191..8a5eeb1a5c84 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
@@ -313,7 +313,7 @@ struct mpt2_ioctl_btdh_mapping {
313 * struct mpt2_diag_register - application register with driver 313 * struct mpt2_diag_register - application register with driver
314 * @hdr - generic header 314 * @hdr - generic header
315 * @reserved - 315 * @reserved -
316 * @buffer_type - specifies either TRACE or SNAPSHOT 316 * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
317 * @application_flags - misc flags 317 * @application_flags - misc flags
318 * @diagnostic_flags - specifies flags affecting command processing 318 * @diagnostic_flags - specifies flags affecting command processing
319 * @product_specific - product specific information 319 * @product_specific - product specific information
@@ -352,7 +352,7 @@ struct mpt2_diag_unregister {
352 * struct mpt2_diag_query - query relevant info associated with diag buffers 352 * struct mpt2_diag_query - query relevant info associated with diag buffers
353 * @hdr - generic header 353 * @hdr - generic header
354 * @reserved - 354 * @reserved -
355 * @buffer_type - specifies either TRACE or SNAPSHOT 355 * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
356 * @application_flags - misc flags 356 * @application_flags - misc flags
357 * @diagnostic_flags - specifies flags affecting command processing 357 * @diagnostic_flags - specifies flags affecting command processing
358 * @product_specific - product specific information 358 * @product_specific - product specific information
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 86ab32d7ab15..55ee014a7e08 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -76,6 +76,7 @@ static u8 tm_cb_idx = -1;
76static u8 ctl_cb_idx = -1; 76static u8 ctl_cb_idx = -1;
77static u8 base_cb_idx = -1; 77static u8 base_cb_idx = -1;
78static u8 transport_cb_idx = -1; 78static u8 transport_cb_idx = -1;
79static u8 scsih_cb_idx = -1;
79static u8 config_cb_idx = -1; 80static u8 config_cb_idx = -1;
80static int mpt_ids; 81static int mpt_ids;
81 82
@@ -196,10 +197,28 @@ static struct pci_device_id scsih_pci_table[] = {
196 PCI_ANY_ID, PCI_ANY_ID }, 197 PCI_ANY_ID, PCI_ANY_ID },
197 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3, 198 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
198 PCI_ANY_ID, PCI_ANY_ID }, 199 PCI_ANY_ID, PCI_ANY_ID },
200 /* Meteor ~ 2116 */
199 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1, 201 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
200 PCI_ANY_ID, PCI_ANY_ID }, 202 PCI_ANY_ID, PCI_ANY_ID },
201 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2, 203 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
202 PCI_ANY_ID, PCI_ANY_ID }, 204 PCI_ANY_ID, PCI_ANY_ID },
205 /* Thunderbolt ~ 2208 */
206 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
207 PCI_ANY_ID, PCI_ANY_ID },
208 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
209 PCI_ANY_ID, PCI_ANY_ID },
210 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
211 PCI_ANY_ID, PCI_ANY_ID },
212 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
213 PCI_ANY_ID, PCI_ANY_ID },
214 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
215 PCI_ANY_ID, PCI_ANY_ID },
216 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
217 PCI_ANY_ID, PCI_ANY_ID },
218 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_7,
219 PCI_ANY_ID, PCI_ANY_ID },
220 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_8,
221 PCI_ANY_ID, PCI_ANY_ID },
203 {0} /* Terminating entry */ 222 {0} /* Terminating entry */
204}; 223};
205MODULE_DEVICE_TABLE(pci, scsih_pci_table); 224MODULE_DEVICE_TABLE(pci, scsih_pci_table);
@@ -317,6 +336,47 @@ _scsih_is_boot_device(u64 sas_address, u64 device_name,
317} 336}
318 337
319/** 338/**
339 * _scsih_get_sas_address - set the sas_address for given device handle
340 * @handle: device handle
341 * @sas_address: sas address
342 *
343 * Returns 0 success, non-zero when failure
344 */
345static int
346_scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle,
347 u64 *sas_address)
348{
349 Mpi2SasDevicePage0_t sas_device_pg0;
350 Mpi2ConfigReply_t mpi_reply;
351 u32 ioc_status;
352
353 if (handle <= ioc->sas_hba.num_phys) {
354 *sas_address = ioc->sas_hba.sas_address;
355 return 0;
356 } else
357 *sas_address = 0;
358
359 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
360 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
361 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
362 ioc->name, __FILE__, __LINE__, __func__);
363 return -ENXIO;
364 }
365
366 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
367 MPI2_IOCSTATUS_MASK;
368 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
369 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
370 "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
371 __FILE__, __LINE__, __func__);
372 return -EIO;
373 }
374
375 *sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
376 return 0;
377}
378
379/**
320 * _scsih_determine_boot_device - determine boot device. 380 * _scsih_determine_boot_device - determine boot device.
321 * @ioc: per adapter object 381 * @ioc: per adapter object
322 * @device: either sas_device or raid_device object 382 * @device: either sas_device or raid_device object
@@ -510,8 +570,6 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
510 struct _sas_device *sas_device) 570 struct _sas_device *sas_device)
511{ 571{
512 unsigned long flags; 572 unsigned long flags;
513 u16 handle, parent_handle;
514 u64 sas_address;
515 573
516 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle" 574 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle"
517 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, 575 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
@@ -521,10 +579,8 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
521 list_add_tail(&sas_device->list, &ioc->sas_device_list); 579 list_add_tail(&sas_device->list, &ioc->sas_device_list);
522 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 580 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
523 581
524 handle = sas_device->handle; 582 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
525 parent_handle = sas_device->parent_handle; 583 sas_device->sas_address_parent))
526 sas_address = sas_device->sas_address;
527 if (!mpt2sas_transport_port_add(ioc, handle, parent_handle))
528 _scsih_sas_device_remove(ioc, sas_device); 584 _scsih_sas_device_remove(ioc, sas_device);
529} 585}
530 586
@@ -553,31 +609,6 @@ _scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc,
553} 609}
554 610
555/** 611/**
556 * mpt2sas_scsih_expander_find_by_handle - expander device search
557 * @ioc: per adapter object
558 * @handle: expander handle (assigned by firmware)
559 * Context: Calling function should acquire ioc->sas_device_lock
560 *
561 * This searches for expander device based on handle, then returns the
562 * sas_node object.
563 */
564struct _sas_node *
565mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
566{
567 struct _sas_node *sas_expander, *r;
568
569 r = NULL;
570 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
571 if (sas_expander->handle != handle)
572 continue;
573 r = sas_expander;
574 goto out;
575 }
576 out:
577 return r;
578}
579
580/**
581 * _scsih_raid_device_find_by_id - raid device search 612 * _scsih_raid_device_find_by_id - raid device search
582 * @ioc: per adapter object 613 * @ioc: per adapter object
583 * @id: sas device target id 614 * @id: sas device target id
@@ -699,6 +730,31 @@ _scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc,
699} 730}
700 731
701/** 732/**
733 * mpt2sas_scsih_expander_find_by_handle - expander device search
734 * @ioc: per adapter object
735 * @handle: expander handle (assigned by firmware)
736 * Context: Calling function should acquire ioc->sas_device_lock
737 *
738 * This searches for expander device based on handle, then returns the
739 * sas_node object.
740 */
741struct _sas_node *
742mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
743{
744 struct _sas_node *sas_expander, *r;
745
746 r = NULL;
747 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
748 if (sas_expander->handle != handle)
749 continue;
750 r = sas_expander;
751 goto out;
752 }
753 out:
754 return r;
755}
756
757/**
702 * mpt2sas_scsih_expander_find_by_sas_address - expander device search 758 * mpt2sas_scsih_expander_find_by_sas_address - expander device search
703 * @ioc: per adapter object 759 * @ioc: per adapter object
704 * @sas_address: sas address 760 * @sas_address: sas address
@@ -1043,17 +1099,46 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
1043 * _scsih_change_queue_depth - setting device queue depth 1099 * _scsih_change_queue_depth - setting device queue depth
1044 * @sdev: scsi device struct 1100 * @sdev: scsi device struct
1045 * @qdepth: requested queue depth 1101 * @qdepth: requested queue depth
1102 * @reason: calling context
1046 * 1103 *
1047 * Returns queue depth. 1104 * Returns queue depth.
1048 */ 1105 */
1049static int 1106static int
1050_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) 1107_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
1051{ 1108{
1052 struct Scsi_Host *shost = sdev->host; 1109 struct Scsi_Host *shost = sdev->host;
1053 int max_depth; 1110 int max_depth;
1054 int tag_type; 1111 int tag_type;
1112 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1113 struct MPT2SAS_DEVICE *sas_device_priv_data;
1114 struct MPT2SAS_TARGET *sas_target_priv_data;
1115 struct _sas_device *sas_device;
1116 unsigned long flags;
1117
1118 if (reason != SCSI_QDEPTH_DEFAULT)
1119 return -EOPNOTSUPP;
1055 1120
1056 max_depth = shost->can_queue; 1121 max_depth = shost->can_queue;
1122
1123 /* limit max device queue for SATA to 32 */
1124 sas_device_priv_data = sdev->hostdata;
1125 if (!sas_device_priv_data)
1126 goto not_sata;
1127 sas_target_priv_data = sas_device_priv_data->sas_target;
1128 if (!sas_target_priv_data)
1129 goto not_sata;
1130 if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))
1131 goto not_sata;
1132 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1133 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1134 sas_device_priv_data->sas_target->sas_address);
1135 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1136 if (sas_device && sas_device->device_info &
1137 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1138 max_depth = MPT2SAS_SATA_QUEUE_DEPTH;
1139
1140 not_sata:
1141
1057 if (!sdev->tagged_supported) 1142 if (!sdev->tagged_supported)
1058 max_depth = 1; 1143 max_depth = 1;
1059 if (qdepth > max_depth) 1144 if (qdepth > max_depth)
@@ -1488,7 +1573,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
1488 r_level, raid_device->handle, 1573 r_level, raid_device->handle,
1489 (unsigned long long)raid_device->wwid, 1574 (unsigned long long)raid_device->wwid,
1490 raid_device->num_pds, ds); 1575 raid_device->num_pds, ds);
1491 _scsih_change_queue_depth(sdev, qdepth); 1576 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
1492 return 0; 1577 return 0;
1493 } 1578 }
1494 1579
@@ -1534,7 +1619,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
1534 _scsih_display_sata_capabilities(ioc, sas_device, sdev); 1619 _scsih_display_sata_capabilities(ioc, sas_device, sdev);
1535 } 1620 }
1536 1621
1537 _scsih_change_queue_depth(sdev, qdepth); 1622 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
1538 1623
1539 if (ssp_target) 1624 if (ssp_target)
1540 sas_read_port_mode_page(sdev); 1625 sas_read_port_mode_page(sdev);
@@ -1874,6 +1959,8 @@ _scsih_abort(struct scsi_cmnd *scmd)
1874 goto out; 1959 goto out;
1875 } 1960 }
1876 1961
1962 mpt2sas_halt_firmware(ioc);
1963
1877 mutex_lock(&ioc->tm_cmds.mutex); 1964 mutex_lock(&ioc->tm_cmds.mutex);
1878 handle = sas_device_priv_data->sas_target->handle; 1965 handle = sas_device_priv_data->sas_target->handle;
1879 mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun, 1966 mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun,
@@ -2297,7 +2384,6 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2297 u16 handle; 2384 u16 handle;
2298 u16 reason_code; 2385 u16 reason_code;
2299 u8 phy_number; 2386 u8 phy_number;
2300 u8 link_rate;
2301 2387
2302 for (i = 0; i < event_data->NumEntries; i++) { 2388 for (i = 0; i < event_data->NumEntries; i++) {
2303 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); 2389 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
@@ -2308,11 +2394,6 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2308 MPI2_EVENT_SAS_TOPO_RC_MASK; 2394 MPI2_EVENT_SAS_TOPO_RC_MASK;
2309 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING) 2395 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
2310 _scsih_block_io_device(ioc, handle); 2396 _scsih_block_io_device(ioc, handle);
2311 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED) {
2312 link_rate = event_data->PHY[i].LinkRate >> 4;
2313 if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
2314 _scsih_ublock_io_device(ioc, handle);
2315 }
2316 } 2397 }
2317} 2398}
2318 2399
@@ -2349,16 +2430,10 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2349 2430
2350 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2431 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2351 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2432 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2352 if (!sas_device) {
2353 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2354 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2355 ioc->name, __func__);
2356 return;
2357 }
2358 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2433 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2359 2434
2360 /* skip is hidden raid component */ 2435 /* skip is hidden raid component */
2361 if (sas_device->hidden_raid_component) 2436 if (sas_device && sas_device->hidden_raid_component)
2362 return; 2437 return;
2363 2438
2364 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); 2439 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
@@ -2371,18 +2446,31 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2371 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL; 2446 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
2372 list_add_tail(&delayed_tr->list, 2447 list_add_tail(&delayed_tr->list,
2373 &ioc->delayed_tr_list); 2448 &ioc->delayed_tr_list);
2374 if (sas_device->starget) 2449 if (sas_device && sas_device->starget) {
2375 dewtprintk(ioc, starget_printk(KERN_INFO, 2450 dewtprintk(ioc, starget_printk(KERN_INFO,
2376 sas_device->starget, "DELAYED:tr:handle(0x%04x), " 2451 sas_device->starget, "DELAYED:tr:handle(0x%04x), "
2377 "(open)\n", sas_device->handle)); 2452 "(open)\n", handle));
2453 } else {
2454 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2455 "DELAYED:tr:handle(0x%04x), (open)\n",
2456 ioc->name, handle));
2457 }
2378 return; 2458 return;
2379 } 2459 }
2380 2460
2381 if (sas_device->starget && sas_device->starget->hostdata) { 2461 if (sas_device) {
2382 sas_target_priv_data = sas_device->starget->hostdata; 2462 sas_device->state |= MPTSAS_STATE_TR_SEND;
2383 sas_target_priv_data->tm_busy = 1; 2463 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2384 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2464 if (sas_device->starget && sas_device->starget->hostdata) {
2385 "tr:handle(0x%04x), (open)\n", sas_device->handle)); 2465 sas_target_priv_data = sas_device->starget->hostdata;
2466 sas_target_priv_data->tm_busy = 1;
2467 dewtprintk(ioc, starget_printk(KERN_INFO,
2468 sas_device->starget, "tr:handle(0x%04x), (open)\n",
2469 handle));
2470 }
2471 } else {
2472 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2473 "tr:handle(0x%04x), (open)\n", ioc->name, handle));
2386 } 2474 }
2387 2475
2388 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 2476 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
@@ -2390,8 +2478,6 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2390 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; 2478 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
2391 mpi_request->DevHandle = cpu_to_le16(handle); 2479 mpi_request->DevHandle = cpu_to_le16(handle);
2392 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; 2480 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
2393 sas_device->state |= MPTSAS_STATE_TR_SEND;
2394 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2395 mpt2sas_base_put_smid_hi_priority(ioc, smid); 2481 mpt2sas_base_put_smid_hi_priority(ioc, smid);
2396} 2482}
2397 2483
@@ -2426,21 +2512,25 @@ _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2426 2512
2427 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2513 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2428 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2514 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2429 if (!sas_device) {
2430 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2431 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2432 ioc->name, __func__);
2433 return 1;
2434 }
2435 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
2436 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2515 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2437 2516
2438 if (sas_device->starget) 2517 if (sas_device) {
2439 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2518 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
2519 if (sas_device->starget)
2520 dewtprintk(ioc, starget_printk(KERN_INFO,
2521 sas_device->starget,
2522 "sc_complete:handle(0x%04x), "
2523 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2524 handle, le16_to_cpu(mpi_reply->IOCStatus),
2525 le32_to_cpu(mpi_reply->IOCLogInfo)));
2526 } else {
2527 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2440 "sc_complete:handle(0x%04x), " 2528 "sc_complete:handle(0x%04x), "
2441 "ioc_status(0x%04x), loginfo(0x%08x)\n", 2529 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2442 handle, le16_to_cpu(mpi_reply->IOCStatus), 2530 ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus),
2443 le32_to_cpu(mpi_reply->IOCLogInfo))); 2531 le32_to_cpu(mpi_reply->IOCLogInfo)));
2532 }
2533
2444 return 1; 2534 return 1;
2445} 2535}
2446 2536
@@ -2478,28 +2568,33 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2478 handle = le16_to_cpu(mpi_reply->DevHandle); 2568 handle = le16_to_cpu(mpi_reply->DevHandle);
2479 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2569 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2480 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2570 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2481 if (!sas_device) {
2482 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2483 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2484 ioc->name, __func__);
2485 return 1;
2486 }
2487 sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
2488 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2571 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2489 2572
2490 if (sas_device->starget) 2573 if (sas_device) {
2491 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2574 sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
2492 "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), " 2575 if (sas_device->starget) {
2493 "loginfo(0x%08x), completed(%d)\n", 2576 dewtprintk(ioc, starget_printk(KERN_INFO,
2494 sas_device->handle, (sas_device->state & 2577 sas_device->starget, "tr_complete:handle(0x%04x), "
2495 MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active", 2578 "(%s) ioc_status(0x%04x), loginfo(0x%08x), "
2496 le16_to_cpu(mpi_reply->IOCStatus), 2579 "completed(%d)\n", sas_device->handle,
2580 (sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ?
2581 "open" : "active",
2582 le16_to_cpu(mpi_reply->IOCStatus),
2583 le32_to_cpu(mpi_reply->IOCLogInfo),
2584 le32_to_cpu(mpi_reply->TerminationCount)));
2585 if (sas_device->starget->hostdata) {
2586 sas_target_priv_data =
2587 sas_device->starget->hostdata;
2588 sas_target_priv_data->tm_busy = 0;
2589 }
2590 }
2591 } else {
2592 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2593 "tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), "
2594 "loginfo(0x%08x), completed(%d)\n", ioc->name,
2595 handle, le16_to_cpu(mpi_reply->IOCStatus),
2497 le32_to_cpu(mpi_reply->IOCLogInfo), 2596 le32_to_cpu(mpi_reply->IOCLogInfo),
2498 le32_to_cpu(mpi_reply->TerminationCount))); 2597 le32_to_cpu(mpi_reply->TerminationCount)));
2499
2500 if (sas_device->starget && sas_device->starget->hostdata) {
2501 sas_target_priv_data = sas_device->starget->hostdata;
2502 sas_target_priv_data->tm_busy = 0;
2503 } 2598 }
2504 2599
2505 if (!list_empty(&ioc->delayed_tr_list)) { 2600 if (!list_empty(&ioc->delayed_tr_list)) {
@@ -2514,8 +2609,7 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2514 } else 2609 } else
2515 rc = 1; 2610 rc = 1;
2516 2611
2517 2612 if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2518 if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2519 return rc; 2613 return rc;
2520 2614
2521 if (ioc->shost_recovery) { 2615 if (ioc->shost_recovery) {
@@ -2531,12 +2625,14 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2531 return rc; 2625 return rc;
2532 } 2626 }
2533 2627
2628 if (sas_device)
2629 sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
2630
2534 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); 2631 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
2535 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); 2632 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
2536 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 2633 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
2537 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; 2634 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
2538 mpi_request->DevHandle = mpi_reply->DevHandle; 2635 mpi_request->DevHandle = mpi_reply->DevHandle;
2539 sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
2540 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); 2636 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
2541 return rc; 2637 return rc;
2542} 2638}
@@ -2678,8 +2774,6 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2678 else 2774 else
2679 return; 2775 return;
2680 2776
2681 mpi_request->EEDPBlockSize = scmd->device->sector_size;
2682
2683 switch (prot_type) { 2777 switch (prot_type) {
2684 case SCSI_PROT_DIF_TYPE1: 2778 case SCSI_PROT_DIF_TYPE1:
2685 2779
@@ -2687,8 +2781,7 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2687 * enable ref/guard checking 2781 * enable ref/guard checking
2688 * auto increment ref tag 2782 * auto increment ref tag
2689 */ 2783 */
2690 mpi_request->EEDPFlags = eedp_flags | 2784 eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
2691 MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
2692 MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | 2785 MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
2693 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; 2786 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2694 mpi_request->CDB.EEDP32.PrimaryReferenceTag = 2787 mpi_request->CDB.EEDP32.PrimaryReferenceTag =
@@ -2701,11 +2794,11 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2701 /* 2794 /*
2702 * enable guard checking 2795 * enable guard checking
2703 */ 2796 */
2704 mpi_request->EEDPFlags = eedp_flags | 2797 eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2705 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2706
2707 break; 2798 break;
2708 } 2799 }
2800 mpi_request->EEDPBlockSize = cpu_to_le32(scmd->device->sector_size);
2801 mpi_request->EEDPFlags = cpu_to_le16(eedp_flags);
2709} 2802}
2710 2803
2711/** 2804/**
@@ -2788,7 +2881,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2788 } 2881 }
2789 2882
2790 /* see if we are busy with task managment stuff */ 2883 /* see if we are busy with task managment stuff */
2791 if (sas_target_priv_data->tm_busy) 2884 if (sas_device_priv_data->block || sas_target_priv_data->tm_busy)
2792 return SCSI_MLQUEUE_DEVICE_BUSY; 2885 return SCSI_MLQUEUE_DEVICE_BUSY;
2793 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress) 2886 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
2794 return SCSI_MLQUEUE_HOST_BUSY; 2887 return SCSI_MLQUEUE_HOST_BUSY;
@@ -2842,7 +2935,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2842 mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR; 2935 mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR;
2843 mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; 2936 mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
2844 mpi_request->SenseBufferLowAddress = 2937 mpi_request->SenseBufferLowAddress =
2845 (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid); 2938 mpt2sas_base_get_sense_buffer_dma(ioc, smid);
2846 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4; 2939 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
2847 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI + 2940 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI +
2848 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR); 2941 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR);
@@ -3059,7 +3152,7 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3059 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 3152 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
3060 response_info = le32_to_cpu(mpi_reply->ResponseInfo); 3153 response_info = le32_to_cpu(mpi_reply->ResponseInfo);
3061 response_bytes = (u8 *)&response_info; 3154 response_bytes = (u8 *)&response_info;
3062 _scsih_response_code(ioc, response_bytes[3]); 3155 _scsih_response_code(ioc, response_bytes[0]);
3063 } 3156 }
3064} 3157}
3065#endif 3158#endif
@@ -3177,7 +3270,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3177 u8 scsi_status; 3270 u8 scsi_status;
3178 u32 log_info; 3271 u32 log_info;
3179 struct MPT2SAS_DEVICE *sas_device_priv_data; 3272 struct MPT2SAS_DEVICE *sas_device_priv_data;
3180 u32 response_code; 3273 u32 response_code = 0;
3181 3274
3182 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 3275 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
3183 scmd = _scsih_scsi_lookup_get(ioc, smid); 3276 scmd = _scsih_scsi_lookup_get(ioc, smid);
@@ -3199,16 +3292,16 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3199 } 3292 }
3200 3293
3201 /* turning off TLR */ 3294 /* turning off TLR */
3295 scsi_state = mpi_reply->SCSIState;
3296 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
3297 response_code =
3298 le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
3202 if (!sas_device_priv_data->tlr_snoop_check) { 3299 if (!sas_device_priv_data->tlr_snoop_check) {
3203 sas_device_priv_data->tlr_snoop_check++; 3300 sas_device_priv_data->tlr_snoop_check++;
3204 if (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) { 3301 if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) &&
3205 response_code = (le32_to_cpu(mpi_reply->ResponseInfo) 3302 response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
3206 >> 24); 3303 sas_device_priv_data->flags &=
3207 if (response_code == 3304 ~MPT_DEVICE_TLR_ON;
3208 MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
3209 sas_device_priv_data->flags &=
3210 ~MPT_DEVICE_TLR_ON;
3211 }
3212 } 3305 }
3213 3306
3214 xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); 3307 xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
@@ -3219,7 +3312,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3219 else 3312 else
3220 log_info = 0; 3313 log_info = 0;
3221 ioc_status &= MPI2_IOCSTATUS_MASK; 3314 ioc_status &= MPI2_IOCSTATUS_MASK;
3222 scsi_state = mpi_reply->SCSIState;
3223 scsi_status = mpi_reply->SCSIStatus; 3315 scsi_status = mpi_reply->SCSIStatus;
3224 3316
3225 if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 && 3317 if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
@@ -3255,10 +3347,9 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3255 3347
3256 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: 3348 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
3257 if (sas_device_priv_data->block) { 3349 if (sas_device_priv_data->block) {
3258 scmd->result = (DID_BUS_BUSY << 16); 3350 scmd->result = DID_TRANSPORT_DISRUPTED << 16;
3259 break; 3351 goto out;
3260 } 3352 }
3261
3262 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: 3353 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
3263 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: 3354 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
3264 scmd->result = DID_RESET << 16; 3355 scmd->result = DID_RESET << 16;
@@ -3304,8 +3395,10 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3304 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR: 3395 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
3305 case MPI2_IOCSTATUS_SUCCESS: 3396 case MPI2_IOCSTATUS_SUCCESS:
3306 scmd->result = (DID_OK << 16) | scsi_status; 3397 scmd->result = (DID_OK << 16) | scsi_status;
3307 if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED | 3398 if (response_code ==
3308 MPI2_SCSI_STATE_NO_SCSI_STATUS)) 3399 MPI2_SCSITASKMGMT_RSP_INVALID_FRAME ||
3400 (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
3401 MPI2_SCSI_STATE_NO_SCSI_STATUS)))
3309 scmd->result = DID_SOFT_ERROR << 16; 3402 scmd->result = DID_SOFT_ERROR << 16;
3310 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED) 3403 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
3311 scmd->result = DID_RESET << 16; 3404 scmd->result = DID_RESET << 16;
@@ -3344,7 +3437,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3344/** 3437/**
3345 * _scsih_sas_host_refresh - refreshing sas host object contents 3438 * _scsih_sas_host_refresh - refreshing sas host object contents
3346 * @ioc: per adapter object 3439 * @ioc: per adapter object
3347 * @update: update link information
3348 * Context: user 3440 * Context: user
3349 * 3441 *
3350 * During port enable, fw will send topology events for every device. Its 3442 * During port enable, fw will send topology events for every device. Its
@@ -3354,13 +3446,14 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3354 * Return nothing. 3446 * Return nothing.
3355 */ 3447 */
3356static void 3448static void
3357_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update) 3449_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
3358{ 3450{
3359 u16 sz; 3451 u16 sz;
3360 u16 ioc_status; 3452 u16 ioc_status;
3361 int i; 3453 int i;
3362 Mpi2ConfigReply_t mpi_reply; 3454 Mpi2ConfigReply_t mpi_reply;
3363 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; 3455 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
3456 u16 attached_handle;
3364 3457
3365 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT 3458 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
3366 "updating handles for sas_host(0x%016llx)\n", 3459 "updating handles for sas_host(0x%016llx)\n",
@@ -3374,27 +3467,24 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update)
3374 ioc->name, __FILE__, __LINE__, __func__); 3467 ioc->name, __FILE__, __LINE__, __func__);
3375 return; 3468 return;
3376 } 3469 }
3377 if (!(mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
3378 sas_iounit_pg0, sz))) {
3379 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3380 MPI2_IOCSTATUS_MASK;
3381 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
3382 goto out;
3383 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
3384 ioc->sas_hba.phy[i].handle =
3385 le16_to_cpu(sas_iounit_pg0->PhyData[i].
3386 ControllerDevHandle);
3387 if (update)
3388 mpt2sas_transport_update_links(
3389 ioc,
3390 ioc->sas_hba.phy[i].handle,
3391 le16_to_cpu(sas_iounit_pg0->PhyData[i].
3392 AttachedDevHandle), i,
3393 sas_iounit_pg0->PhyData[i].
3394 NegotiatedLinkRate >> 4);
3395 }
3396 }
3397 3470
3471 if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
3472 sas_iounit_pg0, sz)) != 0)
3473 goto out;
3474 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
3475 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
3476 goto out;
3477 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
3478 if (i == 0)
3479 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
3480 PhyData[0].ControllerDevHandle);
3481 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
3482 attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
3483 AttachedDevHandle);
3484 mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address,
3485 attached_handle, i, sas_iounit_pg0->PhyData[i].
3486 NegotiatedLinkRate >> 4);
3487 }
3398 out: 3488 out:
3399 kfree(sas_iounit_pg0); 3489 kfree(sas_iounit_pg0);
3400} 3490}
@@ -3507,19 +3597,21 @@ _scsih_sas_host_add(struct MPT2SAS_ADAPTER *ioc)
3507 ioc->name, __FILE__, __LINE__, __func__); 3597 ioc->name, __FILE__, __LINE__, __func__);
3508 goto out; 3598 goto out;
3509 } 3599 }
3510 ioc->sas_hba.phy[i].handle = 3600
3511 le16_to_cpu(sas_iounit_pg0->PhyData[i].ControllerDevHandle); 3601 if (i == 0)
3602 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
3603 PhyData[0].ControllerDevHandle);
3604 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
3512 ioc->sas_hba.phy[i].phy_id = i; 3605 ioc->sas_hba.phy[i].phy_id = i;
3513 mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], 3606 mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i],
3514 phy_pg0, ioc->sas_hba.parent_dev); 3607 phy_pg0, ioc->sas_hba.parent_dev);
3515 } 3608 }
3516 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, 3609 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
3517 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.phy[0].handle))) { 3610 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) {
3518 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 3611 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3519 ioc->name, __FILE__, __LINE__, __func__); 3612 ioc->name, __FILE__, __LINE__, __func__);
3520 goto out; 3613 goto out;
3521 } 3614 }
3522 ioc->sas_hba.handle = le16_to_cpu(sas_device_pg0.DevHandle);
3523 ioc->sas_hba.enclosure_handle = 3615 ioc->sas_hba.enclosure_handle =
3524 le16_to_cpu(sas_device_pg0.EnclosureHandle); 3616 le16_to_cpu(sas_device_pg0.EnclosureHandle);
3525 ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress); 3617 ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
@@ -3562,7 +3654,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3562 Mpi2SasEnclosurePage0_t enclosure_pg0; 3654 Mpi2SasEnclosurePage0_t enclosure_pg0;
3563 u32 ioc_status; 3655 u32 ioc_status;
3564 u16 parent_handle; 3656 u16 parent_handle;
3565 __le64 sas_address; 3657 __le64 sas_address, sas_address_parent = 0;
3566 int i; 3658 int i;
3567 unsigned long flags; 3659 unsigned long flags;
3568 struct _sas_port *mpt2sas_port = NULL; 3660 struct _sas_port *mpt2sas_port = NULL;
@@ -3591,10 +3683,16 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3591 3683
3592 /* handle out of order topology events */ 3684 /* handle out of order topology events */
3593 parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle); 3685 parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle);
3594 if (parent_handle >= ioc->sas_hba.num_phys) { 3686 if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent)
3687 != 0) {
3688 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3689 ioc->name, __FILE__, __LINE__, __func__);
3690 return -1;
3691 }
3692 if (sas_address_parent != ioc->sas_hba.sas_address) {
3595 spin_lock_irqsave(&ioc->sas_node_lock, flags); 3693 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3596 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, 3694 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
3597 parent_handle); 3695 sas_address_parent);
3598 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 3696 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3599 if (!sas_expander) { 3697 if (!sas_expander) {
3600 rc = _scsih_expander_add(ioc, parent_handle); 3698 rc = _scsih_expander_add(ioc, parent_handle);
@@ -3622,14 +3720,12 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3622 3720
3623 sas_expander->handle = handle; 3721 sas_expander->handle = handle;
3624 sas_expander->num_phys = expander_pg0.NumPhys; 3722 sas_expander->num_phys = expander_pg0.NumPhys;
3625 sas_expander->parent_handle = parent_handle; 3723 sas_expander->sas_address_parent = sas_address_parent;
3626 sas_expander->enclosure_handle =
3627 le16_to_cpu(expander_pg0.EnclosureHandle);
3628 sas_expander->sas_address = sas_address; 3724 sas_expander->sas_address = sas_address;
3629 3725
3630 printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x)," 3726 printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x),"
3631 " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name, 3727 " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name,
3632 handle, sas_expander->parent_handle, (unsigned long long) 3728 handle, parent_handle, (unsigned long long)
3633 sas_expander->sas_address, sas_expander->num_phys); 3729 sas_expander->sas_address, sas_expander->num_phys);
3634 3730
3635 if (!sas_expander->num_phys) 3731 if (!sas_expander->num_phys)
@@ -3645,7 +3741,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3645 3741
3646 INIT_LIST_HEAD(&sas_expander->sas_port_list); 3742 INIT_LIST_HEAD(&sas_expander->sas_port_list);
3647 mpt2sas_port = mpt2sas_transport_port_add(ioc, handle, 3743 mpt2sas_port = mpt2sas_transport_port_add(ioc, handle,
3648 sas_expander->parent_handle); 3744 sas_address_parent);
3649 if (!mpt2sas_port) { 3745 if (!mpt2sas_port) {
3650 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 3746 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3651 ioc->name, __FILE__, __LINE__, __func__); 3747 ioc->name, __FILE__, __LINE__, __func__);
@@ -3691,20 +3787,54 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3691 3787
3692 if (mpt2sas_port) 3788 if (mpt2sas_port)
3693 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, 3789 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
3694 sas_expander->parent_handle); 3790 sas_address_parent);
3695 kfree(sas_expander); 3791 kfree(sas_expander);
3696 return rc; 3792 return rc;
3697} 3793}
3698 3794
3699/** 3795/**
3796 * _scsih_done - scsih callback handler.
3797 * @ioc: per adapter object
3798 * @smid: system request message index
3799 * @msix_index: MSIX table index supplied by the OS
3800 * @reply: reply message frame(lower 32bit addr)
3801 *
3802 * Callback handler when sending internal generated message frames.
3803 * The callback index passed is `ioc->scsih_cb_idx`
3804 *
3805 * Return 1 meaning mf should be freed from _base_interrupt
3806 * 0 means the mf is freed from this function.
3807 */
3808static u8
3809_scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3810{
3811 MPI2DefaultReply_t *mpi_reply;
3812
3813 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
3814 if (ioc->scsih_cmds.status == MPT2_CMD_NOT_USED)
3815 return 1;
3816 if (ioc->scsih_cmds.smid != smid)
3817 return 1;
3818 ioc->scsih_cmds.status |= MPT2_CMD_COMPLETE;
3819 if (mpi_reply) {
3820 memcpy(ioc->scsih_cmds.reply, mpi_reply,
3821 mpi_reply->MsgLength*4);
3822 ioc->scsih_cmds.status |= MPT2_CMD_REPLY_VALID;
3823 }
3824 ioc->scsih_cmds.status &= ~MPT2_CMD_PENDING;
3825 complete(&ioc->scsih_cmds.done);
3826 return 1;
3827}
3828
3829/**
3700 * _scsih_expander_remove - removing expander object 3830 * _scsih_expander_remove - removing expander object
3701 * @ioc: per adapter object 3831 * @ioc: per adapter object
3702 * @handle: expander handle 3832 * @sas_address: expander sas_address
3703 * 3833 *
3704 * Return nothing. 3834 * Return nothing.
3705 */ 3835 */
3706static void 3836static void
3707_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle) 3837_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
3708{ 3838{
3709 struct _sas_node *sas_expander; 3839 struct _sas_node *sas_expander;
3710 unsigned long flags; 3840 unsigned long flags;
@@ -3713,7 +3843,8 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3713 return; 3843 return;
3714 3844
3715 spin_lock_irqsave(&ioc->sas_node_lock, flags); 3845 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3716 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle); 3846 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
3847 sas_address);
3717 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 3848 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3718 _scsih_expander_node_remove(ioc, sas_expander); 3849 _scsih_expander_node_remove(ioc, sas_expander);
3719} 3850}
@@ -3805,8 +3936,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3805 } 3936 }
3806 3937
3807 sas_device->handle = handle; 3938 sas_device->handle = handle;
3808 sas_device->parent_handle = 3939 if (_scsih_get_sas_address(ioc, le16_to_cpu
3809 le16_to_cpu(sas_device_pg0.ParentDevHandle); 3940 (sas_device_pg0.ParentDevHandle),
3941 &sas_device->sas_address_parent) != 0)
3942 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3943 ioc->name, __FILE__, __LINE__, __func__);
3810 sas_device->enclosure_handle = 3944 sas_device->enclosure_handle =
3811 le16_to_cpu(sas_device_pg0.EnclosureHandle); 3945 le16_to_cpu(sas_device_pg0.EnclosureHandle);
3812 sas_device->slot = 3946 sas_device->slot =
@@ -3836,43 +3970,39 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3836/** 3970/**
3837 * _scsih_remove_device - removing sas device object 3971 * _scsih_remove_device - removing sas device object
3838 * @ioc: per adapter object 3972 * @ioc: per adapter object
3839 * @handle: sas device handle 3973 * @sas_device: the sas_device object
3840 * 3974 *
3841 * Return nothing. 3975 * Return nothing.
3842 */ 3976 */
3843static void 3977static void
3844_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) 3978_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device
3979 *sas_device)
3845{ 3980{
3846 struct MPT2SAS_TARGET *sas_target_priv_data; 3981 struct MPT2SAS_TARGET *sas_target_priv_data;
3847 struct _sas_device *sas_device;
3848 unsigned long flags;
3849 Mpi2SasIoUnitControlReply_t mpi_reply; 3982 Mpi2SasIoUnitControlReply_t mpi_reply;
3850 Mpi2SasIoUnitControlRequest_t mpi_request; 3983 Mpi2SasIoUnitControlRequest_t mpi_request;
3851 u16 device_handle; 3984 u16 device_handle, handle;
3852 3985
3853 /* lookup sas_device */ 3986 if (!sas_device)
3854 spin_lock_irqsave(&ioc->sas_device_lock, flags);
3855 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
3856 if (!sas_device) {
3857 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3858 return; 3987 return;
3859 }
3860 3988
3861 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle" 3989 handle = sas_device->handle;
3862 "(0x%04x)\n", ioc->name, __func__, handle)); 3990 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x),"
3991 " sas_addr(0x%016llx)\n", ioc->name, __func__, handle,
3992 (unsigned long long) sas_device->sas_address));
3863 3993
3864 if (sas_device->starget && sas_device->starget->hostdata) { 3994 if (sas_device->starget && sas_device->starget->hostdata) {
3865 sas_target_priv_data = sas_device->starget->hostdata; 3995 sas_target_priv_data = sas_device->starget->hostdata;
3866 sas_target_priv_data->deleted = 1; 3996 sas_target_priv_data->deleted = 1;
3867 } 3997 }
3868 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3869 3998
3870 if (ioc->remove_host) 3999 if (ioc->remove_host || ioc->shost_recovery || !handle)
3871 goto out; 4000 goto out;
3872 4001
3873 if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { 4002 if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) {
3874 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " 4003 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
3875 "target_reset handle(0x%04x)\n", ioc->name, handle)); 4004 "target_reset handle(0x%04x)\n", ioc->name,
4005 handle));
3876 goto skip_tr; 4006 goto skip_tr;
3877 } 4007 }
3878 4008
@@ -3925,10 +4055,10 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3925 _scsih_ublock_io_device(ioc, handle); 4055 _scsih_ublock_io_device(ioc, handle);
3926 4056
3927 mpt2sas_transport_port_remove(ioc, sas_device->sas_address, 4057 mpt2sas_transport_port_remove(ioc, sas_device->sas_address,
3928 sas_device->parent_handle); 4058 sas_device->sas_address_parent);
3929 4059
3930 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" 4060 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
3931 "(0x%016llx)\n", ioc->name, sas_device->handle, 4061 "(0x%016llx)\n", ioc->name, handle,
3932 (unsigned long long) sas_device->sas_address); 4062 (unsigned long long) sas_device->sas_address);
3933 _scsih_sas_device_remove(ioc, sas_device); 4063 _scsih_sas_device_remove(ioc, sas_device);
3934 4064
@@ -3952,7 +4082,7 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3952 u16 reason_code; 4082 u16 reason_code;
3953 u8 phy_number; 4083 u8 phy_number;
3954 char *status_str = NULL; 4084 char *status_str = NULL;
3955 char link_rate[25]; 4085 u8 link_rate, prev_link_rate;
3956 4086
3957 switch (event_data->ExpStatus) { 4087 switch (event_data->ExpStatus) {
3958 case MPI2_EVENT_SAS_TOPO_ES_ADDED: 4088 case MPI2_EVENT_SAS_TOPO_ES_ADDED:
@@ -3962,6 +4092,7 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3962 status_str = "remove"; 4092 status_str = "remove";
3963 break; 4093 break;
3964 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: 4094 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
4095 case 0:
3965 status_str = "responding"; 4096 status_str = "responding";
3966 break; 4097 break;
3967 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: 4098 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
@@ -3987,30 +4118,30 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3987 MPI2_EVENT_SAS_TOPO_RC_MASK; 4118 MPI2_EVENT_SAS_TOPO_RC_MASK;
3988 switch (reason_code) { 4119 switch (reason_code) {
3989 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 4120 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
3990 snprintf(link_rate, 25, ": add, link(0x%02x)", 4121 status_str = "target add";
3991 (event_data->PHY[i].LinkRate >> 4));
3992 status_str = link_rate;
3993 break; 4122 break;
3994 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 4123 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
3995 status_str = ": remove"; 4124 status_str = "target remove";
3996 break; 4125 break;
3997 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: 4126 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
3998 status_str = ": remove_delay"; 4127 status_str = "delay target remove";
3999 break; 4128 break;
4000 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 4129 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
4001 snprintf(link_rate, 25, ": link(0x%02x)", 4130 status_str = "link rate change";
4002 (event_data->PHY[i].LinkRate >> 4));
4003 status_str = link_rate;
4004 break; 4131 break;
4005 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: 4132 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
4006 status_str = ": responding"; 4133 status_str = "target responding";
4007 break; 4134 break;
4008 default: 4135 default:
4009 status_str = ": unknown"; 4136 status_str = "unknown";
4010 break; 4137 break;
4011 } 4138 }
4012 printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x)%s\n", 4139 link_rate = event_data->PHY[i].LinkRate >> 4;
4013 phy_number, handle, status_str); 4140 prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
4141 printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x): %s:"
4142 " link rate: new(0x%02x), old(0x%02x)\n", phy_number,
4143 handle, status_str, link_rate, prev_link_rate);
4144
4014 } 4145 }
4015} 4146}
4016#endif 4147#endif
@@ -4031,8 +4162,10 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4031 u16 reason_code; 4162 u16 reason_code;
4032 u8 phy_number; 4163 u8 phy_number;
4033 struct _sas_node *sas_expander; 4164 struct _sas_node *sas_expander;
4165 struct _sas_device *sas_device;
4166 u64 sas_address;
4034 unsigned long flags; 4167 unsigned long flags;
4035 u8 link_rate_; 4168 u8 link_rate, prev_link_rate;
4036 Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data; 4169 Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data;
4037 4170
4038#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4171#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4040,10 +4173,13 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4040 _scsih_sas_topology_change_event_debug(ioc, event_data); 4173 _scsih_sas_topology_change_event_debug(ioc, event_data);
4041#endif 4174#endif
4042 4175
4176 if (ioc->shost_recovery)
4177 return;
4178
4043 if (!ioc->sas_hba.num_phys) 4179 if (!ioc->sas_hba.num_phys)
4044 _scsih_sas_host_add(ioc); 4180 _scsih_sas_host_add(ioc);
4045 else 4181 else
4046 _scsih_sas_host_refresh(ioc, 0); 4182 _scsih_sas_host_refresh(ioc);
4047 4183
4048 if (fw_event->ignore) { 4184 if (fw_event->ignore) {
4049 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander " 4185 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander "
@@ -4058,6 +4194,17 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4058 if (_scsih_expander_add(ioc, parent_handle) != 0) 4194 if (_scsih_expander_add(ioc, parent_handle) != 0)
4059 return; 4195 return;
4060 4196
4197 spin_lock_irqsave(&ioc->sas_node_lock, flags);
4198 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
4199 parent_handle);
4200 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
4201 if (sas_expander)
4202 sas_address = sas_expander->sas_address;
4203 else if (parent_handle < ioc->sas_hba.num_phys)
4204 sas_address = ioc->sas_hba.sas_address;
4205 else
4206 return;
4207
4061 /* handle siblings events */ 4208 /* handle siblings events */
4062 for (i = 0; i < event_data->NumEntries; i++) { 4209 for (i = 0; i < event_data->NumEntries; i++) {
4063 if (fw_event->ignore) { 4210 if (fw_event->ignore) {
@@ -4077,48 +4224,47 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4077 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); 4224 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
4078 if (!handle) 4225 if (!handle)
4079 continue; 4226 continue;
4080 link_rate_ = event_data->PHY[i].LinkRate >> 4; 4227 link_rate = event_data->PHY[i].LinkRate >> 4;
4228 prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
4081 switch (reason_code) { 4229 switch (reason_code) {
4082 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 4230 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
4231
4232 if (link_rate == prev_link_rate)
4233 break;
4234
4235 mpt2sas_transport_update_links(ioc, sas_address,
4236 handle, phy_number, link_rate);
4237
4238 if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
4239 _scsih_ublock_io_device(ioc, handle);
4240 break;
4083 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 4241 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
4084 if (!parent_handle) { 4242
4085 if (phy_number < ioc->sas_hba.num_phys) 4243 mpt2sas_transport_update_links(ioc, sas_address,
4086 mpt2sas_transport_update_links( 4244 handle, phy_number, link_rate);
4087 ioc, 4245
4088 ioc->sas_hba.phy[phy_number].handle, 4246 _scsih_add_device(ioc, handle, phy_number, 0);
4089 handle, phy_number, link_rate_);
4090 } else {
4091 spin_lock_irqsave(&ioc->sas_node_lock, flags);
4092 sas_expander =
4093 mpt2sas_scsih_expander_find_by_handle(ioc,
4094 parent_handle);
4095 spin_unlock_irqrestore(&ioc->sas_node_lock,
4096 flags);
4097 if (sas_expander) {
4098 if (phy_number < sas_expander->num_phys)
4099 mpt2sas_transport_update_links(
4100 ioc,
4101 sas_expander->
4102 phy[phy_number].handle,
4103 handle, phy_number,
4104 link_rate_);
4105 }
4106 }
4107 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED) {
4108 if (link_rate_ < MPI2_SAS_NEG_LINK_RATE_1_5)
4109 break;
4110 _scsih_add_device(ioc, handle, phy_number, 0);
4111 }
4112 break; 4247 break;
4113 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 4248 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
4114 _scsih_remove_device(ioc, handle); 4249
4250 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4251 sas_device = _scsih_sas_device_find_by_handle(ioc,
4252 handle);
4253 if (!sas_device) {
4254 spin_unlock_irqrestore(&ioc->sas_device_lock,
4255 flags);
4256 break;
4257 }
4258 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4259 _scsih_remove_device(ioc, sas_device);
4115 break; 4260 break;
4116 } 4261 }
4117 } 4262 }
4118 4263
4119 /* handle expander removal */ 4264 /* handle expander removal */
4120 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING) 4265 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
4121 _scsih_expander_remove(ioc, parent_handle); 4266 sas_expander)
4267 _scsih_expander_remove(ioc, sas_address);
4122 4268
4123} 4269}
4124 4270
@@ -4170,6 +4316,12 @@ _scsih_sas_device_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4170 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: 4316 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
4171 reason_str = "internal async notification"; 4317 reason_str = "internal async notification";
4172 break; 4318 break;
4319 case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY:
4320 reason_str = "expander reduced functionality";
4321 break;
4322 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY:
4323 reason_str = "expander reduced functionality complete";
4324 break;
4173 default: 4325 default:
4174 reason_str = "unknown reason"; 4326 reason_str = "unknown reason";
4175 break; 4327 break;
@@ -4197,11 +4349,43 @@ static void
4197_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, 4349_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
4198 struct fw_event_work *fw_event) 4350 struct fw_event_work *fw_event)
4199{ 4351{
4352 struct MPT2SAS_TARGET *target_priv_data;
4353 struct _sas_device *sas_device;
4354 __le64 sas_address;
4355 unsigned long flags;
4356 Mpi2EventDataSasDeviceStatusChange_t *event_data =
4357 fw_event->event_data;
4358
4200#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4359#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4201 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4360 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4202 _scsih_sas_device_status_change_event_debug(ioc, 4361 _scsih_sas_device_status_change_event_debug(ioc,
4203 fw_event->event_data); 4362 event_data);
4204#endif 4363#endif
4364
4365 if (!(event_data->ReasonCode ==
4366 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
4367 event_data->ReasonCode ==
4368 MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET))
4369 return;
4370
4371 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4372 sas_address = le64_to_cpu(event_data->SASAddress);
4373 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
4374 sas_address);
4375 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4376
4377 if (!sas_device || !sas_device->starget)
4378 return;
4379
4380 target_priv_data = sas_device->starget->hostdata;
4381 if (!target_priv_data)
4382 return;
4383
4384 if (event_data->ReasonCode ==
4385 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
4386 target_priv_data->tm_busy = 1;
4387 else
4388 target_priv_data->tm_busy = 0;
4205} 4389}
4206 4390
4207#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4391#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4281,6 +4465,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4281#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4465#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4282 Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; 4466 Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
4283#endif 4467#endif
4468 u16 ioc_status;
4284 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: " 4469 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: "
4285 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, 4470 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
4286 event_data->PortWidth)); 4471 event_data->PortWidth));
@@ -4314,8 +4499,9 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4314 mpt2sas_scsih_issue_tm(ioc, handle, lun, 4499 mpt2sas_scsih_issue_tm(ioc, handle, lun,
4315 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30); 4500 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30);
4316 ioc->tm_cmds.status = MPT2_CMD_NOT_USED; 4501 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
4317 4502 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
4318 if ((mpi_reply->IOCStatus == MPI2_IOCSTATUS_SUCCESS) && 4503 & MPI2_IOCSTATUS_MASK;
4504 if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
4319 (mpi_reply->ResponseCode == 4505 (mpi_reply->ResponseCode ==
4320 MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || 4506 MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4321 mpi_reply->ResponseCode == 4507 mpi_reply->ResponseCode ==
@@ -4570,7 +4756,7 @@ _scsih_sas_pd_delete(struct MPT2SAS_ADAPTER *ioc,
4570 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 4756 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4571 if (!sas_device) 4757 if (!sas_device)
4572 return; 4758 return;
4573 _scsih_remove_device(ioc, handle); 4759 _scsih_remove_device(ioc, sas_device);
4574} 4760}
4575 4761
4576/** 4762/**
@@ -4591,6 +4777,8 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
4591 Mpi2ConfigReply_t mpi_reply; 4777 Mpi2ConfigReply_t mpi_reply;
4592 Mpi2SasDevicePage0_t sas_device_pg0; 4778 Mpi2SasDevicePage0_t sas_device_pg0;
4593 u32 ioc_status; 4779 u32 ioc_status;
4780 u64 sas_address;
4781 u16 parent_handle;
4594 4782
4595 spin_lock_irqsave(&ioc->sas_device_lock, flags); 4783 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4596 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 4784 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
@@ -4615,9 +4803,10 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
4615 return; 4803 return;
4616 } 4804 }
4617 4805
4618 mpt2sas_transport_update_links(ioc, 4806 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
4619 le16_to_cpu(sas_device_pg0.ParentDevHandle), 4807 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
4620 handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); 4808 mpt2sas_transport_update_links(ioc, sas_address, handle,
4809 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
4621 4810
4622 _scsih_add_device(ioc, handle, 0, 1); 4811 _scsih_add_device(ioc, handle, 0, 1);
4623} 4812}
@@ -4857,7 +5046,7 @@ static void
4857_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, 5046_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
4858 struct fw_event_work *fw_event) 5047 struct fw_event_work *fw_event)
4859{ 5048{
4860 u16 handle; 5049 u16 handle, parent_handle;
4861 u32 state; 5050 u32 state;
4862 struct _sas_device *sas_device; 5051 struct _sas_device *sas_device;
4863 unsigned long flags; 5052 unsigned long flags;
@@ -4865,6 +5054,7 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
4865 Mpi2SasDevicePage0_t sas_device_pg0; 5054 Mpi2SasDevicePage0_t sas_device_pg0;
4866 u32 ioc_status; 5055 u32 ioc_status;
4867 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data; 5056 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
5057 u64 sas_address;
4868 5058
4869 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) 5059 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
4870 return; 5060 return;
@@ -4906,9 +5096,10 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
4906 return; 5096 return;
4907 } 5097 }
4908 5098
4909 mpt2sas_transport_update_links(ioc, 5099 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
4910 le16_to_cpu(sas_device_pg0.ParentDevHandle), 5100 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
4911 handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); 5101 mpt2sas_transport_update_links(ioc, sas_address, handle,
5102 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
4912 5103
4913 _scsih_add_device(ioc, handle, 0, 1); 5104 _scsih_add_device(ioc, handle, 0, 1);
4914 5105
@@ -4948,11 +5139,17 @@ _scsih_sas_ir_operation_status_event_debug(struct MPT2SAS_ADAPTER *ioc,
4948 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: 5139 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
4949 reason_str = "consistency check"; 5140 reason_str = "consistency check";
4950 break; 5141 break;
4951 default: 5142 case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT:
4952 reason_str = "unknown reason"; 5143 reason_str = "background init";
5144 break;
5145 case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT:
5146 reason_str = "make data consistent";
4953 break; 5147 break;
4954 } 5148 }
4955 5149
5150 if (!reason_str)
5151 return;
5152
4956 printk(MPT2SAS_INFO_FMT "raid operational status: (%s)" 5153 printk(MPT2SAS_INFO_FMT "raid operational status: (%s)"
4957 "\thandle(0x%04x), percent complete(%d)\n", 5154 "\thandle(0x%04x), percent complete(%d)\n",
4958 ioc->name, reason_str, 5155 ioc->name, reason_str,
@@ -5252,18 +5449,23 @@ _scsih_mark_responding_expander(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5252{ 5449{
5253 struct _sas_node *sas_expander; 5450 struct _sas_node *sas_expander;
5254 unsigned long flags; 5451 unsigned long flags;
5452 int i;
5255 5453
5256 spin_lock_irqsave(&ioc->sas_node_lock, flags); 5454 spin_lock_irqsave(&ioc->sas_node_lock, flags);
5257 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { 5455 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
5258 if (sas_expander->sas_address == sas_address) { 5456 if (sas_expander->sas_address != sas_address)
5259 sas_expander->responding = 1; 5457 continue;
5260 if (sas_expander->handle != handle) { 5458 sas_expander->responding = 1;
5261 printk(KERN_INFO "old handle(0x%04x)\n", 5459 if (sas_expander->handle == handle)
5262 sas_expander->handle);
5263 sas_expander->handle = handle;
5264 }
5265 goto out; 5460 goto out;
5266 } 5461 printk(KERN_INFO "\texpander(0x%016llx): handle changed"
5462 " from(0x%04x) to (0x%04x)!!!\n",
5463 (unsigned long long)sas_expander->sas_address,
5464 sas_expander->handle, handle);
5465 sas_expander->handle = handle;
5466 for (i = 0 ; i < sas_expander->num_phys ; i++)
5467 sas_expander->phy[i].handle = handle;
5468 goto out;
5267 } 5469 }
5268 out: 5470 out:
5269 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 5471 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
@@ -5340,7 +5542,9 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5340 (unsigned long long) 5542 (unsigned long long)
5341 sas_device->enclosure_logical_id, 5543 sas_device->enclosure_logical_id,
5342 sas_device->slot); 5544 sas_device->slot);
5343 _scsih_remove_device(ioc, sas_device->handle); 5545 /* invalidate the device handle */
5546 sas_device->handle = 0;
5547 _scsih_remove_device(ioc, sas_device);
5344 } 5548 }
5345 5549
5346 list_for_each_entry_safe(raid_device, raid_device_next, 5550 list_for_each_entry_safe(raid_device, raid_device_next,
@@ -5366,7 +5570,7 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5366 sas_expander->responding = 0; 5570 sas_expander->responding = 0;
5367 continue; 5571 continue;
5368 } 5572 }
5369 _scsih_expander_remove(ioc, sas_expander->handle); 5573 _scsih_expander_remove(ioc, sas_expander->sas_address);
5370 goto retry_expander_search; 5574 goto retry_expander_search;
5371 } 5575 }
5372} 5576}
@@ -5406,7 +5610,7 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
5406 case MPT2_IOC_DONE_RESET: 5610 case MPT2_IOC_DONE_RESET:
5407 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 5611 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5408 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); 5612 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
5409 _scsih_sas_host_refresh(ioc, 0); 5613 _scsih_sas_host_refresh(ioc);
5410 _scsih_search_responding_sas_devices(ioc); 5614 _scsih_search_responding_sas_devices(ioc);
5411 _scsih_search_responding_raid_devices(ioc); 5615 _scsih_search_responding_raid_devices(ioc);
5412 _scsih_search_responding_expanders(ioc); 5616 _scsih_search_responding_expanders(ioc);
@@ -5646,7 +5850,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5646 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 5850 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5647 if (!sas_device) 5851 if (!sas_device)
5648 continue; 5852 continue;
5649 _scsih_remove_device(ioc, sas_device->handle); 5853 _scsih_remove_device(ioc, sas_device);
5650 if (ioc->shost_recovery) 5854 if (ioc->shost_recovery)
5651 return; 5855 return;
5652 goto retry_device_search; 5856 goto retry_device_search;
@@ -5669,7 +5873,8 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5669 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 5873 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5670 if (!expander_sibling) 5874 if (!expander_sibling)
5671 continue; 5875 continue;
5672 _scsih_expander_remove(ioc, expander_sibling->handle); 5876 _scsih_expander_remove(ioc,
5877 expander_sibling->sas_address);
5673 if (ioc->shost_recovery) 5878 if (ioc->shost_recovery)
5674 return; 5879 return;
5675 goto retry_expander_search; 5880 goto retry_expander_search;
@@ -5677,7 +5882,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5677 } 5882 }
5678 5883
5679 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, 5884 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
5680 sas_expander->parent_handle); 5885 sas_expander->sas_address_parent);
5681 5886
5682 printk(MPT2SAS_INFO_FMT "expander_remove: handle" 5887 printk(MPT2SAS_INFO_FMT "expander_remove: handle"
5683 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, 5888 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name,
@@ -5690,9 +5895,99 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5690} 5895}
5691 5896
5692/** 5897/**
5898 * _scsih_ir_shutdown - IR shutdown notification
5899 * @ioc: per adapter object
5900 *
5901 * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that
5902 * the host system is shutting down.
5903 *
5904 * Return nothing.
5905 */
5906static void
5907_scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
5908{
5909 Mpi2RaidActionRequest_t *mpi_request;
5910 Mpi2RaidActionReply_t *mpi_reply;
5911 u16 smid;
5912
5913 /* is IR firmware build loaded ? */
5914 if (!ioc->ir_firmware)
5915 return;
5916
5917 /* are there any volumes ? */
5918 if (list_empty(&ioc->raid_device_list))
5919 return;
5920
5921 mutex_lock(&ioc->scsih_cmds.mutex);
5922
5923 if (ioc->scsih_cmds.status != MPT2_CMD_NOT_USED) {
5924 printk(MPT2SAS_ERR_FMT "%s: scsih_cmd in use\n",
5925 ioc->name, __func__);
5926 goto out;
5927 }
5928 ioc->scsih_cmds.status = MPT2_CMD_PENDING;
5929
5930 smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx);
5931 if (!smid) {
5932 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
5933 ioc->name, __func__);
5934 ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
5935 goto out;
5936 }
5937
5938 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
5939 ioc->scsih_cmds.smid = smid;
5940 memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t));
5941
5942 mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
5943 mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
5944
5945 printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
5946 init_completion(&ioc->scsih_cmds.done);
5947 mpt2sas_base_put_smid_default(ioc, smid);
5948 wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
5949
5950 if (!(ioc->scsih_cmds.status & MPT2_CMD_COMPLETE)) {
5951 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
5952 ioc->name, __func__);
5953 goto out;
5954 }
5955
5956 if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) {
5957 mpi_reply = ioc->scsih_cmds.reply;
5958
5959 printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
5960 "ioc_status(0x%04x), loginfo(0x%08x)\n",
5961 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
5962 le32_to_cpu(mpi_reply->IOCLogInfo));
5963 }
5964
5965 out:
5966 ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
5967 mutex_unlock(&ioc->scsih_cmds.mutex);
5968}
5969
5970/**
5971 * _scsih_shutdown - routine call during system shutdown
5972 * @pdev: PCI device struct
5973 *
5974 * Return nothing.
5975 */
5976static void
5977_scsih_shutdown(struct pci_dev *pdev)
5978{
5979 struct Scsi_Host *shost = pci_get_drvdata(pdev);
5980 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
5981
5982 _scsih_ir_shutdown(ioc);
5983 mpt2sas_base_detach(ioc);
5984}
5985
5986/**
5693 * _scsih_remove - detach and remove add host 5987 * _scsih_remove - detach and remove add host
5694 * @pdev: PCI device struct 5988 * @pdev: PCI device struct
5695 * 5989 *
5990 * Routine called when unloading the driver.
5696 * Return nothing. 5991 * Return nothing.
5697 */ 5992 */
5698static void __devexit 5993static void __devexit
@@ -5726,7 +6021,7 @@ _scsih_remove(struct pci_dev *pdev)
5726 mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 6021 mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
5727 mpt2sas_port->remote_identify.sas_address); 6022 mpt2sas_port->remote_identify.sas_address);
5728 if (sas_device) { 6023 if (sas_device) {
5729 _scsih_remove_device(ioc, sas_device->handle); 6024 _scsih_remove_device(ioc, sas_device);
5730 goto retry_again; 6025 goto retry_again;
5731 } 6026 }
5732 } else { 6027 } else {
@@ -5735,7 +6030,7 @@ _scsih_remove(struct pci_dev *pdev)
5735 mpt2sas_port->remote_identify.sas_address); 6030 mpt2sas_port->remote_identify.sas_address);
5736 if (expander_sibling) { 6031 if (expander_sibling) {
5737 _scsih_expander_remove(ioc, 6032 _scsih_expander_remove(ioc,
5738 expander_sibling->handle); 6033 expander_sibling->sas_address);
5739 goto retry_again; 6034 goto retry_again;
5740 } 6035 }
5741 } 6036 }
@@ -5749,7 +6044,7 @@ _scsih_remove(struct pci_dev *pdev)
5749 } 6044 }
5750 6045
5751 sas_remove_host(shost); 6046 sas_remove_host(shost);
5752 mpt2sas_base_detach(ioc); 6047 _scsih_shutdown(pdev);
5753 list_del(&ioc->list); 6048 list_del(&ioc->list);
5754 scsi_remove_host(shost); 6049 scsi_remove_host(shost);
5755 scsi_host_put(shost); 6050 scsi_host_put(shost);
@@ -5770,7 +6065,8 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
5770 void *device; 6065 void *device;
5771 struct _sas_device *sas_device; 6066 struct _sas_device *sas_device;
5772 struct _raid_device *raid_device; 6067 struct _raid_device *raid_device;
5773 u16 handle, parent_handle; 6068 u16 handle;
6069 u64 sas_address_parent;
5774 u64 sas_address; 6070 u64 sas_address;
5775 unsigned long flags; 6071 unsigned long flags;
5776 int rc; 6072 int rc;
@@ -5799,17 +6095,17 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
5799 } else { 6095 } else {
5800 sas_device = device; 6096 sas_device = device;
5801 handle = sas_device->handle; 6097 handle = sas_device->handle;
5802 parent_handle = sas_device->parent_handle; 6098 sas_address_parent = sas_device->sas_address_parent;
5803 sas_address = sas_device->sas_address; 6099 sas_address = sas_device->sas_address;
5804 spin_lock_irqsave(&ioc->sas_device_lock, flags); 6100 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5805 list_move_tail(&sas_device->list, &ioc->sas_device_list); 6101 list_move_tail(&sas_device->list, &ioc->sas_device_list);
5806 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 6102 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5807 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 6103 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
5808 sas_device->parent_handle)) { 6104 sas_device->sas_address_parent)) {
5809 _scsih_sas_device_remove(ioc, sas_device); 6105 _scsih_sas_device_remove(ioc, sas_device);
5810 } else if (!sas_device->starget) { 6106 } else if (!sas_device->starget) {
5811 mpt2sas_transport_port_remove(ioc, sas_address, 6107 mpt2sas_transport_port_remove(ioc, sas_address,
5812 parent_handle); 6108 sas_address_parent);
5813 _scsih_sas_device_remove(ioc, sas_device); 6109 _scsih_sas_device_remove(ioc, sas_device);
5814 } 6110 }
5815 } 6111 }
@@ -5849,8 +6145,6 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
5849{ 6145{
5850 struct _sas_device *sas_device, *next; 6146 struct _sas_device *sas_device, *next;
5851 unsigned long flags; 6147 unsigned long flags;
5852 u16 handle, parent_handle;
5853 u64 sas_address;
5854 6148
5855 /* SAS Device List */ 6149 /* SAS Device List */
5856 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, 6150 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
@@ -5859,14 +6153,13 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
5859 list_move_tail(&sas_device->list, &ioc->sas_device_list); 6153 list_move_tail(&sas_device->list, &ioc->sas_device_list);
5860 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 6154 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5861 6155
5862 handle = sas_device->handle; 6156 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
5863 parent_handle = sas_device->parent_handle; 6157 sas_device->sas_address_parent)) {
5864 sas_address = sas_device->sas_address;
5865 if (!mpt2sas_transport_port_add(ioc, handle, parent_handle)) {
5866 _scsih_sas_device_remove(ioc, sas_device); 6158 _scsih_sas_device_remove(ioc, sas_device);
5867 } else if (!sas_device->starget) { 6159 } else if (!sas_device->starget) {
5868 mpt2sas_transport_port_remove(ioc, sas_address, 6160 mpt2sas_transport_port_remove(ioc,
5869 parent_handle); 6161 sas_device->sas_address,
6162 sas_device->sas_address_parent);
5870 _scsih_sas_device_remove(ioc, sas_device); 6163 _scsih_sas_device_remove(ioc, sas_device);
5871 } 6164 }
5872 } 6165 }
@@ -5935,6 +6228,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5935 ioc->ctl_cb_idx = ctl_cb_idx; 6228 ioc->ctl_cb_idx = ctl_cb_idx;
5936 ioc->base_cb_idx = base_cb_idx; 6229 ioc->base_cb_idx = base_cb_idx;
5937 ioc->transport_cb_idx = transport_cb_idx; 6230 ioc->transport_cb_idx = transport_cb_idx;
6231 ioc->scsih_cb_idx = scsih_cb_idx;
5938 ioc->config_cb_idx = config_cb_idx; 6232 ioc->config_cb_idx = config_cb_idx;
5939 ioc->tm_tr_cb_idx = tm_tr_cb_idx; 6233 ioc->tm_tr_cb_idx = tm_tr_cb_idx;
5940 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; 6234 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
@@ -6072,6 +6366,7 @@ static struct pci_driver scsih_driver = {
6072 .id_table = scsih_pci_table, 6366 .id_table = scsih_pci_table,
6073 .probe = _scsih_probe, 6367 .probe = _scsih_probe,
6074 .remove = __devexit_p(_scsih_remove), 6368 .remove = __devexit_p(_scsih_remove),
6369 .shutdown = _scsih_shutdown,
6075#ifdef CONFIG_PM 6370#ifdef CONFIG_PM
6076 .suspend = _scsih_suspend, 6371 .suspend = _scsih_suspend,
6077 .resume = _scsih_resume, 6372 .resume = _scsih_resume,
@@ -6113,6 +6408,9 @@ _scsih_init(void)
6113 transport_cb_idx = mpt2sas_base_register_callback_handler( 6408 transport_cb_idx = mpt2sas_base_register_callback_handler(
6114 mpt2sas_transport_done); 6409 mpt2sas_transport_done);
6115 6410
6411 /* scsih internal commands callback handler */
6412 scsih_cb_idx = mpt2sas_base_register_callback_handler(_scsih_done);
6413
6116 /* configuration page API internal commands callback handler */ 6414 /* configuration page API internal commands callback handler */
6117 config_cb_idx = mpt2sas_base_register_callback_handler( 6415 config_cb_idx = mpt2sas_base_register_callback_handler(
6118 mpt2sas_config_done); 6416 mpt2sas_config_done);
@@ -6152,6 +6450,7 @@ _scsih_exit(void)
6152 mpt2sas_base_release_callback_handler(tm_cb_idx); 6450 mpt2sas_base_release_callback_handler(tm_cb_idx);
6153 mpt2sas_base_release_callback_handler(base_cb_idx); 6451 mpt2sas_base_release_callback_handler(base_cb_idx);
6154 mpt2sas_base_release_callback_handler(transport_cb_idx); 6452 mpt2sas_base_release_callback_handler(transport_cb_idx);
6453 mpt2sas_base_release_callback_handler(scsih_cb_idx);
6155 mpt2sas_base_release_callback_handler(config_cb_idx); 6454 mpt2sas_base_release_callback_handler(config_cb_idx);
6156 mpt2sas_base_release_callback_handler(ctl_cb_idx); 6455 mpt2sas_base_release_callback_handler(ctl_cb_idx);
6157 6456
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index eb98188c7f3f..3a82872bad44 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -59,24 +59,23 @@
59 59
60#include "mpt2sas_base.h" 60#include "mpt2sas_base.h"
61/** 61/**
62 * _transport_sas_node_find_by_handle - sas node search 62 * _transport_sas_node_find_by_sas_address - sas node search
63 * @ioc: per adapter object 63 * @ioc: per adapter object
64 * @handle: expander or hba handle (assigned by firmware) 64 * @sas_address: sas address of expander or sas host
65 * Context: Calling function should acquire ioc->sas_node_lock. 65 * Context: Calling function should acquire ioc->sas_node_lock.
66 * 66 *
67 * Search for either hba phys or expander device based on handle, then returns 67 * Search for either hba phys or expander device based on handle, then returns
68 * the sas_node object. 68 * the sas_node object.
69 */ 69 */
70static struct _sas_node * 70static struct _sas_node *
71_transport_sas_node_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) 71_transport_sas_node_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
72 u64 sas_address)
72{ 73{
73 int i; 74 if (ioc->sas_hba.sas_address == sas_address)
74 75 return &ioc->sas_hba;
75 for (i = 0; i < ioc->sas_hba.num_phys; i++) 76 else
76 if (ioc->sas_hba.phy[i].handle == handle) 77 return mpt2sas_scsih_expander_find_by_sas_address(ioc,
77 return &ioc->sas_hba; 78 sas_address);
78
79 return mpt2sas_scsih_expander_find_by_handle(ioc, handle);
80} 79}
81 80
82/** 81/**
@@ -259,8 +258,7 @@ struct rep_manu_reply{
259 u8 response_length; 258 u8 response_length;
260 u16 expander_change_count; 259 u16 expander_change_count;
261 u8 reserved0[2]; 260 u8 reserved0[2];
262 u8 sas_format:1; 261 u8 sas_format;
263 u8 reserved1:7;
264 u8 reserved2[3]; 262 u8 reserved2[3];
265 u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN]; 263 u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
266 u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN]; 264 u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
@@ -375,7 +373,8 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
375 mpi_request->VP_ID = 0; 373 mpi_request->VP_ID = 0;
376 sas_address_le = (u64 *)&mpi_request->SASAddress; 374 sas_address_le = (u64 *)&mpi_request->SASAddress;
377 *sas_address_le = cpu_to_le64(sas_address); 375 *sas_address_le = cpu_to_le64(sas_address);
378 mpi_request->RequestDataLength = sizeof(struct rep_manu_request); 376 mpi_request->RequestDataLength =
377 cpu_to_le16(sizeof(struct rep_manu_request));
379 psge = &mpi_request->SGL; 378 psge = &mpi_request->SGL;
380 379
381 /* WRITE sgel first */ 380 /* WRITE sgel first */
@@ -438,8 +437,8 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
438 SAS_EXPANDER_PRODUCT_ID_LEN); 437 SAS_EXPANDER_PRODUCT_ID_LEN);
439 strncpy(edev->product_rev, manufacture_reply->product_rev, 438 strncpy(edev->product_rev, manufacture_reply->product_rev,
440 SAS_EXPANDER_PRODUCT_REV_LEN); 439 SAS_EXPANDER_PRODUCT_REV_LEN);
441 edev->level = manufacture_reply->sas_format; 440 edev->level = manufacture_reply->sas_format & 1;
442 if (manufacture_reply->sas_format) { 441 if (edev->level) {
443 strncpy(edev->component_vendor_id, 442 strncpy(edev->component_vendor_id,
444 manufacture_reply->component_vendor_id, 443 manufacture_reply->component_vendor_id,
445 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); 444 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
@@ -469,7 +468,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
469 * mpt2sas_transport_port_add - insert port to the list 468 * mpt2sas_transport_port_add - insert port to the list
470 * @ioc: per adapter object 469 * @ioc: per adapter object
471 * @handle: handle of attached device 470 * @handle: handle of attached device
472 * @parent_handle: parent handle(either hba or expander) 471 * @sas_address: sas address of parent expander or sas host
473 * Context: This function will acquire ioc->sas_node_lock. 472 * Context: This function will acquire ioc->sas_node_lock.
474 * 473 *
475 * Adding new port object to the sas_node->sas_port_list. 474 * Adding new port object to the sas_node->sas_port_list.
@@ -478,7 +477,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
478 */ 477 */
479struct _sas_port * 478struct _sas_port *
480mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle, 479mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
481 u16 parent_handle) 480 u64 sas_address)
482{ 481{
483 struct _sas_phy *mpt2sas_phy, *next; 482 struct _sas_phy *mpt2sas_phy, *next;
484 struct _sas_port *mpt2sas_port; 483 struct _sas_port *mpt2sas_port;
@@ -488,9 +487,6 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
488 int i; 487 int i;
489 struct sas_port *port; 488 struct sas_port *port;
490 489
491 if (!parent_handle)
492 return NULL;
493
494 mpt2sas_port = kzalloc(sizeof(struct _sas_port), 490 mpt2sas_port = kzalloc(sizeof(struct _sas_port),
495 GFP_KERNEL); 491 GFP_KERNEL);
496 if (!mpt2sas_port) { 492 if (!mpt2sas_port) {
@@ -502,17 +498,16 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
502 INIT_LIST_HEAD(&mpt2sas_port->port_list); 498 INIT_LIST_HEAD(&mpt2sas_port->port_list);
503 INIT_LIST_HEAD(&mpt2sas_port->phy_list); 499 INIT_LIST_HEAD(&mpt2sas_port->phy_list);
504 spin_lock_irqsave(&ioc->sas_node_lock, flags); 500 spin_lock_irqsave(&ioc->sas_node_lock, flags);
505 sas_node = _transport_sas_node_find_by_handle(ioc, parent_handle); 501 sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
506 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 502 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
507 503
508 if (!sas_node) { 504 if (!sas_node) {
509 printk(MPT2SAS_ERR_FMT "%s: Could not find parent(0x%04x)!\n", 505 printk(MPT2SAS_ERR_FMT "%s: Could not find "
510 ioc->name, __func__, parent_handle); 506 "parent sas_address(0x%016llx)!\n", ioc->name,
507 __func__, (unsigned long long)sas_address);
511 goto out_fail; 508 goto out_fail;
512 } 509 }
513 510
514 mpt2sas_port->handle = parent_handle;
515 mpt2sas_port->sas_address = sas_node->sas_address;
516 if ((_transport_set_identify(ioc, handle, 511 if ((_transport_set_identify(ioc, handle,
517 &mpt2sas_port->remote_identify))) { 512 &mpt2sas_port->remote_identify))) {
518 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 513 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
@@ -604,7 +599,7 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
604 * mpt2sas_transport_port_remove - remove port from the list 599 * mpt2sas_transport_port_remove - remove port from the list
605 * @ioc: per adapter object 600 * @ioc: per adapter object
606 * @sas_address: sas address of attached device 601 * @sas_address: sas address of attached device
607 * @parent_handle: handle to the upstream parent(either hba or expander) 602 * @sas_address_parent: sas address of parent expander or sas host
608 * Context: This function will acquire ioc->sas_node_lock. 603 * Context: This function will acquire ioc->sas_node_lock.
609 * 604 *
610 * Removing object and freeing associated memory from the 605 * Removing object and freeing associated memory from the
@@ -614,7 +609,7 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
614 */ 609 */
615void 610void
616mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, 611mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
617 u16 parent_handle) 612 u64 sas_address_parent)
618{ 613{
619 int i; 614 int i;
620 unsigned long flags; 615 unsigned long flags;
@@ -624,7 +619,8 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
624 struct _sas_phy *mpt2sas_phy, *next_phy; 619 struct _sas_phy *mpt2sas_phy, *next_phy;
625 620
626 spin_lock_irqsave(&ioc->sas_node_lock, flags); 621 spin_lock_irqsave(&ioc->sas_node_lock, flags);
627 sas_node = _transport_sas_node_find_by_handle(ioc, parent_handle); 622 sas_node = _transport_sas_node_find_by_sas_address(ioc,
623 sas_address_parent);
628 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 624 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
629 if (!sas_node) 625 if (!sas_node)
630 return; 626 return;
@@ -650,8 +646,7 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
650 &mpt2sas_port->phy_list, port_siblings) { 646 &mpt2sas_port->phy_list, port_siblings) {
651 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 647 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
652 dev_printk(KERN_INFO, &mpt2sas_port->port->dev, 648 dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
653 "remove: parent_handle(0x%04x), " 649 "remove: sas_addr(0x%016llx), phy(%d)\n",
654 "sas_addr(0x%016llx), phy(%d)\n", parent_handle,
655 (unsigned long long) 650 (unsigned long long)
656 mpt2sas_port->remote_identify.sas_address, 651 mpt2sas_port->remote_identify.sas_address,
657 mpt2sas_phy->phy_id); 652 mpt2sas_phy->phy_id);
@@ -799,8 +794,8 @@ mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
799/** 794/**
800 * mpt2sas_transport_update_links - refreshing phy link changes 795 * mpt2sas_transport_update_links - refreshing phy link changes
801 * @ioc: per adapter object 796 * @ioc: per adapter object
802 * @handle: handle to sas_host or expander 797 * @sas_address: sas address of parent expander or sas host
803 * @attached_handle: attached device handle 798 * @handle: attached device handle
804 * @phy_numberv: phy number 799 * @phy_numberv: phy number
805 * @link_rate: new link rate 800 * @link_rate: new link rate
806 * 801 *
@@ -808,28 +803,25 @@ mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
808 */ 803 */
809void 804void
810mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, 805mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
811 u16 handle, u16 attached_handle, u8 phy_number, u8 link_rate) 806 u64 sas_address, u16 handle, u8 phy_number, u8 link_rate)
812{ 807{
813 unsigned long flags; 808 unsigned long flags;
814 struct _sas_node *sas_node; 809 struct _sas_node *sas_node;
815 struct _sas_phy *mpt2sas_phy; 810 struct _sas_phy *mpt2sas_phy;
816 811
817 if (ioc->shost_recovery) { 812 if (ioc->shost_recovery)
818 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
819 __func__, ioc->name);
820 return; 813 return;
821 }
822 814
823 spin_lock_irqsave(&ioc->sas_node_lock, flags); 815 spin_lock_irqsave(&ioc->sas_node_lock, flags);
824 sas_node = _transport_sas_node_find_by_handle(ioc, handle); 816 sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
825 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 817 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
826 if (!sas_node) 818 if (!sas_node)
827 return; 819 return;
828 820
829 mpt2sas_phy = &sas_node->phy[phy_number]; 821 mpt2sas_phy = &sas_node->phy[phy_number];
830 mpt2sas_phy->attached_handle = attached_handle; 822 mpt2sas_phy->attached_handle = handle;
831 if (attached_handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) 823 if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5))
832 _transport_set_identify(ioc, mpt2sas_phy->attached_handle, 824 _transport_set_identify(ioc, handle,
833 &mpt2sas_phy->remote_identify); 825 &mpt2sas_phy->remote_identify);
834 else 826 else
835 memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct 827 memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct
@@ -841,13 +833,11 @@ mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
841 833
842 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 834 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
843 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, 835 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
844 "refresh: handle(0x%04x), sas_addr(0x%016llx),\n" 836 "refresh: parent sas_addr(0x%016llx),\n"
845 "\tlink_rate(0x%02x), phy(%d)\n" 837 "\tlink_rate(0x%02x), phy(%d)\n"
846 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", 838 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
847 handle, (unsigned long long) 839 (unsigned long long)sas_address,
848 mpt2sas_phy->identify.sas_address, link_rate, 840 link_rate, phy_number, handle, (unsigned long long)
849 phy_number, attached_handle,
850 (unsigned long long)
851 mpt2sas_phy->remote_identify.sas_address); 841 mpt2sas_phy->remote_identify.sas_address);
852} 842}
853 843
@@ -1126,7 +1116,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1126 dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio), 1116 dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
1127 blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); 1117 blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
1128 if (!dma_addr_out) { 1118 if (!dma_addr_out) {
1129 mpt2sas_base_free_smid(ioc, le16_to_cpu(smid)); 1119 mpt2sas_base_free_smid(ioc, smid);
1130 goto unmap; 1120 goto unmap;
1131 } 1121 }
1132 1122
@@ -1144,7 +1134,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1144 dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio), 1134 dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio),
1145 blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); 1135 blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
1146 if (!dma_addr_in) { 1136 if (!dma_addr_in) {
1147 mpt2sas_base_free_smid(ioc, le16_to_cpu(smid)); 1137 mpt2sas_base_free_smid(ioc, smid);
1148 goto unmap; 1138 goto unmap;
1149 } 1139 }
1150 1140