diff options
| author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-12-26 09:52:54 -0500 |
|---|---|---|
| committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-12-26 09:52:54 -0500 |
| commit | 7f50548abb5454bd82c25aae15f0a3bf6a530f46 (patch) | |
| tree | 175b5d695437151f0f9f778ad8eb7f274468842f /drivers/scsi/mpt2sas | |
| parent | b3172f222ab5afdc91ea058bd11c42cf169728f3 (diff) | |
| parent | 6b7b284958d47b77d06745b36bc7f36dab769d9b (diff) | |
Merge commit 'v2.6.33-rc2' into for-2.6.33
Diffstat (limited to 'drivers/scsi/mpt2sas')
| -rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2.h | 5 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h | 274 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_ioc.h | 18 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_raid.h | 14 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_tool.h | 16 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 157 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 37 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.c | 197 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.h | 4 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 821 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_transport.c | 86 |
11 files changed, 1212 insertions, 417 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 | |||
| 817 | typedef 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 | |||
| 1831 | typedef 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 | |||
| 1880 | typedef 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) */ | ||
| 2504 | typedef 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 | |||
| 2512 | typedef 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 | |||
| 2565 | typedef 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 | |||
| 479 | typedef 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 | ||
| 474 | typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED | 489 | typedef 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 | ||
| 283 | typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST | 287 | typedef 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 | ||
| 315 | typedef struct _MPI2_DIAG_BUFFER_POST_REPLY | 323 | typedef 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..89d02401b9ec 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; | |||
| 77 | module_param(msix_disable, int, 0); | 78 | module_param(msix_disable, int, 0); |
| 78 | MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); | 79 | MODULE_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 | */ | ||
| 88 | static int diag_buffer_enable; | ||
| 89 | module_param(diag_buffer_enable, int, 0); | ||
| 90 | MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers " | ||
| 91 | "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)"); | ||
| 92 | |||
| 93 | int mpt2sas_fwfault_debug; | ||
| 94 | MODULE_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 | */ | ||
| 101 | static 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 | } | ||
| 116 | module_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 | */ | ||
| 226 | void | ||
| 227 | mpt2sas_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 | */ | ||
| 242 | void | ||
| 243 | mpt2sas_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 | */ | ||
| 535 | void | ||
| 536 | mpt2sas_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 | */ |
| 1263 | dma_addr_t | 1333 | __le32 |
| 1264 | mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid) | 1334 | mpt2sas_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(¤t_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 | ||
| @@ -3496,6 +3583,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
| 3496 | ioc->transport_cmds.status = MPT2_CMD_NOT_USED; | 3583 | ioc->transport_cmds.status = MPT2_CMD_NOT_USED; |
| 3497 | mutex_init(&ioc->transport_cmds.mutex); | 3584 | mutex_init(&ioc->transport_cmds.mutex); |
| 3498 | 3585 | ||
| 3586 | /* scsih internal command bits */ | ||
| 3587 | ioc->scsih_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | ||
| 3588 | ioc->scsih_cmds.status = MPT2_CMD_NOT_USED; | ||
| 3589 | mutex_init(&ioc->scsih_cmds.mutex); | ||
| 3590 | |||
| 3499 | /* task management internal command bits */ | 3591 | /* task management internal command bits */ |
| 3500 | ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | 3592 | ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); |
| 3501 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; | 3593 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; |
| @@ -3531,6 +3623,8 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
| 3531 | goto out_free_resources; | 3623 | goto out_free_resources; |
| 3532 | 3624 | ||
| 3533 | mpt2sas_base_start_watchdog(ioc); | 3625 | mpt2sas_base_start_watchdog(ioc); |
| 3626 | if (diag_buffer_enable != 0) | ||
| 3627 | mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); | ||
| 3534 | return 0; | 3628 | return 0; |
| 3535 | 3629 | ||
| 3536 | out_free_resources: | 3630 | out_free_resources: |
| @@ -3684,6 +3778,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, | 3778 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, |
| 3685 | __func__)); | 3779 | __func__)); |
| 3686 | 3780 | ||
| 3781 | if (mpt2sas_fwfault_debug) | ||
| 3782 | mpt2sas_halt_firmware(ioc); | ||
| 3783 | |||
| 3687 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | 3784 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); |
| 3688 | if (ioc->shost_recovery) { | 3785 | if (ioc->shost_recovery) { |
| 3689 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | 3786 | 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 | */ |
| 363 | struct _sas_port { | 361 | struct _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, | |||
| 773 | void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid); | 775 | void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid); |
| 774 | void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid); | 776 | void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid); |
| 775 | void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr); | 777 | void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr); |
| 776 | dma_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); |
| 808 | void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type); | 810 | void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type); |
| 809 | 811 | ||
| 812 | void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc); | ||
| 813 | |||
| 810 | /* scsih shared API */ | 814 | /* scsih shared API */ |
| 811 | u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | 815 | u8 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, | |||
| 886 | void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, | 890 | void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, |
| 887 | Mpi2EventNotificationReply_t *mpi_reply); | 891 | Mpi2EventNotificationReply_t *mpi_reply); |
| 888 | 892 | ||
| 893 | void mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, | ||
| 894 | u8 bits_to_regsiter); | ||
| 895 | |||
| 889 | /* transport shared API */ | 896 | /* transport shared API */ |
| 890 | u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 897 | u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
| 891 | u32 reply); | 898 | u32 reply); |
| 892 | struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, | 899 | struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, |
| 893 | u16 handle, u16 parent_handle); | 900 | u16 handle, u64 sas_address); |
| 894 | void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | 901 | void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, |
| 895 | u16 parent_handle); | 902 | u64 sas_address_parent); |
| 896 | int mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy | 903 | int 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); |
| 898 | int mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy | 905 | int 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); |
| 900 | void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, u16 handle, | 907 | void 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); |
| 902 | extern struct sas_function_template mpt2sas_transport_functions; | 909 | extern struct sas_function_template mpt2sas_transport_functions; |
| 903 | extern struct scsi_transport_template *mpt2sas_transport_template; | 910 | extern struct scsi_transport_template *mpt2sas_transport_template; |
| 904 | extern int scsi_internal_device_block(struct scsi_device *sdev); | 911 | extern 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 | */ |
| 1265 | static long | 1269 | static 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 | */ | ||
| 1442 | void | ||
| 1443 | mpt2sas_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 | */ | ||
| 1488 | static 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, | |||
| 2474 | static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR, | 2541 | static 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 | */ | ||
| 2553 | static 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 | } | ||
| 2562 | static 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 | } | ||
| 2578 | static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR, | ||
| 2579 | _ctl_fwfault_debug_show, _ctl_fwfault_debug_store); | ||
| 2580 | |||
| 2477 | struct device_attribute *mpt2sas_host_attrs[] = { | 2581 | struct 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..efabea1a3ce4 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; | |||
| 76 | static u8 ctl_cb_idx = -1; | 76 | static u8 ctl_cb_idx = -1; |
| 77 | static u8 base_cb_idx = -1; | 77 | static u8 base_cb_idx = -1; |
| 78 | static u8 transport_cb_idx = -1; | 78 | static u8 transport_cb_idx = -1; |
| 79 | static u8 scsih_cb_idx = -1; | ||
| 79 | static u8 config_cb_idx = -1; | 80 | static u8 config_cb_idx = -1; |
| 80 | static int mpt_ids; | 81 | static 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 | }; |
| 205 | MODULE_DEVICE_TABLE(pci, scsih_pci_table); | 224 | MODULE_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 | */ | ||
| 345 | static 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 | */ | ||
| 564 | struct _sas_node * | ||
| 565 | mpt2sas_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 | */ | ||
| 741 | struct _sas_node * | ||
| 742 | mpt2sas_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 | */ |
| 1049 | static int | 1106 | static 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); |
| @@ -2894,7 +2987,7 @@ _scsih_normalize_sense(char *sense_buffer, struct sense_info *data) | |||
| 2894 | 2987 | ||
| 2895 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 2988 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
| 2896 | /** | 2989 | /** |
| 2897 | * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request | 2990 | * _scsih_scsi_ioc_info - translated non-successfull SCSI_IO request |
| 2898 | * @ioc: per adapter object | 2991 | * @ioc: per adapter object |
| 2899 | * @scmd: pointer to scsi command object | 2992 | * @scmd: pointer to scsi command object |
| 2900 | * @mpi_reply: reply mf payload returned from firmware | 2993 | * @mpi_reply: reply mf payload returned from firmware |
| @@ -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 | */ |
| 3356 | static void | 3448 | static 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 | */ | ||
| 3808 | static 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 | */ |
| 3706 | static void | 3836 | static 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 | */ |
| 3843 | static void | 3977 | static 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 | */ | ||
| 5906 | static 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 | */ | ||
| 5976 | static 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 | */ |
| 5698 | static void __devexit | 5993 | static 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 | */ |
| 70 | static struct _sas_node * | 70 | static 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 | */ |
| 479 | struct _sas_port * | 478 | struct _sas_port * |
| 480 | mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle, | 479 | mpt2sas_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 | */ |
| 615 | void | 610 | void |
| 616 | mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | 611 | mpt2sas_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 | */ |
| 809 | void | 804 | void |
| 810 | mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, | 805 | mpt2sas_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 | ||
