diff options
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r-- | drivers/scsi/mpt2sas/Kconfig | 1 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2.h | 17 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h | 297 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_history.txt | 93 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_init.h | 24 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_ioc.h | 91 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_raid.h | 14 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_sas.h | 6 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_tool.h | 16 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 171 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 47 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_config.c | 52 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.c | 210 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.h | 4 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 1078 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_transport.c | 283 |
16 files changed, 1898 insertions, 506 deletions
diff --git a/drivers/scsi/mpt2sas/Kconfig b/drivers/scsi/mpt2sas/Kconfig index 70c4c2467dd8..ba8e128de238 100644 --- a/drivers/scsi/mpt2sas/Kconfig +++ b/drivers/scsi/mpt2sas/Kconfig | |||
@@ -44,6 +44,7 @@ config SCSI_MPT2SAS | |||
44 | tristate "LSI MPT Fusion SAS 2.0 Device Driver" | 44 | tristate "LSI MPT Fusion SAS 2.0 Device Driver" |
45 | depends on PCI && SCSI | 45 | depends on PCI && SCSI |
46 | select SCSI_SAS_ATTRS | 46 | select SCSI_SAS_ATTRS |
47 | select RAID_ATTRS | ||
47 | ---help--- | 48 | ---help--- |
48 | This driver supports PCI-Express SAS 6Gb/s Host Adapters. | 49 | This driver supports PCI-Express SAS 6Gb/s Host Adapters. |
49 | 50 | ||
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h index f9f6c0839276..9958d847a88d 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.14 |
12 | * | 12 | * |
13 | * Version History | 13 | * Version History |
14 | * --------------- | 14 | * --------------- |
@@ -52,6 +52,11 @@ | |||
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. | ||
56 | * 10-28-09 02.00.14 Bumped MPI2_HEADER_VERSION_UNIT. | ||
57 | * Added MSI-x index mask and shift for Reply Post Host | ||
58 | * Index register. | ||
59 | * Added function code for Host Based Discovery Action. | ||
55 | * -------------------------------------------------------------------------- | 60 | * -------------------------------------------------------------------------- |
56 | */ | 61 | */ |
57 | 62 | ||
@@ -77,7 +82,7 @@ | |||
77 | #define MPI2_VERSION_02_00 (0x0200) | 82 | #define MPI2_VERSION_02_00 (0x0200) |
78 | 83 | ||
79 | /* versioning for this MPI header set */ | 84 | /* versioning for this MPI header set */ |
80 | #define MPI2_HEADER_VERSION_UNIT (0x0C) | 85 | #define MPI2_HEADER_VERSION_UNIT (0x0E) |
81 | #define MPI2_HEADER_VERSION_DEV (0x00) | 86 | #define MPI2_HEADER_VERSION_DEV (0x00) |
82 | #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) | 87 | #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) |
83 | #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) | 88 | #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) |
@@ -231,9 +236,12 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS | |||
231 | #define MPI2_REPLY_FREE_HOST_INDEX_OFFSET (0x00000048) | 236 | #define MPI2_REPLY_FREE_HOST_INDEX_OFFSET (0x00000048) |
232 | 237 | ||
233 | /* | 238 | /* |
234 | * Offset for the Reply Descriptor Post Queue | 239 | * Defines for the Reply Descriptor Post Queue |
235 | */ | 240 | */ |
236 | #define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x0000006C) | 241 | #define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x0000006C) |
242 | #define MPI2_REPLY_POST_HOST_INDEX_MASK (0x00FFFFFF) | ||
243 | #define MPI2_RPHI_MSIX_INDEX_MASK (0xFF000000) | ||
244 | #define MPI2_RPHI_MSIX_INDEX_SHIFT (24) | ||
237 | 245 | ||
238 | /* | 246 | /* |
239 | * Defines for the HCBSize and address | 247 | * Defines for the HCBSize and address |
@@ -496,12 +504,13 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION | |||
496 | #define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) /* Target Command Buffer Post Base */ | 504 | #define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) /* Target Command Buffer Post Base */ |
497 | #define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) /* Target Command Buffer Post List */ | 505 | #define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) /* Target Command Buffer Post List */ |
498 | #define MPI2_FUNCTION_RAID_ACCELERATOR (0x2C) /* RAID Accelerator*/ | 506 | #define MPI2_FUNCTION_RAID_ACCELERATOR (0x2C) /* RAID Accelerator*/ |
507 | /* Host Based Discovery Action */ | ||
508 | #define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION (0x2F) | ||
499 | 509 | ||
500 | 510 | ||
501 | 511 | ||
502 | /* Doorbell functions */ | 512 | /* Doorbell functions */ |
503 | #define MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET (0x40) | 513 | #define MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET (0x40) |
504 | /* #define MPI2_FUNCTION_IO_UNIT_RESET (0x41) */ | ||
505 | #define MPI2_FUNCTION_HANDSHAKE (0x42) | 514 | #define MPI2_FUNCTION_HANDSHAKE (0x42) |
506 | 515 | ||
507 | 516 | ||
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h index ab47c4679640..cf0ac9f40c97 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.13 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -100,6 +100,15 @@ | |||
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. | ||
110 | * 10-28-09 02.00.13 Added MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY. | ||
111 | * Added SAS PHY Page 4 structure and defines. | ||
103 | * -------------------------------------------------------------------------- | 112 | * -------------------------------------------------------------------------- |
104 | */ | 113 | */ |
105 | 114 | ||
@@ -182,6 +191,7 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION | |||
182 | #define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG (0x16) | 191 | #define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG (0x16) |
183 | #define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING (0x17) | 192 | #define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING (0x17) |
184 | #define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT (0x18) | 193 | #define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT (0x18) |
194 | #define MPI2_CONFIG_EXTPAGETYPE_ETHERNET (0x19) | ||
185 | 195 | ||
186 | 196 | ||
187 | /***************************************************************************** | 197 | /***************************************************************************** |
@@ -268,6 +278,14 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION | |||
268 | #define MPI2_DPM_PGAD_START_ENTRY_MASK (0x0000FFFF) | 278 | #define MPI2_DPM_PGAD_START_ENTRY_MASK (0x0000FFFF) |
269 | 279 | ||
270 | 280 | ||
281 | /* Ethernet PageAddress format */ | ||
282 | #define MPI2_ETHERNET_PGAD_FORM_MASK (0xF0000000) | ||
283 | #define MPI2_ETHERNET_PGAD_FORM_IF_NUM (0x00000000) | ||
284 | |||
285 | #define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK (0x000000FF) | ||
286 | |||
287 | |||
288 | |||
271 | /**************************************************************************** | 289 | /**************************************************************************** |
272 | * Configuration messages | 290 | * Configuration messages |
273 | ****************************************************************************/ | 291 | ****************************************************************************/ |
@@ -349,6 +367,15 @@ typedef struct _MPI2_CONFIG_REPLY | |||
349 | #define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064) | 367 | #define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064) |
350 | #define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065) | 368 | #define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065) |
351 | 369 | ||
370 | #define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080) | ||
371 | #define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081) | ||
372 | #define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082) | ||
373 | #define MPI2_MFGPAGE_DEVID_SAS2208_4 (0x0083) | ||
374 | #define MPI2_MFGPAGE_DEVID_SAS2208_5 (0x0084) | ||
375 | #define MPI2_MFGPAGE_DEVID_SAS2208_6 (0x0085) | ||
376 | #define MPI2_MFGPAGE_DEVID_SAS2208_7 (0x0086) | ||
377 | #define MPI2_MFGPAGE_DEVID_SAS2208_8 (0x0087) | ||
378 | |||
352 | 379 | ||
353 | /* Manufacturing Page 0 */ | 380 | /* Manufacturing Page 0 */ |
354 | 381 | ||
@@ -687,6 +714,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1 | |||
687 | #define MPI2_IOUNITPAGE1_PAGEVERSION (0x04) | 714 | #define MPI2_IOUNITPAGE1_PAGEVERSION (0x04) |
688 | 715 | ||
689 | /* IO Unit Page 1 Flags defines */ | 716 | /* IO Unit Page 1 Flags defines */ |
717 | #define MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY (0x00000800) | ||
690 | #define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE (0x00000600) | 718 | #define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE (0x00000600) |
691 | #define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE (0x00000000) | 719 | #define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE (0x00000000) |
692 | #define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE (0x00000200) | 720 | #define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE (0x00000200) |
@@ -787,6 +815,56 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_6 { | |||
787 | #define MPI2_IOUNITPAGE6_FLAGS_ENABLE_RAID_ACCELERATOR (0x0001) | 815 | #define MPI2_IOUNITPAGE6_FLAGS_ENABLE_RAID_ACCELERATOR (0x0001) |
788 | 816 | ||
789 | 817 | ||
818 | /* IO Unit Page 7 */ | ||
819 | |||
820 | typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 { | ||
821 | MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */ | ||
822 | U16 Reserved1; /* 0x04 */ | ||
823 | U8 PCIeWidth; /* 0x06 */ | ||
824 | U8 PCIeSpeed; /* 0x07 */ | ||
825 | U32 ProcessorState; /* 0x08 */ | ||
826 | U32 Reserved2; /* 0x0C */ | ||
827 | U16 IOCTemperature; /* 0x10 */ | ||
828 | U8 IOCTemperatureUnits; /* 0x12 */ | ||
829 | U8 IOCSpeed; /* 0x13 */ | ||
830 | U32 Reserved3; /* 0x14 */ | ||
831 | } MPI2_CONFIG_PAGE_IO_UNIT_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_7, | ||
832 | Mpi2IOUnitPage7_t, MPI2_POINTER pMpi2IOUnitPage7_t; | ||
833 | |||
834 | #define MPI2_IOUNITPAGE7_PAGEVERSION (0x00) | ||
835 | |||
836 | /* defines for IO Unit Page 7 PCIeWidth field */ | ||
837 | #define MPI2_IOUNITPAGE7_PCIE_WIDTH_X1 (0x01) | ||
838 | #define MPI2_IOUNITPAGE7_PCIE_WIDTH_X2 (0x02) | ||
839 | #define MPI2_IOUNITPAGE7_PCIE_WIDTH_X4 (0x04) | ||
840 | #define MPI2_IOUNITPAGE7_PCIE_WIDTH_X8 (0x08) | ||
841 | |||
842 | /* defines for IO Unit Page 7 PCIeSpeed field */ | ||
843 | #define MPI2_IOUNITPAGE7_PCIE_SPEED_2_5_GBPS (0x00) | ||
844 | #define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS (0x01) | ||
845 | #define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS (0x02) | ||
846 | |||
847 | /* defines for IO Unit Page 7 ProcessorState field */ | ||
848 | #define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND (0x0000000F) | ||
849 | #define MPI2_IOUNITPAGE7_PSTATE_SHIFT_SECOND (0) | ||
850 | |||
851 | #define MPI2_IOUNITPAGE7_PSTATE_NOT_PRESENT (0x00) | ||
852 | #define MPI2_IOUNITPAGE7_PSTATE_DISABLED (0x01) | ||
853 | #define MPI2_IOUNITPAGE7_PSTATE_ENABLED (0x02) | ||
854 | |||
855 | /* defines for IO Unit Page 7 IOCTemperatureUnits field */ | ||
856 | #define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT (0x00) | ||
857 | #define MPI2_IOUNITPAGE7_IOC_TEMP_FAHRENHEIT (0x01) | ||
858 | #define MPI2_IOUNITPAGE7_IOC_TEMP_CELSIUS (0x02) | ||
859 | |||
860 | /* defines for IO Unit Page 7 IOCSpeed field */ | ||
861 | #define MPI2_IOUNITPAGE7_IOC_SPEED_FULL (0x01) | ||
862 | #define MPI2_IOUNITPAGE7_IOC_SPEED_HALF (0x02) | ||
863 | #define MPI2_IOUNITPAGE7_IOC_SPEED_QUARTER (0x04) | ||
864 | #define MPI2_IOUNITPAGE7_IOC_SPEED_EIGHTH (0x08) | ||
865 | |||
866 | |||
867 | |||
790 | /**************************************************************************** | 868 | /**************************************************************************** |
791 | * IOC Config Pages | 869 | * IOC Config Pages |
792 | ****************************************************************************/ | 870 | ****************************************************************************/ |
@@ -1470,6 +1548,12 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 | |||
1470 | 1548 | ||
1471 | /* values for PhyInfo fields */ | 1549 | /* values for PhyInfo fields */ |
1472 | #define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000) | 1550 | #define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000) |
1551 | |||
1552 | #define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK (0x18000000) | ||
1553 | #define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE (0x00000000) | ||
1554 | #define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL (0x08000000) | ||
1555 | #define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER (0x10000000) | ||
1556 | |||
1473 | #define MPI2_SAS_PHYINFO_CHANGED_REQ_INSIDE_ZPSDS (0x04000000) | 1557 | #define MPI2_SAS_PHYINFO_CHANGED_REQ_INSIDE_ZPSDS (0x04000000) |
1474 | #define MPI2_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT (0x02000000) | 1558 | #define MPI2_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT (0x02000000) |
1475 | #define MPI2_SAS_PHYINFO_REQ_INSIDE_ZPSDS (0x01000000) | 1559 | #define MPI2_SAS_PHYINFO_REQ_INSIDE_ZPSDS (0x01000000) |
@@ -1682,11 +1766,11 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1 | |||
1682 | /* values for SAS IO Unit Page 1 PortFlags */ | 1766 | /* values for SAS IO Unit Page 1 PortFlags */ |
1683 | #define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01) | 1767 | #define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01) |
1684 | 1768 | ||
1685 | /* values for SAS IO Unit Page 2 PhyFlags */ | 1769 | /* values for SAS IO Unit Page 1 PhyFlags */ |
1686 | #define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE (0x10) | 1770 | #define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE (0x10) |
1687 | #define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE (0x08) | 1771 | #define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE (0x08) |
1688 | 1772 | ||
1689 | /* values for SAS IO Unit Page 0 MaxMinLinkRate */ | 1773 | /* values for SAS IO Unit Page 1 MaxMinLinkRate */ |
1690 | #define MPI2_SASIOUNIT1_MAX_RATE_MASK (0xF0) | 1774 | #define MPI2_SASIOUNIT1_MAX_RATE_MASK (0xF0) |
1691 | #define MPI2_SASIOUNIT1_MAX_RATE_1_5 (0x80) | 1775 | #define MPI2_SASIOUNIT1_MAX_RATE_1_5 (0x80) |
1692 | #define MPI2_SASIOUNIT1_MAX_RATE_3_0 (0x90) | 1776 | #define MPI2_SASIOUNIT1_MAX_RATE_3_0 (0x90) |
@@ -1745,6 +1829,74 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_4 | |||
1745 | #define MPI2_SASIOUNIT4_PHY_SPINUP_GROUP_MASK (0x03) | 1829 | #define MPI2_SASIOUNIT4_PHY_SPINUP_GROUP_MASK (0x03) |
1746 | 1830 | ||
1747 | 1831 | ||
1832 | /* SAS IO Unit Page 5 */ | ||
1833 | |||
1834 | typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS { | ||
1835 | U8 ControlFlags; /* 0x00 */ | ||
1836 | U8 Reserved1; /* 0x01 */ | ||
1837 | U16 InactivityTimerExponent; /* 0x02 */ | ||
1838 | U8 SATAPartialTimeout; /* 0x04 */ | ||
1839 | U8 Reserved2; /* 0x05 */ | ||
1840 | U8 SATASlumberTimeout; /* 0x06 */ | ||
1841 | U8 Reserved3; /* 0x07 */ | ||
1842 | U8 SASPartialTimeout; /* 0x08 */ | ||
1843 | U8 Reserved4; /* 0x09 */ | ||
1844 | U8 SASSlumberTimeout; /* 0x0A */ | ||
1845 | U8 Reserved5; /* 0x0B */ | ||
1846 | } MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS, | ||
1847 | MPI2_POINTER PTR_MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS, | ||
1848 | Mpi2SasIOUnit5PhyPmSettings_t, MPI2_POINTER pMpi2SasIOUnit5PhyPmSettings_t; | ||
1849 | |||
1850 | /* defines for ControlFlags field */ | ||
1851 | #define MPI2_SASIOUNIT5_CONTROL_SAS_SLUMBER_ENABLE (0x08) | ||
1852 | #define MPI2_SASIOUNIT5_CONTROL_SAS_PARTIAL_ENABLE (0x04) | ||
1853 | #define MPI2_SASIOUNIT5_CONTROL_SATA_SLUMBER_ENABLE (0x02) | ||
1854 | #define MPI2_SASIOUNIT5_CONTROL_SATA_PARTIAL_ENABLE (0x01) | ||
1855 | |||
1856 | /* defines for InactivityTimerExponent field */ | ||
1857 | #define MPI2_SASIOUNIT5_ITE_MASK_SAS_SLUMBER (0x7000) | ||
1858 | #define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_SLUMBER (12) | ||
1859 | #define MPI2_SASIOUNIT5_ITE_MASK_SAS_PARTIAL (0x0700) | ||
1860 | #define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_PARTIAL (8) | ||
1861 | #define MPI2_SASIOUNIT5_ITE_MASK_SATA_SLUMBER (0x0070) | ||
1862 | #define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_SLUMBER (4) | ||
1863 | #define MPI2_SASIOUNIT5_ITE_MASK_SATA_PARTIAL (0x0007) | ||
1864 | #define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_PARTIAL (0) | ||
1865 | |||
1866 | #define MPI2_SASIOUNIT5_ITE_TEN_SECONDS (7) | ||
1867 | #define MPI2_SASIOUNIT5_ITE_ONE_SECOND (6) | ||
1868 | #define MPI2_SASIOUNIT5_ITE_HUNDRED_MILLISECONDS (5) | ||
1869 | #define MPI2_SASIOUNIT5_ITE_TEN_MILLISECONDS (4) | ||
1870 | #define MPI2_SASIOUNIT5_ITE_ONE_MILLISECOND (3) | ||
1871 | #define MPI2_SASIOUNIT5_ITE_HUNDRED_MICROSECONDS (2) | ||
1872 | #define MPI2_SASIOUNIT5_ITE_TEN_MICROSECONDS (1) | ||
1873 | #define MPI2_SASIOUNIT5_ITE_ONE_MICROSECOND (0) | ||
1874 | |||
1875 | /* | ||
1876 | * Host code (drivers, BIOS, utilities, etc.) should leave this define set to | ||
1877 | * one and check Header.ExtPageLength or NumPhys at runtime. | ||
1878 | */ | ||
1879 | #ifndef MPI2_SAS_IOUNIT5_PHY_MAX | ||
1880 | #define MPI2_SAS_IOUNIT5_PHY_MAX (1) | ||
1881 | #endif | ||
1882 | |||
1883 | typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_5 { | ||
1884 | MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */ | ||
1885 | U8 NumPhys; /* 0x08 */ | ||
1886 | U8 Reserved1; /* 0x09 */ | ||
1887 | U16 Reserved2; /* 0x0A */ | ||
1888 | U32 Reserved3; /* 0x0C */ | ||
1889 | MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS SASPhyPowerManagementSettings | ||
1890 | [MPI2_SAS_IOUNIT5_PHY_MAX]; /* 0x10 */ | ||
1891 | } MPI2_CONFIG_PAGE_SASIOUNIT_5, | ||
1892 | MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_5, | ||
1893 | Mpi2SasIOUnitPage5_t, MPI2_POINTER pMpi2SasIOUnitPage5_t; | ||
1894 | |||
1895 | #define MPI2_SASIOUNITPAGE5_PAGEVERSION (0x00) | ||
1896 | |||
1897 | |||
1898 | |||
1899 | |||
1748 | /**************************************************************************** | 1900 | /**************************************************************************** |
1749 | * SAS Expander Config Pages | 1901 | * SAS Expander Config Pages |
1750 | ****************************************************************************/ | 1902 | ****************************************************************************/ |
@@ -1927,6 +2079,8 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0 | |||
1927 | /* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */ | 2079 | /* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */ |
1928 | 2080 | ||
1929 | /* values for SAS Device Page 0 Flags field */ | 2081 | /* values for SAS Device Page 0 Flags field */ |
2082 | #define MPI2_SAS_DEVICE0_FLAGS_SLUMBER_PM_CAPABLE (0x1000) | ||
2083 | #define MPI2_SAS_DEVICE0_FLAGS_PARTIAL_PM_CAPABLE (0x0800) | ||
1930 | #define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400) | 2084 | #define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400) |
1931 | #define MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200) | 2085 | #define MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200) |
1932 | #define MPI2_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100) | 2086 | #define MPI2_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100) |
@@ -2140,6 +2294,26 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_3 { | |||
2140 | #define MPI2_SASPHY3_PAGEVERSION (0x00) | 2294 | #define MPI2_SASPHY3_PAGEVERSION (0x00) |
2141 | 2295 | ||
2142 | 2296 | ||
2297 | /* SAS PHY Page 4 */ | ||
2298 | |||
2299 | typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_4 { | ||
2300 | MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */ | ||
2301 | U16 Reserved1; /* 0x08 */ | ||
2302 | U8 Reserved2; /* 0x0A */ | ||
2303 | U8 Flags; /* 0x0B */ | ||
2304 | U8 InitialFrame[28]; /* 0x0C */ | ||
2305 | } MPI2_CONFIG_PAGE_SAS_PHY_4, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_4, | ||
2306 | Mpi2SasPhyPage4_t, MPI2_POINTER pMpi2SasPhyPage4_t; | ||
2307 | |||
2308 | #define MPI2_SASPHY4_PAGEVERSION (0x00) | ||
2309 | |||
2310 | /* values for the Flags field */ | ||
2311 | #define MPI2_SASPHY4_FLAGS_FRAME_VALID (0x02) | ||
2312 | #define MPI2_SASPHY4_FLAGS_SATA_FRAME (0x01) | ||
2313 | |||
2314 | |||
2315 | |||
2316 | |||
2143 | /**************************************************************************** | 2317 | /**************************************************************************** |
2144 | * SAS Port Config Pages | 2318 | * SAS Port Config Pages |
2145 | ****************************************************************************/ | 2319 | ****************************************************************************/ |
@@ -2343,5 +2517,122 @@ typedef struct _MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 | |||
2343 | #define MPI2_DRVMAP0_MAPINFO_MISSING_MASK (0x000F) | 2517 | #define MPI2_DRVMAP0_MAPINFO_MISSING_MASK (0x000F) |
2344 | 2518 | ||
2345 | 2519 | ||
2520 | /**************************************************************************** | ||
2521 | * Ethernet Config Pages | ||
2522 | ****************************************************************************/ | ||
2523 | |||
2524 | /* Ethernet Page 0 */ | ||
2525 | |||
2526 | /* IP address (union of IPv4 and IPv6) */ | ||
2527 | typedef union _MPI2_ETHERNET_IP_ADDR { | ||
2528 | U32 IPv4Addr; | ||
2529 | U32 IPv6Addr[4]; | ||
2530 | } MPI2_ETHERNET_IP_ADDR, MPI2_POINTER PTR_MPI2_ETHERNET_IP_ADDR, | ||
2531 | Mpi2EthernetIpAddr_t, MPI2_POINTER pMpi2EthernetIpAddr_t; | ||
2532 | |||
2533 | #define MPI2_ETHERNET_HOST_NAME_LENGTH (32) | ||
2534 | |||
2535 | typedef struct _MPI2_CONFIG_PAGE_ETHERNET_0 { | ||
2536 | MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */ | ||
2537 | U8 NumInterfaces; /* 0x08 */ | ||
2538 | U8 Reserved0; /* 0x09 */ | ||
2539 | U16 Reserved1; /* 0x0A */ | ||
2540 | U32 Status; /* 0x0C */ | ||
2541 | U8 MediaState; /* 0x10 */ | ||
2542 | U8 Reserved2; /* 0x11 */ | ||
2543 | U16 Reserved3; /* 0x12 */ | ||
2544 | U8 MacAddress[6]; /* 0x14 */ | ||
2545 | U8 Reserved4; /* 0x1A */ | ||
2546 | U8 Reserved5; /* 0x1B */ | ||
2547 | MPI2_ETHERNET_IP_ADDR IpAddress; /* 0x1C */ | ||
2548 | MPI2_ETHERNET_IP_ADDR SubnetMask; /* 0x2C */ | ||
2549 | MPI2_ETHERNET_IP_ADDR GatewayIpAddress; /* 0x3C */ | ||
2550 | MPI2_ETHERNET_IP_ADDR DNS1IpAddress; /* 0x4C */ | ||
2551 | MPI2_ETHERNET_IP_ADDR DNS2IpAddress; /* 0x5C */ | ||
2552 | MPI2_ETHERNET_IP_ADDR DhcpIpAddress; /* 0x6C */ | ||
2553 | U8 HostName | ||
2554 | [MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */ | ||
2555 | } MPI2_CONFIG_PAGE_ETHERNET_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_0, | ||
2556 | Mpi2EthernetPage0_t, MPI2_POINTER pMpi2EthernetPage0_t; | ||
2557 | |||
2558 | #define MPI2_ETHERNETPAGE0_PAGEVERSION (0x00) | ||
2559 | |||
2560 | /* values for Ethernet Page 0 Status field */ | ||
2561 | #define MPI2_ETHPG0_STATUS_IPV6_CAPABLE (0x80000000) | ||
2562 | #define MPI2_ETHPG0_STATUS_IPV4_CAPABLE (0x40000000) | ||
2563 | #define MPI2_ETHPG0_STATUS_CONSOLE_CONNECTED (0x20000000) | ||
2564 | #define MPI2_ETHPG0_STATUS_DEFAULT_IF (0x00000100) | ||
2565 | #define MPI2_ETHPG0_STATUS_FW_DWNLD_ENABLED (0x00000080) | ||
2566 | #define MPI2_ETHPG0_STATUS_TELNET_ENABLED (0x00000040) | ||
2567 | #define MPI2_ETHPG0_STATUS_SSH2_ENABLED (0x00000020) | ||
2568 | #define MPI2_ETHPG0_STATUS_DHCP_CLIENT_ENABLED (0x00000010) | ||
2569 | #define MPI2_ETHPG0_STATUS_IPV6_ENABLED (0x00000008) | ||
2570 | #define MPI2_ETHPG0_STATUS_IPV4_ENABLED (0x00000004) | ||
2571 | #define MPI2_ETHPG0_STATUS_IPV6_ADDRESSES (0x00000002) | ||
2572 | #define MPI2_ETHPG0_STATUS_ETH_IF_ENABLED (0x00000001) | ||
2573 | |||
2574 | /* values for Ethernet Page 0 MediaState field */ | ||
2575 | #define MPI2_ETHPG0_MS_DUPLEX_MASK (0x80) | ||
2576 | #define MPI2_ETHPG0_MS_HALF_DUPLEX (0x00) | ||
2577 | #define MPI2_ETHPG0_MS_FULL_DUPLEX (0x80) | ||
2578 | |||
2579 | #define MPI2_ETHPG0_MS_CONNECT_SPEED_MASK (0x07) | ||
2580 | #define MPI2_ETHPG0_MS_NOT_CONNECTED (0x00) | ||
2581 | #define MPI2_ETHPG0_MS_10MBIT (0x01) | ||
2582 | #define MPI2_ETHPG0_MS_100MBIT (0x02) | ||
2583 | #define MPI2_ETHPG0_MS_1GBIT (0x03) | ||
2584 | |||
2585 | |||
2586 | /* Ethernet Page 1 */ | ||
2587 | |||
2588 | typedef struct _MPI2_CONFIG_PAGE_ETHERNET_1 { | ||
2589 | MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */ | ||
2590 | U32 Reserved0; /* 0x08 */ | ||
2591 | U32 Flags; /* 0x0C */ | ||
2592 | U8 MediaState; /* 0x10 */ | ||
2593 | U8 Reserved1; /* 0x11 */ | ||
2594 | U16 Reserved2; /* 0x12 */ | ||
2595 | U8 MacAddress[6]; /* 0x14 */ | ||
2596 | U8 Reserved3; /* 0x1A */ | ||
2597 | U8 Reserved4; /* 0x1B */ | ||
2598 | MPI2_ETHERNET_IP_ADDR StaticIpAddress; /* 0x1C */ | ||
2599 | MPI2_ETHERNET_IP_ADDR StaticSubnetMask; /* 0x2C */ | ||
2600 | MPI2_ETHERNET_IP_ADDR StaticGatewayIpAddress; /* 0x3C */ | ||
2601 | MPI2_ETHERNET_IP_ADDR StaticDNS1IpAddress; /* 0x4C */ | ||
2602 | MPI2_ETHERNET_IP_ADDR StaticDNS2IpAddress; /* 0x5C */ | ||
2603 | U32 Reserved5; /* 0x6C */ | ||
2604 | U32 Reserved6; /* 0x70 */ | ||
2605 | U32 Reserved7; /* 0x74 */ | ||
2606 | U32 Reserved8; /* 0x78 */ | ||
2607 | U8 HostName | ||
2608 | [MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */ | ||
2609 | } MPI2_CONFIG_PAGE_ETHERNET_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_1, | ||
2610 | Mpi2EthernetPage1_t, MPI2_POINTER pMpi2EthernetPage1_t; | ||
2611 | |||
2612 | #define MPI2_ETHERNETPAGE1_PAGEVERSION (0x00) | ||
2613 | |||
2614 | /* values for Ethernet Page 1 Flags field */ | ||
2615 | #define MPI2_ETHPG1_FLAG_SET_DEFAULT_IF (0x00000100) | ||
2616 | #define MPI2_ETHPG1_FLAG_ENABLE_FW_DOWNLOAD (0x00000080) | ||
2617 | #define MPI2_ETHPG1_FLAG_ENABLE_TELNET (0x00000040) | ||
2618 | #define MPI2_ETHPG1_FLAG_ENABLE_SSH2 (0x00000020) | ||
2619 | #define MPI2_ETHPG1_FLAG_ENABLE_DHCP_CLIENT (0x00000010) | ||
2620 | #define MPI2_ETHPG1_FLAG_ENABLE_IPV6 (0x00000008) | ||
2621 | #define MPI2_ETHPG1_FLAG_ENABLE_IPV4 (0x00000004) | ||
2622 | #define MPI2_ETHPG1_FLAG_USE_IPV6_ADDRESSES (0x00000002) | ||
2623 | #define MPI2_ETHPG1_FLAG_ENABLE_ETH_IF (0x00000001) | ||
2624 | |||
2625 | /* values for Ethernet Page 1 MediaState field */ | ||
2626 | #define MPI2_ETHPG1_MS_DUPLEX_MASK (0x80) | ||
2627 | #define MPI2_ETHPG1_MS_HALF_DUPLEX (0x00) | ||
2628 | #define MPI2_ETHPG1_MS_FULL_DUPLEX (0x80) | ||
2629 | |||
2630 | #define MPI2_ETHPG1_MS_DATA_RATE_MASK (0x07) | ||
2631 | #define MPI2_ETHPG1_MS_DATA_RATE_AUTO (0x00) | ||
2632 | #define MPI2_ETHPG1_MS_DATA_RATE_10MBIT (0x01) | ||
2633 | #define MPI2_ETHPG1_MS_DATA_RATE_100MBIT (0x02) | ||
2634 | #define MPI2_ETHPG1_MS_DATA_RATE_1GBIT (0x03) | ||
2635 | |||
2636 | |||
2346 | #endif | 2637 | #endif |
2347 | 2638 | ||
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_history.txt b/drivers/scsi/mpt2sas/mpi/mpi2_history.txt index 65fcaa31cb30..c4adf76b49d9 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_history.txt +++ b/drivers/scsi/mpt2sas/mpi/mpi2_history.txt | |||
@@ -5,23 +5,24 @@ | |||
5 | Copyright (c) 2000-2009 LSI Corporation. | 5 | Copyright (c) 2000-2009 LSI Corporation. |
6 | 6 | ||
7 | --------------------------------------- | 7 | --------------------------------------- |
8 | Header Set Release Version: 02.00.12 | 8 | Header Set Release Version: 02.00.14 |
9 | Header Set Release Date: 05-06-09 | 9 | Header Set Release Date: 10-28-09 |
10 | --------------------------------------- | 10 | --------------------------------------- |
11 | 11 | ||
12 | Filename Current version Prior version | 12 | Filename Current version Prior version |
13 | ---------- --------------- ------------- | 13 | ---------- --------------- ------------- |
14 | mpi2.h 02.00.12 02.00.11 | 14 | mpi2.h 02.00.14 02.00.13 |
15 | mpi2_cnfg.h 02.00.11 02.00.10 | 15 | mpi2_cnfg.h 02.00.13 02.00.12 |
16 | mpi2_init.h 02.00.07 02.00.06 | 16 | mpi2_init.h 02.00.08 02.00.07 |
17 | mpi2_ioc.h 02.00.11 02.00.10 | 17 | mpi2_ioc.h 02.00.13 02.00.12 |
18 | mpi2_raid.h 02.00.03 02.00.03 | 18 | mpi2_raid.h 02.00.04 02.00.04 |
19 | mpi2_sas.h 02.00.02 02.00.02 | 19 | mpi2_sas.h 02.00.03 02.00.02 |
20 | mpi2_targ.h 02.00.03 02.00.03 | 20 | mpi2_targ.h 02.00.03 02.00.03 |
21 | mpi2_tool.h 02.00.03 02.00.02 | 21 | mpi2_tool.h 02.00.04 02.00.04 |
22 | mpi2_type.h 02.00.00 02.00.00 | 22 | mpi2_type.h 02.00.00 02.00.00 |
23 | mpi2_ra.h 02.00.00 | 23 | mpi2_ra.h 02.00.00 02.00.00 |
24 | mpi2_history.txt 02.00.11 02.00.12 | 24 | mpi2_hbd.h 02.00.00 |
25 | mpi2_history.txt 02.00.14 02.00.13 | ||
25 | 26 | ||
26 | 27 | ||
27 | * Date Version Description | 28 | * Date Version Description |
@@ -65,6 +66,11 @@ mpi2.h | |||
65 | * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those | 66 | * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those |
66 | * bytes reserved. | 67 | * bytes reserved. |
67 | * Added RAID Accelerator functionality. | 68 | * Added RAID Accelerator functionality. |
69 | * 07-30-09 02.00.13 Bumped MPI2_HEADER_VERSION_UNIT. | ||
70 | * 10-28-09 02.00.14 Bumped MPI2_HEADER_VERSION_UNIT. | ||
71 | * Added MSI-x index mask and shift for Reply Post Host | ||
72 | * Index register. | ||
73 | * Added function code for Host Based Discovery Action. | ||
68 | * -------------------------------------------------------------------------- | 74 | * -------------------------------------------------------------------------- |
69 | 75 | ||
70 | mpi2_cnfg.h | 76 | mpi2_cnfg.h |
@@ -155,6 +161,15 @@ mpi2_cnfg.h | |||
155 | * Added expander reduced functionality data to SAS | 161 | * Added expander reduced functionality data to SAS |
156 | * Expander Page 0. | 162 | * Expander Page 0. |
157 | * Added SAS PHY Page 2 and SAS PHY Page 3. | 163 | * Added SAS PHY Page 2 and SAS PHY Page 3. |
164 | * 07-30-09 02.00.12 Added IO Unit Page 7. | ||
165 | * Added new device ids. | ||
166 | * Added SAS IO Unit Page 5. | ||
167 | * Added partial and slumber power management capable flags | ||
168 | * to SAS Device Page 0 Flags field. | ||
169 | * Added PhyInfo defines for power condition. | ||
170 | * Added Ethernet configuration pages. | ||
171 | * 10-28-09 02.00.13 Added MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY. | ||
172 | * Added SAS PHY Page 4 structure and defines. | ||
158 | * -------------------------------------------------------------------------- | 173 | * -------------------------------------------------------------------------- |
159 | 174 | ||
160 | mpi2_init.h | 175 | mpi2_init.h |
@@ -172,6 +187,10 @@ mpi2_init.h | |||
172 | * Query Asynchronous Event. | 187 | * Query Asynchronous Event. |
173 | * Defined two new bits in the SlotStatus field of the SCSI | 188 | * Defined two new bits in the SlotStatus field of the SCSI |
174 | * Enclosure Processor Request and Reply. | 189 | * Enclosure Processor Request and Reply. |
190 | * 10-28-09 02.00.08 Added defines for decoding the ResponseInfo bytes for | ||
191 | * both SCSI IO Error Reply and SCSI Task Management Reply. | ||
192 | * Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY. | ||
193 | * Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define. | ||
175 | * -------------------------------------------------------------------------- | 194 | * -------------------------------------------------------------------------- |
176 | 195 | ||
177 | mpi2_ioc.h | 196 | mpi2_ioc.h |
@@ -246,6 +265,20 @@ mpi2_ioc.h | |||
246 | * Added two new reason codes for SAS Device Status Change | 265 | * Added two new reason codes for SAS Device Status Change |
247 | * Event. | 266 | * Event. |
248 | * Added new event: SAS PHY Counter. | 267 | * Added new event: SAS PHY Counter. |
268 | * 07-30-09 02.00.12 Added GPIO Interrupt event define and structure. | ||
269 | * Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define. | ||
270 | * Added new product id family for 2208. | ||
271 | * 10-28-09 02.00.13 Added HostMSIxVectors field to MPI2_IOC_INIT_REQUEST. | ||
272 | * Added MaxMSIxVectors field to MPI2_IOC_FACTS_REPLY. | ||
273 | * Added MinDevHandle field to MPI2_IOC_FACTS_REPLY. | ||
274 | * Added MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY. | ||
275 | * Added MPI2_EVENT_HOST_BASED_DISCOVERY_PHY define. | ||
276 | * Added MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER define. | ||
277 | * Added Host Based Discovery Phy Event data. | ||
278 | * Added defines for ProductID Product field | ||
279 | * (MPI2_FW_HEADER_PID_). | ||
280 | * Modified values for SAS ProductID Family | ||
281 | * (MPI2_FW_HEADER_PID_FAMILY_). | ||
249 | * -------------------------------------------------------------------------- | 282 | * -------------------------------------------------------------------------- |
250 | 283 | ||
251 | mpi2_raid.h | 284 | mpi2_raid.h |
@@ -256,6 +289,8 @@ mpi2_raid.h | |||
256 | * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that | 289 | * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that |
257 | * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT | 290 | * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT |
258 | * can be sized by the build environment. | 291 | * can be sized by the build environment. |
292 | * 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of | ||
293 | * VolumeCreationFlags and marked the old one as obsolete. | ||
259 | * -------------------------------------------------------------------------- | 294 | * -------------------------------------------------------------------------- |
260 | 295 | ||
261 | mpi2_sas.h | 296 | mpi2_sas.h |
@@ -264,6 +299,8 @@ mpi2_sas.h | |||
264 | * Control Request. | 299 | * Control Request. |
265 | * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control | 300 | * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control |
266 | * Request. | 301 | * Request. |
302 | * 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST | ||
303 | * to MPI2_SGE_IO_UNION since it supports chained SGLs. | ||
267 | * -------------------------------------------------------------------------- | 304 | * -------------------------------------------------------------------------- |
268 | 305 | ||
269 | mpi2_targ.h | 306 | mpi2_targ.h |
@@ -283,6 +320,10 @@ mpi2_tool.h | |||
283 | * structures and defines. | 320 | * structures and defines. |
284 | * 02-29-08 02.00.02 Modified various names to make them 32-character unique. | 321 | * 02-29-08 02.00.02 Modified various names to make them 32-character unique. |
285 | * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool. | 322 | * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool. |
323 | * 07-30-09 02.00.04 Added ExtendedType field to DiagnosticBufferPost request | ||
324 | * and reply messages. | ||
325 | * Added MPI2_DIAG_BUF_TYPE_EXTENDED. | ||
326 | * Incremented MPI2_DIAG_BUF_TYPE_COUNT. | ||
286 | * -------------------------------------------------------------------------- | 327 | * -------------------------------------------------------------------------- |
287 | 328 | ||
288 | mpi2_type.h | 329 | mpi2_type.h |
@@ -293,20 +334,26 @@ mpi2_ra.h | |||
293 | * 05-06-09 02.00.00 Initial version. | 334 | * 05-06-09 02.00.00 Initial version. |
294 | * -------------------------------------------------------------------------- | 335 | * -------------------------------------------------------------------------- |
295 | 336 | ||
337 | mpi2_hbd.h | ||
338 | * 10-28-09 02.00.00 Initial version. | ||
339 | * -------------------------------------------------------------------------- | ||
340 | |||
341 | |||
296 | mpi2_history.txt Parts list history | 342 | mpi2_history.txt Parts list history |
297 | 343 | ||
298 | Filename 02.00.12 | 344 | Filename 02.00.14 02.00.13 02.00.12 |
299 | ---------- -------- | 345 | ---------- -------- -------- -------- |
300 | mpi2.h 02.00.12 | 346 | mpi2.h 02.00.14 02.00.13 02.00.12 |
301 | mpi2_cnfg.h 02.00.11 | 347 | mpi2_cnfg.h 02.00.13 02.00.12 02.00.11 |
302 | mpi2_init.h 02.00.07 | 348 | mpi2_init.h 02.00.08 02.00.07 02.00.07 |
303 | mpi2_ioc.h 02.00.11 | 349 | mpi2_ioc.h 02.00.13 02.00.12 02.00.11 |
304 | mpi2_raid.h 02.00.03 | 350 | mpi2_raid.h 02.00.04 02.00.04 02.00.03 |
305 | mpi2_sas.h 02.00.02 | 351 | mpi2_sas.h 02.00.03 02.00.02 02.00.02 |
306 | mpi2_targ.h 02.00.03 | 352 | mpi2_targ.h 02.00.03 02.00.03 02.00.03 |
307 | mpi2_tool.h 02.00.03 | 353 | mpi2_tool.h 02.00.04 02.00.04 02.00.03 |
308 | mpi2_type.h 02.00.00 | 354 | mpi2_type.h 02.00.00 02.00.00 02.00.00 |
309 | mpi2_ra.h 02.00.00 | 355 | mpi2_ra.h 02.00.00 02.00.00 02.00.00 |
356 | mpi2_hbd.h 02.00.00 | ||
310 | 357 | ||
311 | Filename 02.00.11 02.00.10 02.00.09 02.00.08 02.00.07 02.00.06 | 358 | Filename 02.00.11 02.00.10 02.00.09 02.00.08 02.00.07 02.00.06 |
312 | ---------- -------- -------- -------- -------- -------- -------- | 359 | ---------- -------- -------- -------- -------- -------- -------- |
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h index 563e56d2e945..6541945e97c3 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_init.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI SCSI initiator mode messages and structures | 6 | * Title: MPI SCSI initiator mode messages and structures |
7 | * Creation Date: June 23, 2006 | 7 | * Creation Date: June 23, 2006 |
8 | * | 8 | * |
9 | * mpi2_init.h Version: 02.00.07 | 9 | * mpi2_init.h Version: 02.00.08 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -27,6 +27,10 @@ | |||
27 | * Query Asynchronous Event. | 27 | * Query Asynchronous Event. |
28 | * Defined two new bits in the SlotStatus field of the SCSI | 28 | * Defined two new bits in the SlotStatus field of the SCSI |
29 | * Enclosure Processor Request and Reply. | 29 | * Enclosure Processor Request and Reply. |
30 | * 10-28-09 02.00.08 Added defines for decoding the ResponseInfo bytes for | ||
31 | * both SCSI IO Error Reply and SCSI Task Management Reply. | ||
32 | * Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY. | ||
33 | * Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define. | ||
30 | * -------------------------------------------------------------------------- | 34 | * -------------------------------------------------------------------------- |
31 | */ | 35 | */ |
32 | 36 | ||
@@ -254,6 +258,11 @@ typedef struct _MPI2_SCSI_IO_REPLY | |||
254 | #define MPI2_SCSI_STATE_AUTOSENSE_FAILED (0x02) | 258 | #define MPI2_SCSI_STATE_AUTOSENSE_FAILED (0x02) |
255 | #define MPI2_SCSI_STATE_AUTOSENSE_VALID (0x01) | 259 | #define MPI2_SCSI_STATE_AUTOSENSE_VALID (0x01) |
256 | 260 | ||
261 | /* masks and shifts for the ResponseInfo field */ | ||
262 | |||
263 | #define MPI2_SCSI_RI_MASK_REASONCODE (0x000000FF) | ||
264 | #define MPI2_SCSI_RI_SHIFT_REASONCODE (0) | ||
265 | |||
257 | #define MPI2_SCSI_TASKTAG_UNKNOWN (0xFFFF) | 266 | #define MPI2_SCSI_TASKTAG_UNKNOWN (0xFFFF) |
258 | 267 | ||
259 | 268 | ||
@@ -327,6 +336,7 @@ typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY | |||
327 | U16 IOCStatus; /* 0x0E */ | 336 | U16 IOCStatus; /* 0x0E */ |
328 | U32 IOCLogInfo; /* 0x10 */ | 337 | U32 IOCLogInfo; /* 0x10 */ |
329 | U32 TerminationCount; /* 0x14 */ | 338 | U32 TerminationCount; /* 0x14 */ |
339 | U32 ResponseInfo; /* 0x18 */ | ||
330 | } MPI2_SCSI_TASK_MANAGE_REPLY, | 340 | } MPI2_SCSI_TASK_MANAGE_REPLY, |
331 | MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REPLY, | 341 | MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REPLY, |
332 | Mpi2SCSITaskManagementReply_t, MPI2_POINTER pMpi2SCSIManagementReply_t; | 342 | Mpi2SCSITaskManagementReply_t, MPI2_POINTER pMpi2SCSIManagementReply_t; |
@@ -339,8 +349,20 @@ typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY | |||
339 | #define MPI2_SCSITASKMGMT_RSP_TM_FAILED (0x05) | 349 | #define MPI2_SCSITASKMGMT_RSP_TM_FAILED (0x05) |
340 | #define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED (0x08) | 350 | #define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED (0x08) |
341 | #define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN (0x09) | 351 | #define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN (0x09) |
352 | #define MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG (0x0A) | ||
342 | #define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC (0x80) | 353 | #define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC (0x80) |
343 | 354 | ||
355 | /* masks and shifts for the ResponseInfo field */ | ||
356 | |||
357 | #define MPI2_SCSITASKMGMT_RI_MASK_REASONCODE (0x000000FF) | ||
358 | #define MPI2_SCSITASKMGMT_RI_SHIFT_REASONCODE (0) | ||
359 | #define MPI2_SCSITASKMGMT_RI_MASK_ARI2 (0x0000FF00) | ||
360 | #define MPI2_SCSITASKMGMT_RI_SHIFT_ARI2 (8) | ||
361 | #define MPI2_SCSITASKMGMT_RI_MASK_ARI1 (0x00FF0000) | ||
362 | #define MPI2_SCSITASKMGMT_RI_SHIFT_ARI1 (16) | ||
363 | #define MPI2_SCSITASKMGMT_RI_MASK_ARI0 (0xFF000000) | ||
364 | #define MPI2_SCSITASKMGMT_RI_SHIFT_ARI0 (24) | ||
365 | |||
344 | 366 | ||
345 | /**************************************************************************** | 367 | /**************************************************************************** |
346 | * SCSI Enclosure Processor messages | 368 | * SCSI Enclosure Processor messages |
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h index c294128bdeb4..754938422f6a 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.13 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -84,6 +84,20 @@ | |||
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. | ||
90 | * 10-28-09 02.00.13 Added HostMSIxVectors field to MPI2_IOC_INIT_REQUEST. | ||
91 | * Added MaxMSIxVectors field to MPI2_IOC_FACTS_REPLY. | ||
92 | * Added MinDevHandle field to MPI2_IOC_FACTS_REPLY. | ||
93 | * Added MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY. | ||
94 | * Added MPI2_EVENT_HOST_BASED_DISCOVERY_PHY define. | ||
95 | * Added MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER define. | ||
96 | * Added Host Based Discovery Phy Event data. | ||
97 | * Added defines for ProductID Product field | ||
98 | * (MPI2_FW_HEADER_PID_). | ||
99 | * Modified values for SAS ProductID Family | ||
100 | * (MPI2_FW_HEADER_PID_FAMILY_). | ||
87 | * -------------------------------------------------------------------------- | 101 | * -------------------------------------------------------------------------- |
88 | */ | 102 | */ |
89 | 103 | ||
@@ -116,8 +130,10 @@ typedef struct _MPI2_IOC_INIT_REQUEST | |||
116 | U16 MsgVersion; /* 0x0C */ | 130 | U16 MsgVersion; /* 0x0C */ |
117 | U16 HeaderVersion; /* 0x0E */ | 131 | U16 HeaderVersion; /* 0x0E */ |
118 | U32 Reserved5; /* 0x10 */ | 132 | U32 Reserved5; /* 0x10 */ |
119 | U32 Reserved6; /* 0x14 */ | 133 | U16 Reserved6; /* 0x14 */ |
120 | U16 Reserved7; /* 0x18 */ | 134 | U8 Reserved7; /* 0x16 */ |
135 | U8 HostMSIxVectors; /* 0x17 */ | ||
136 | U16 Reserved8; /* 0x18 */ | ||
121 | U16 SystemRequestFrameSize; /* 0x1A */ | 137 | U16 SystemRequestFrameSize; /* 0x1A */ |
122 | U16 ReplyDescriptorPostQueueDepth; /* 0x1C */ | 138 | U16 ReplyDescriptorPostQueueDepth; /* 0x1C */ |
123 | U16 ReplyFreeQueueDepth; /* 0x1E */ | 139 | U16 ReplyFreeQueueDepth; /* 0x1E */ |
@@ -212,7 +228,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY | |||
212 | U8 MaxChainDepth; /* 0x14 */ | 228 | U8 MaxChainDepth; /* 0x14 */ |
213 | U8 WhoInit; /* 0x15 */ | 229 | U8 WhoInit; /* 0x15 */ |
214 | U8 NumberOfPorts; /* 0x16 */ | 230 | U8 NumberOfPorts; /* 0x16 */ |
215 | U8 Reserved2; /* 0x17 */ | 231 | U8 MaxMSIxVectors; /* 0x17 */ |
216 | U16 RequestCredit; /* 0x18 */ | 232 | U16 RequestCredit; /* 0x18 */ |
217 | U16 ProductID; /* 0x1A */ | 233 | U16 ProductID; /* 0x1A */ |
218 | U32 IOCCapabilities; /* 0x1C */ | 234 | U32 IOCCapabilities; /* 0x1C */ |
@@ -230,7 +246,8 @@ typedef struct _MPI2_IOC_FACTS_REPLY | |||
230 | U8 MaxVolumes; /* 0x37 */ | 246 | U8 MaxVolumes; /* 0x37 */ |
231 | U16 MaxDevHandle; /* 0x38 */ | 247 | U16 MaxDevHandle; /* 0x38 */ |
232 | U16 MaxPersistentEntries; /* 0x3A */ | 248 | U16 MaxPersistentEntries; /* 0x3A */ |
233 | U32 Reserved4; /* 0x3C */ | 249 | U16 MinDevHandle; /* 0x3C */ |
250 | U16 Reserved4; /* 0x3E */ | ||
234 | } MPI2_IOC_FACTS_REPLY, MPI2_POINTER PTR_MPI2_IOC_FACTS_REPLY, | 251 | } MPI2_IOC_FACTS_REPLY, MPI2_POINTER PTR_MPI2_IOC_FACTS_REPLY, |
235 | Mpi2IOCFactsReply_t, MPI2_POINTER pMpi2IOCFactsReply_t; | 252 | Mpi2IOCFactsReply_t, MPI2_POINTER pMpi2IOCFactsReply_t; |
236 | 253 | ||
@@ -266,6 +283,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY | |||
266 | /* ProductID field uses MPI2_FW_HEADER_PID_ */ | 283 | /* ProductID field uses MPI2_FW_HEADER_PID_ */ |
267 | 284 | ||
268 | /* IOCCapabilities */ | 285 | /* IOCCapabilities */ |
286 | #define MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY (0x00010000) | ||
269 | #define MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX (0x00008000) | 287 | #define MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX (0x00008000) |
270 | #define MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR (0x00004000) | 288 | #define MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR (0x00004000) |
271 | #define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY (0x00002000) | 289 | #define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY (0x00002000) |
@@ -274,6 +292,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY | |||
274 | #define MPI2_IOCFACTS_CAPABILITY_MULTICAST (0x00000100) | 292 | #define MPI2_IOCFACTS_CAPABILITY_MULTICAST (0x00000100) |
275 | #define MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET (0x00000080) | 293 | #define MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET (0x00000080) |
276 | #define MPI2_IOCFACTS_CAPABILITY_EEDP (0x00000040) | 294 | #define MPI2_IOCFACTS_CAPABILITY_EEDP (0x00000040) |
295 | #define MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020) | ||
277 | #define MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010) | 296 | #define MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010) |
278 | #define MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008) | 297 | #define MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008) |
279 | #define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004) | 298 | #define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004) |
@@ -448,6 +467,8 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY | |||
448 | #define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST (0x0020) | 467 | #define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST (0x0020) |
449 | #define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021) | 468 | #define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021) |
450 | #define MPI2_EVENT_SAS_PHY_COUNTER (0x0022) | 469 | #define MPI2_EVENT_SAS_PHY_COUNTER (0x0022) |
470 | #define MPI2_EVENT_GPIO_INTERRUPT (0x0023) | ||
471 | #define MPI2_EVENT_HOST_BASED_DISCOVERY_PHY (0x0024) | ||
451 | 472 | ||
452 | 473 | ||
453 | /* Log Entry Added Event data */ | 474 | /* Log Entry Added Event data */ |
@@ -469,6 +490,16 @@ typedef struct _MPI2_EVENT_DATA_LOG_ENTRY_ADDED | |||
469 | MPI2_POINTER PTR_MPI2_EVENT_DATA_LOG_ENTRY_ADDED, | 490 | MPI2_POINTER PTR_MPI2_EVENT_DATA_LOG_ENTRY_ADDED, |
470 | Mpi2EventDataLogEntryAdded_t, MPI2_POINTER pMpi2EventDataLogEntryAdded_t; | 491 | Mpi2EventDataLogEntryAdded_t, MPI2_POINTER pMpi2EventDataLogEntryAdded_t; |
471 | 492 | ||
493 | /* GPIO Interrupt Event data */ | ||
494 | |||
495 | typedef struct _MPI2_EVENT_DATA_GPIO_INTERRUPT { | ||
496 | U8 GPIONum; /* 0x00 */ | ||
497 | U8 Reserved1; /* 0x01 */ | ||
498 | U16 Reserved2; /* 0x02 */ | ||
499 | } MPI2_EVENT_DATA_GPIO_INTERRUPT, | ||
500 | MPI2_POINTER PTR_MPI2_EVENT_DATA_GPIO_INTERRUPT, | ||
501 | Mpi2EventDataGpioInterrupt_t, MPI2_POINTER pMpi2EventDataGpioInterrupt_t; | ||
502 | |||
472 | /* Hard Reset Received Event data */ | 503 | /* Hard Reset Received Event data */ |
473 | 504 | ||
474 | typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED | 505 | typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED |
@@ -778,6 +809,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST | |||
778 | MPI2_POINTER pMpi2EventDataSasTopologyChangeList_t; | 809 | MPI2_POINTER pMpi2EventDataSasTopologyChangeList_t; |
779 | 810 | ||
780 | /* values for the ExpStatus field */ | 811 | /* values for the ExpStatus field */ |
812 | #define MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER (0x00) | ||
781 | #define MPI2_EVENT_SAS_TOPO_ES_ADDED (0x01) | 813 | #define MPI2_EVENT_SAS_TOPO_ES_ADDED (0x01) |
782 | #define MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING (0x02) | 814 | #define MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING (0x02) |
783 | #define MPI2_EVENT_SAS_TOPO_ES_RESPONDING (0x03) | 815 | #define MPI2_EVENT_SAS_TOPO_ES_RESPONDING (0x03) |
@@ -863,6 +895,44 @@ typedef struct _MPI2_EVENT_DATA_SAS_PHY_COUNTER { | |||
863 | * */ | 895 | * */ |
864 | 896 | ||
865 | 897 | ||
898 | /* Host Based Discovery Phy Event data */ | ||
899 | |||
900 | typedef struct _MPI2_EVENT_HBD_PHY_SAS { | ||
901 | U8 Flags; /* 0x00 */ | ||
902 | U8 NegotiatedLinkRate; /* 0x01 */ | ||
903 | U8 PhyNum; /* 0x02 */ | ||
904 | U8 PhysicalPort; /* 0x03 */ | ||
905 | U32 Reserved1; /* 0x04 */ | ||
906 | U8 InitialFrame[28]; /* 0x08 */ | ||
907 | } MPI2_EVENT_HBD_PHY_SAS, MPI2_POINTER PTR_MPI2_EVENT_HBD_PHY_SAS, | ||
908 | Mpi2EventHbdPhySas_t, MPI2_POINTER pMpi2EventHbdPhySas_t; | ||
909 | |||
910 | /* values for the Flags field */ | ||
911 | #define MPI2_EVENT_HBD_SAS_FLAGS_FRAME_VALID (0x02) | ||
912 | #define MPI2_EVENT_HBD_SAS_FLAGS_SATA_FRAME (0x01) | ||
913 | |||
914 | /* use MPI2_SAS_NEG_LINK_RATE_ defines from mpi2_cnfg.h for | ||
915 | * the NegotiatedLinkRate field */ | ||
916 | |||
917 | typedef union _MPI2_EVENT_HBD_DESCRIPTOR { | ||
918 | MPI2_EVENT_HBD_PHY_SAS Sas; | ||
919 | } MPI2_EVENT_HBD_DESCRIPTOR, MPI2_POINTER PTR_MPI2_EVENT_HBD_DESCRIPTOR, | ||
920 | Mpi2EventHbdDescriptor_t, MPI2_POINTER pMpi2EventHbdDescriptor_t; | ||
921 | |||
922 | typedef struct _MPI2_EVENT_DATA_HBD_PHY { | ||
923 | U8 DescriptorType; /* 0x00 */ | ||
924 | U8 Reserved1; /* 0x01 */ | ||
925 | U16 Reserved2; /* 0x02 */ | ||
926 | U32 Reserved3; /* 0x04 */ | ||
927 | MPI2_EVENT_HBD_DESCRIPTOR Descriptor; /* 0x08 */ | ||
928 | } MPI2_EVENT_DATA_HBD_PHY, MPI2_POINTER PTR_MPI2_EVENT_DATA_HBD_PHY, | ||
929 | Mpi2EventDataHbdPhy_t, MPI2_POINTER pMpi2EventDataMpi2EventDataHbdPhy_t; | ||
930 | |||
931 | /* values for the DescriptorType field */ | ||
932 | #define MPI2_EVENT_HBD_DT_SAS (0x01) | ||
933 | |||
934 | |||
935 | |||
866 | /**************************************************************************** | 936 | /**************************************************************************** |
867 | * EventAck message | 937 | * EventAck message |
868 | ****************************************************************************/ | 938 | ****************************************************************************/ |
@@ -1111,12 +1181,17 @@ typedef struct _MPI2_FW_IMAGE_HEADER | |||
1111 | #define MPI2_FW_HEADER_PID_TYPE_MASK (0xF000) | 1181 | #define MPI2_FW_HEADER_PID_TYPE_MASK (0xF000) |
1112 | #define MPI2_FW_HEADER_PID_TYPE_SAS (0x2000) | 1182 | #define MPI2_FW_HEADER_PID_TYPE_SAS (0x2000) |
1113 | 1183 | ||
1114 | #define MPI2_FW_HEADER_PID_PROD_MASK (0x0F00) | 1184 | #define MPI2_FW_HEADER_PID_PROD_MASK (0x0F00) |
1115 | #define MPI2_FW_HEADER_PID_PROD_A (0x0000) | 1185 | #define MPI2_FW_HEADER_PID_PROD_A (0x0000) |
1186 | #define MPI2_FW_HEADER_PID_PROD_MASK (0x0F00) | ||
1187 | #define MPI2_FW_HEADER_PID_PROD_TARGET_INITIATOR_SCSI (0x0200) | ||
1188 | #define MPI2_FW_HEADER_PID_PROD_IR_SCSI (0x0700) | ||
1189 | |||
1116 | 1190 | ||
1117 | #define MPI2_FW_HEADER_PID_FAMILY_MASK (0x00FF) | 1191 | #define MPI2_FW_HEADER_PID_FAMILY_MASK (0x00FF) |
1118 | /* SAS */ | 1192 | /* SAS */ |
1119 | #define MPI2_FW_HEADER_PID_FAMILY_2108_SAS (0x0010) | 1193 | #define MPI2_FW_HEADER_PID_FAMILY_2108_SAS (0x0013) |
1194 | #define MPI2_FW_HEADER_PID_FAMILY_2208_SAS (0x0014) | ||
1120 | 1195 | ||
1121 | /* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */ | 1196 | /* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */ |
1122 | 1197 | ||
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_sas.h b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h index 8a42b136cf53..2d8aeed51392 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_sas.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI Serial Attached SCSI structures and definitions | 6 | * Title: MPI Serial Attached SCSI structures and definitions |
7 | * Creation Date: February 9, 2007 | 7 | * Creation Date: February 9, 2007 |
8 | * | 8 | * |
9 | * mpi2.h Version: 02.00.02 | 9 | * mpi2.h Version: 02.00.03 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -18,6 +18,8 @@ | |||
18 | * Control Request. | 18 | * Control Request. |
19 | * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control | 19 | * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control |
20 | * Request. | 20 | * Request. |
21 | * 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST | ||
22 | * to MPI2_SGE_IO_UNION since it supports chained SGLs. | ||
21 | * -------------------------------------------------------------------------- | 23 | * -------------------------------------------------------------------------- |
22 | */ | 24 | */ |
23 | 25 | ||
@@ -160,7 +162,7 @@ typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST | |||
160 | U32 Reserved4; /* 0x14 */ | 162 | U32 Reserved4; /* 0x14 */ |
161 | U32 DataLength; /* 0x18 */ | 163 | U32 DataLength; /* 0x18 */ |
162 | U8 CommandFIS[20]; /* 0x1C */ | 164 | U8 CommandFIS[20]; /* 0x1C */ |
163 | MPI2_SIMPLE_SGE_UNION SGL; /* 0x20 */ | 165 | MPI2_SGE_IO_UNION SGL; /* 0x20 */ |
164 | } MPI2_SATA_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REQUEST, | 166 | } MPI2_SATA_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REQUEST, |
165 | Mpi2SataPassthroughRequest_t, MPI2_POINTER pMpi2SataPassthroughRequest_t; | 167 | Mpi2SataPassthroughRequest_t, MPI2_POINTER pMpi2SataPassthroughRequest_t; |
166 | 168 | ||
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..88e6eebc3159 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,43 @@ 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 fwfault_debug(%d)\n", mpt2sas_fwfault_debug); | ||
111 | list_for_each_entry(ioc, &mpt2sas_ioc_list, list) | ||
112 | ioc->fwfault_debug = mpt2sas_fwfault_debug; | ||
113 | return 0; | ||
114 | } | ||
115 | module_param_call(mpt2sas_fwfault_debug, _scsih_set_fwfault_debug, | ||
116 | param_get_int, &mpt2sas_fwfault_debug, 0644); | ||
117 | |||
80 | /** | 118 | /** |
81 | * _base_fault_reset_work - workq handling ioc fault conditions | 119 | * _base_fault_reset_work - workq handling ioc fault conditions |
82 | * @work: input argument, used to derive ioc | 120 | * @work: input argument, used to derive ioc |
@@ -121,7 +159,7 @@ _base_fault_reset_work(struct work_struct *work) | |||
121 | 159 | ||
122 | /** | 160 | /** |
123 | * mpt2sas_base_start_watchdog - start the fault_reset_work_q | 161 | * mpt2sas_base_start_watchdog - start the fault_reset_work_q |
124 | * @ioc: pointer to scsi command object | 162 | * @ioc: per adapter object |
125 | * Context: sleep. | 163 | * Context: sleep. |
126 | * | 164 | * |
127 | * Return nothing. | 165 | * Return nothing. |
@@ -155,7 +193,7 @@ mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc) | |||
155 | 193 | ||
156 | /** | 194 | /** |
157 | * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q | 195 | * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q |
158 | * @ioc: pointer to scsi command object | 196 | * @ioc: per adapter object |
159 | * Context: sleep. | 197 | * Context: sleep. |
160 | * | 198 | * |
161 | * Return nothing. | 199 | * Return nothing. |
@@ -177,10 +215,55 @@ mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc) | |||
177 | } | 215 | } |
178 | } | 216 | } |
179 | 217 | ||
218 | /** | ||
219 | * mpt2sas_base_fault_info - verbose translation of firmware FAULT code | ||
220 | * @ioc: per adapter object | ||
221 | * @fault_code: fault code | ||
222 | * | ||
223 | * Return nothing. | ||
224 | */ | ||
225 | void | ||
226 | mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code) | ||
227 | { | ||
228 | printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n", | ||
229 | ioc->name, fault_code); | ||
230 | } | ||
231 | |||
232 | /** | ||
233 | * mpt2sas_halt_firmware - halt's mpt controller firmware | ||
234 | * @ioc: per adapter object | ||
235 | * | ||
236 | * For debugging timeout related issues. Writing 0xCOFFEE00 | ||
237 | * to the doorbell register will halt controller firmware. With | ||
238 | * the purpose to stop both driver and firmware, the enduser can | ||
239 | * obtain a ring buffer from controller UART. | ||
240 | */ | ||
241 | void | ||
242 | mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc) | ||
243 | { | ||
244 | u32 doorbell; | ||
245 | |||
246 | if (!ioc->fwfault_debug) | ||
247 | return; | ||
248 | |||
249 | dump_stack(); | ||
250 | |||
251 | doorbell = readl(&ioc->chip->Doorbell); | ||
252 | if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) | ||
253 | mpt2sas_base_fault_info(ioc , doorbell); | ||
254 | else { | ||
255 | writel(0xC0FFEE00, &ioc->chip->Doorbell); | ||
256 | printk(MPT2SAS_ERR_FMT "Firmware is halted due to command " | ||
257 | "timeout\n", ioc->name); | ||
258 | } | ||
259 | |||
260 | panic("panic in %s\n", __func__); | ||
261 | } | ||
262 | |||
180 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 263 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
181 | /** | 264 | /** |
182 | * _base_sas_ioc_info - verbose translation of the ioc status | 265 | * _base_sas_ioc_info - verbose translation of the ioc status |
183 | * @ioc: pointer to scsi command object | 266 | * @ioc: per adapter object |
184 | * @mpi_reply: reply mf payload returned from firmware | 267 | * @mpi_reply: reply mf payload returned from firmware |
185 | * @request_hdr: request mf | 268 | * @request_hdr: request mf |
186 | * | 269 | * |
@@ -394,7 +477,7 @@ _base_sas_ioc_info(struct MPT2SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply, | |||
394 | 477 | ||
395 | /** | 478 | /** |
396 | * _base_display_event_data - verbose translation of firmware asyn events | 479 | * _base_display_event_data - verbose translation of firmware asyn events |
397 | * @ioc: pointer to scsi command object | 480 | * @ioc: per adapter object |
398 | * @mpi_reply: reply mf payload returned from firmware | 481 | * @mpi_reply: reply mf payload returned from firmware |
399 | * | 482 | * |
400 | * Return nothing. | 483 | * Return nothing. |
@@ -474,7 +557,7 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc, | |||
474 | 557 | ||
475 | /** | 558 | /** |
476 | * _base_sas_log_info - verbose translation of firmware log info | 559 | * _base_sas_log_info - verbose translation of firmware log info |
477 | * @ioc: pointer to scsi command object | 560 | * @ioc: per adapter object |
478 | * @log_info: log info | 561 | * @log_info: log info |
479 | * | 562 | * |
480 | * Return nothing. | 563 | * Return nothing. |
@@ -526,22 +609,8 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info) | |||
526 | } | 609 | } |
527 | 610 | ||
528 | /** | 611 | /** |
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 - | 612 | * _base_display_reply_info - |
544 | * @ioc: pointer to scsi command object | 613 | * @ioc: per adapter object |
545 | * @smid: system request message index | 614 | * @smid: system request message index |
546 | * @msix_index: MSIX table index supplied by the OS | 615 | * @msix_index: MSIX table index supplied by the OS |
547 | * @reply: reply message frame(lower 32bit addr) | 616 | * @reply: reply message frame(lower 32bit addr) |
@@ -570,7 +639,7 @@ _base_display_reply_info(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
570 | 639 | ||
571 | /** | 640 | /** |
572 | * mpt2sas_base_done - base internal command completion routine | 641 | * mpt2sas_base_done - base internal command completion routine |
573 | * @ioc: pointer to scsi command object | 642 | * @ioc: per adapter object |
574 | * @smid: system request message index | 643 | * @smid: system request message index |
575 | * @msix_index: MSIX table index supplied by the OS | 644 | * @msix_index: MSIX table index supplied by the OS |
576 | * @reply: reply message frame(lower 32bit addr) | 645 | * @reply: reply message frame(lower 32bit addr) |
@@ -603,7 +672,7 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
603 | 672 | ||
604 | /** | 673 | /** |
605 | * _base_async_event - main callback handler for firmware asyn events | 674 | * _base_async_event - main callback handler for firmware asyn events |
606 | * @ioc: pointer to scsi command object | 675 | * @ioc: per adapter object |
607 | * @msix_index: MSIX table index supplied by the OS | 676 | * @msix_index: MSIX table index supplied by the OS |
608 | * @reply: reply message frame(lower 32bit addr) | 677 | * @reply: reply message frame(lower 32bit addr) |
609 | * | 678 | * |
@@ -684,7 +753,7 @@ _base_get_cb_idx(struct MPT2SAS_ADAPTER *ioc, u16 smid) | |||
684 | 753 | ||
685 | /** | 754 | /** |
686 | * _base_mask_interrupts - disable interrupts | 755 | * _base_mask_interrupts - disable interrupts |
687 | * @ioc: pointer to scsi command object | 756 | * @ioc: per adapter object |
688 | * | 757 | * |
689 | * Disabling ResetIRQ, Reply and Doorbell Interrupts | 758 | * Disabling ResetIRQ, Reply and Doorbell Interrupts |
690 | * | 759 | * |
@@ -704,7 +773,7 @@ _base_mask_interrupts(struct MPT2SAS_ADAPTER *ioc) | |||
704 | 773 | ||
705 | /** | 774 | /** |
706 | * _base_unmask_interrupts - enable interrupts | 775 | * _base_unmask_interrupts - enable interrupts |
707 | * @ioc: pointer to scsi command object | 776 | * @ioc: per adapter object |
708 | * | 777 | * |
709 | * Enabling only Reply Interrupts | 778 | * Enabling only Reply Interrupts |
710 | * | 779 | * |
@@ -1152,6 +1221,8 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
1152 | u32 memap_sz; | 1221 | u32 memap_sz; |
1153 | u32 pio_sz; | 1222 | u32 pio_sz; |
1154 | int i, r = 0; | 1223 | int i, r = 0; |
1224 | u64 pio_chip = 0; | ||
1225 | u64 chip_phys = 0; | ||
1155 | 1226 | ||
1156 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", | 1227 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", |
1157 | ioc->name, __func__)); | 1228 | ioc->name, __func__)); |
@@ -1185,12 +1256,13 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
1185 | if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO) { | 1256 | if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO) { |
1186 | if (pio_sz) | 1257 | if (pio_sz) |
1187 | continue; | 1258 | continue; |
1188 | ioc->pio_chip = pci_resource_start(pdev, i); | 1259 | pio_chip = (u64)pci_resource_start(pdev, i); |
1189 | pio_sz = pci_resource_len(pdev, i); | 1260 | pio_sz = pci_resource_len(pdev, i); |
1190 | } else { | 1261 | } else { |
1191 | if (memap_sz) | 1262 | if (memap_sz) |
1192 | continue; | 1263 | continue; |
1193 | ioc->chip_phys = pci_resource_start(pdev, i); | 1264 | ioc->chip_phys = pci_resource_start(pdev, i); |
1265 | chip_phys = (u64)ioc->chip_phys; | ||
1194 | memap_sz = pci_resource_len(pdev, i); | 1266 | memap_sz = pci_resource_len(pdev, i); |
1195 | ioc->chip = ioremap(ioc->chip_phys, memap_sz); | 1267 | ioc->chip = ioremap(ioc->chip_phys, memap_sz); |
1196 | if (ioc->chip == NULL) { | 1268 | if (ioc->chip == NULL) { |
@@ -1210,10 +1282,10 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
1210 | printk(MPT2SAS_INFO_FMT "%s: IRQ %d\n", | 1282 | printk(MPT2SAS_INFO_FMT "%s: IRQ %d\n", |
1211 | ioc->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" : | 1283 | ioc->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" : |
1212 | "IO-APIC enabled"), ioc->pci_irq); | 1284 | "IO-APIC enabled"), ioc->pci_irq); |
1213 | printk(MPT2SAS_INFO_FMT "iomem(0x%lx), mapped(0x%p), size(%d)\n", | 1285 | printk(MPT2SAS_INFO_FMT "iomem(0x%016llx), mapped(0x%p), size(%d)\n", |
1214 | ioc->name, ioc->chip_phys, ioc->chip, memap_sz); | 1286 | ioc->name, (unsigned long long)chip_phys, ioc->chip, memap_sz); |
1215 | printk(MPT2SAS_INFO_FMT "ioport(0x%lx), size(%d)\n", | 1287 | printk(MPT2SAS_INFO_FMT "ioport(0x%016llx), size(%d)\n", |
1216 | ioc->name, ioc->pio_chip, pio_sz); | 1288 | ioc->name, (unsigned long long)pio_chip, pio_sz); |
1217 | 1289 | ||
1218 | return 0; | 1290 | return 0; |
1219 | 1291 | ||
@@ -1258,12 +1330,13 @@ mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid) | |||
1258 | * @ioc: per adapter object | 1330 | * @ioc: per adapter object |
1259 | * @smid: system request message index | 1331 | * @smid: system request message index |
1260 | * | 1332 | * |
1261 | * Returns phys pointer to sense buffer. | 1333 | * Returns phys pointer to the low 32bit address of the sense buffer. |
1262 | */ | 1334 | */ |
1263 | dma_addr_t | 1335 | __le32 |
1264 | mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid) | 1336 | mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid) |
1265 | { | 1337 | { |
1266 | return ioc->sense_dma + ((smid - 1) * SCSI_SENSE_BUFFERSIZE); | 1338 | return cpu_to_le32(ioc->sense_dma + |
1339 | ((smid - 1) * SCSI_SENSE_BUFFERSIZE)); | ||
1267 | } | 1340 | } |
1268 | 1341 | ||
1269 | /** | 1342 | /** |
@@ -1697,6 +1770,12 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) | |||
1697 | } | 1770 | } |
1698 | 1771 | ||
1699 | if (ioc->facts.IOCCapabilities & | 1772 | if (ioc->facts.IOCCapabilities & |
1773 | MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) { | ||
1774 | printk(KERN_INFO "%sDiag Extended Buffer", i ? "," : ""); | ||
1775 | i++; | ||
1776 | } | ||
1777 | |||
1778 | if (ioc->facts.IOCCapabilities & | ||
1700 | MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) { | 1779 | MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) { |
1701 | printk("%sTask Set Full", i ? "," : ""); | 1780 | printk("%sTask Set Full", i ? "," : ""); |
1702 | i++; | 1781 | i++; |
@@ -2871,6 +2950,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2871 | Mpi2IOCInitRequest_t mpi_request; | 2950 | Mpi2IOCInitRequest_t mpi_request; |
2872 | Mpi2IOCInitReply_t mpi_reply; | 2951 | Mpi2IOCInitReply_t mpi_reply; |
2873 | int r; | 2952 | int r; |
2953 | struct timeval current_time; | ||
2954 | u16 ioc_status; | ||
2874 | 2955 | ||
2875 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 2956 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, |
2876 | __func__)); | 2957 | __func__)); |
@@ -2921,6 +3002,13 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2921 | cpu_to_le32(ioc->reply_post_free_dma); | 3002 | cpu_to_le32(ioc->reply_post_free_dma); |
2922 | #endif | 3003 | #endif |
2923 | 3004 | ||
3005 | /* This time stamp specifies number of milliseconds | ||
3006 | * since epoch ~ midnight January 1, 1970. | ||
3007 | */ | ||
3008 | do_gettimeofday(¤t_time); | ||
3009 | mpi_request.TimeStamp = (current_time.tv_sec * 1000) + | ||
3010 | (current_time.tv_usec >> 3); | ||
3011 | |||
2924 | if (ioc->logging_level & MPT_DEBUG_INIT) { | 3012 | if (ioc->logging_level & MPT_DEBUG_INIT) { |
2925 | u32 *mfp; | 3013 | u32 *mfp; |
2926 | int i; | 3014 | int i; |
@@ -2943,7 +3031,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2943 | return r; | 3031 | return r; |
2944 | } | 3032 | } |
2945 | 3033 | ||
2946 | if (mpi_reply.IOCStatus != MPI2_IOCSTATUS_SUCCESS || | 3034 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; |
3035 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS || | ||
2947 | mpi_reply.IOCLogInfo) { | 3036 | mpi_reply.IOCLogInfo) { |
2948 | printk(MPT2SAS_ERR_FMT "%s: failed\n", ioc->name, __func__); | 3037 | printk(MPT2SAS_ERR_FMT "%s: failed\n", ioc->name, __func__); |
2949 | r = -EIO; | 3038 | r = -EIO; |
@@ -3461,11 +3550,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3461 | return r; | 3550 | return r; |
3462 | 3551 | ||
3463 | pci_set_drvdata(ioc->pdev, ioc->shost); | 3552 | pci_set_drvdata(ioc->pdev, ioc->shost); |
3464 | r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); | 3553 | r = _base_get_ioc_facts(ioc, CAN_SLEEP); |
3465 | if (r) | 3554 | if (r) |
3466 | goto out_free_resources; | 3555 | goto out_free_resources; |
3467 | 3556 | ||
3468 | r = _base_get_ioc_facts(ioc, CAN_SLEEP); | 3557 | r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); |
3469 | if (r) | 3558 | if (r) |
3470 | goto out_free_resources; | 3559 | goto out_free_resources; |
3471 | 3560 | ||
@@ -3486,6 +3575,8 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3486 | 3575 | ||
3487 | init_waitqueue_head(&ioc->reset_wq); | 3576 | init_waitqueue_head(&ioc->reset_wq); |
3488 | 3577 | ||
3578 | ioc->fwfault_debug = mpt2sas_fwfault_debug; | ||
3579 | |||
3489 | /* base internal command bits */ | 3580 | /* base internal command bits */ |
3490 | mutex_init(&ioc->base_cmds.mutex); | 3581 | mutex_init(&ioc->base_cmds.mutex); |
3491 | ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | 3582 | ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); |
@@ -3496,6 +3587,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3496 | ioc->transport_cmds.status = MPT2_CMD_NOT_USED; | 3587 | ioc->transport_cmds.status = MPT2_CMD_NOT_USED; |
3497 | mutex_init(&ioc->transport_cmds.mutex); | 3588 | mutex_init(&ioc->transport_cmds.mutex); |
3498 | 3589 | ||
3590 | /* scsih internal command bits */ | ||
3591 | ioc->scsih_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | ||
3592 | ioc->scsih_cmds.status = MPT2_CMD_NOT_USED; | ||
3593 | mutex_init(&ioc->scsih_cmds.mutex); | ||
3594 | |||
3499 | /* task management internal command bits */ | 3595 | /* task management internal command bits */ |
3500 | ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | 3596 | ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); |
3501 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; | 3597 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; |
@@ -3531,6 +3627,8 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3531 | goto out_free_resources; | 3627 | goto out_free_resources; |
3532 | 3628 | ||
3533 | mpt2sas_base_start_watchdog(ioc); | 3629 | mpt2sas_base_start_watchdog(ioc); |
3630 | if (diag_buffer_enable != 0) | ||
3631 | mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); | ||
3534 | return 0; | 3632 | return 0; |
3535 | 3633 | ||
3536 | out_free_resources: | 3634 | out_free_resources: |
@@ -3684,6 +3782,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, | 3782 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, |
3685 | __func__)); | 3783 | __func__)); |
3686 | 3784 | ||
3785 | if (mpt2sas_fwfault_debug) | ||
3786 | mpt2sas_halt_firmware(ioc); | ||
3787 | |||
3687 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | 3788 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); |
3688 | if (ioc->shost_recovery) { | 3789 | if (ioc->shost_recovery) { |
3689 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | 3790 | 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..e18b0544c38f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
@@ -69,10 +69,10 @@ | |||
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 "04.100.01.00" |
73 | #define MPT2SAS_MAJOR_VERSION 02 | 73 | #define MPT2SAS_MAJOR_VERSION 04 |
74 | #define MPT2SAS_MINOR_VERSION 100 | 74 | #define MPT2SAS_MINOR_VERSION 100 |
75 | #define MPT2SAS_BUILD_VERSION 03 | 75 | #define MPT2SAS_BUILD_VERSION 01 |
76 | #define MPT2SAS_RELEASE_VERSION 00 | 76 | #define MPT2SAS_RELEASE_VERSION 00 |
77 | 77 | ||
78 | /* | 78 | /* |
@@ -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; |
@@ -323,6 +323,7 @@ struct _sas_device { | |||
323 | * @device_info: bitfield provides detailed info about the hidden components | 323 | * @device_info: bitfield provides detailed info about the hidden components |
324 | * @num_pds: number of hidden raid components | 324 | * @num_pds: number of hidden raid components |
325 | * @responding: used in _scsih_raid_device_mark_responding | 325 | * @responding: used in _scsih_raid_device_mark_responding |
326 | * @percent_complete: resync percent complete | ||
326 | */ | 327 | */ |
327 | struct _raid_device { | 328 | struct _raid_device { |
328 | struct list_head list; | 329 | struct list_head list; |
@@ -336,6 +337,7 @@ struct _raid_device { | |||
336 | u32 device_info; | 337 | u32 device_info; |
337 | u8 num_pds; | 338 | u8 num_pds; |
338 | u8 responding; | 339 | u8 responding; |
340 | u8 percent_complete; | ||
339 | }; | 341 | }; |
340 | 342 | ||
341 | /** | 343 | /** |
@@ -352,8 +354,6 @@ struct _boot_device { | |||
352 | /** | 354 | /** |
353 | * struct _sas_port - wide/narrow sas port information | 355 | * struct _sas_port - wide/narrow sas port information |
354 | * @port_list: list of ports belonging to expander | 356 | * @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 | 357 | * @num_phys: number of phys belonging to this port |
358 | * @remote_identify: attached device identification | 358 | * @remote_identify: attached device identification |
359 | * @rphy: sas transport rphy object | 359 | * @rphy: sas transport rphy object |
@@ -362,8 +362,6 @@ struct _boot_device { | |||
362 | */ | 362 | */ |
363 | struct _sas_port { | 363 | struct _sas_port { |
364 | struct list_head port_list; | 364 | struct list_head port_list; |
365 | u16 handle; | ||
366 | u64 sas_address; | ||
367 | u8 num_phys; | 365 | u8 num_phys; |
368 | struct sas_identify remote_identify; | 366 | struct sas_identify remote_identify; |
369 | struct sas_rphy *rphy; | 367 | struct sas_rphy *rphy; |
@@ -398,7 +396,7 @@ struct _sas_phy { | |||
398 | * @num_phys: number phys belonging to this sas_host/expander | 396 | * @num_phys: number phys belonging to this sas_host/expander |
399 | * @sas_address: sas address of this sas_host/expander | 397 | * @sas_address: sas address of this sas_host/expander |
400 | * @handle: handle for this sas_host/expander | 398 | * @handle: handle for this sas_host/expander |
401 | * @parent_handle: parent handle | 399 | * @sas_address_parent: sas address of parent expander or sas host |
402 | * @enclosure_handle: handle for this a member of an enclosure | 400 | * @enclosure_handle: handle for this a member of an enclosure |
403 | * @device_info: bitwise defining capabilities of this sas_host/expander | 401 | * @device_info: bitwise defining capabilities of this sas_host/expander |
404 | * @responding: used in _scsih_expander_device_mark_responding | 402 | * @responding: used in _scsih_expander_device_mark_responding |
@@ -411,7 +409,7 @@ struct _sas_node { | |||
411 | u8 num_phys; | 409 | u8 num_phys; |
412 | u64 sas_address; | 410 | u64 sas_address; |
413 | u16 handle; | 411 | u16 handle; |
414 | u16 parent_handle; | 412 | u64 sas_address_parent; |
415 | u16 enclosure_handle; | 413 | u16 enclosure_handle; |
416 | u64 enclosure_logical_id; | 414 | u64 enclosure_logical_id; |
417 | u8 responding; | 415 | u8 responding; |
@@ -468,8 +466,8 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); | |||
468 | * @pdev: pci pdev object | 466 | * @pdev: pci pdev object |
469 | * @chip: memory mapped register space | 467 | * @chip: memory mapped register space |
470 | * @chip_phys: physical addrss prior to mapping | 468 | * @chip_phys: physical addrss prior to mapping |
471 | * @pio_chip: I/O mapped register space | ||
472 | * @logging_level: see mpt2sas_debug.h | 469 | * @logging_level: see mpt2sas_debug.h |
470 | * @fwfault_debug: debuging FW timeouts | ||
473 | * @ir_firmware: IR firmware present | 471 | * @ir_firmware: IR firmware present |
474 | * @bars: bitmask of BAR's that must be configured | 472 | * @bars: bitmask of BAR's that must be configured |
475 | * @mask_interrupts: ignore interrupt | 473 | * @mask_interrupts: ignore interrupt |
@@ -495,12 +493,14 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); | |||
495 | * @msix_table_backup: backup msix table | 493 | * @msix_table_backup: backup msix table |
496 | * @scsi_io_cb_idx: shost generated commands | 494 | * @scsi_io_cb_idx: shost generated commands |
497 | * @tm_cb_idx: task management commands | 495 | * @tm_cb_idx: task management commands |
496 | * @scsih_cb_idx: scsih internal commands | ||
498 | * @transport_cb_idx: transport internal commands | 497 | * @transport_cb_idx: transport internal commands |
499 | * @ctl_cb_idx: clt internal commands | 498 | * @ctl_cb_idx: clt internal commands |
500 | * @base_cb_idx: base internal commands | 499 | * @base_cb_idx: base internal commands |
501 | * @config_cb_idx: base internal commands | 500 | * @config_cb_idx: base internal commands |
502 | * @base_cmds: | 501 | * @base_cmds: |
503 | * @transport_cmds: | 502 | * @transport_cmds: |
503 | * @scsih_cmds: | ||
504 | * @tm_cmds: | 504 | * @tm_cmds: |
505 | * @ctl_cmds: | 505 | * @ctl_cmds: |
506 | * @config_cmds: | 506 | * @config_cmds: |
@@ -588,9 +588,9 @@ struct MPT2SAS_ADAPTER { | |||
588 | char tmp_string[MPT_STRING_LENGTH]; | 588 | char tmp_string[MPT_STRING_LENGTH]; |
589 | struct pci_dev *pdev; | 589 | struct pci_dev *pdev; |
590 | Mpi2SystemInterfaceRegs_t __iomem *chip; | 590 | Mpi2SystemInterfaceRegs_t __iomem *chip; |
591 | unsigned long chip_phys; | 591 | resource_size_t chip_phys; |
592 | 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); |
@@ -849,6 +853,8 @@ int mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
849 | *mpi_reply, Mpi2IOUnitPage1_t *config_page); | 853 | *mpi_reply, Mpi2IOUnitPage1_t *config_page); |
850 | int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | 854 | int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t |
851 | *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz); | 855 | *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz); |
856 | int mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, | ||
857 | Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz); | ||
852 | int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | 858 | int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t |
853 | *mpi_reply, Mpi2IOCPage8_t *config_page); | 859 | *mpi_reply, Mpi2IOCPage8_t *config_page); |
854 | int mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | 860 | int mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t |
@@ -886,19 +892,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, | 892 | void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, |
887 | Mpi2EventNotificationReply_t *mpi_reply); | 893 | Mpi2EventNotificationReply_t *mpi_reply); |
888 | 894 | ||
895 | void mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, | ||
896 | u8 bits_to_regsiter); | ||
897 | |||
889 | /* transport shared API */ | 898 | /* transport shared API */ |
890 | u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 899 | u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
891 | u32 reply); | 900 | u32 reply); |
892 | struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, | 901 | struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, |
893 | u16 handle, u16 parent_handle); | 902 | u16 handle, u64 sas_address); |
894 | void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | 903 | void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, |
895 | u16 parent_handle); | 904 | u64 sas_address_parent); |
896 | int mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy | 905 | int mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy |
897 | *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev); | 906 | *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev); |
898 | int mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy | 907 | int mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy |
899 | *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev); | 908 | *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev); |
900 | void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, u16 handle, | 909 | void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, |
901 | u16 attached_handle, u8 phy_number, u8 link_rate); | 910 | u64 sas_address, u16 handle, u8 phy_number, u8 link_rate); |
902 | extern struct sas_function_template mpt2sas_transport_functions; | 911 | extern struct sas_function_template mpt2sas_transport_functions; |
903 | extern struct scsi_transport_template *mpt2sas_transport_template; | 912 | extern struct scsi_transport_template *mpt2sas_transport_template; |
904 | extern int scsi_internal_device_block(struct scsi_device *sdev); | 913 | extern int scsi_internal_device_block(struct scsi_device *sdev); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index 594a389c6526..cf44b355bc97 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/workqueue.h> | 51 | #include <linux/workqueue.h> |
52 | #include <linux/delay.h> | 52 | #include <linux/delay.h> |
53 | #include <linux/pci.h> | 53 | #include <linux/pci.h> |
54 | #include <linux/slab.h> | ||
54 | 55 | ||
55 | #include "mpt2sas_base.h" | 56 | #include "mpt2sas_base.h" |
56 | 57 | ||
@@ -324,7 +325,9 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
324 | if (r != 0) | 325 | if (r != 0) |
325 | goto out; | 326 | goto out; |
326 | if (mpi_request->Action == | 327 | if (mpi_request->Action == |
327 | MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT) { | 328 | MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT || |
329 | mpi_request->Action == | ||
330 | MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) { | ||
328 | ioc->base_add_sg_single(&mpi_request->PageBufferSGE, | 331 | ioc->base_add_sg_single(&mpi_request->PageBufferSGE, |
329 | MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz, | 332 | MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz, |
330 | mem.page_dma); | 333 | mem.page_dma); |
@@ -882,7 +885,7 @@ mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
882 | } | 885 | } |
883 | 886 | ||
884 | /** | 887 | /** |
885 | * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 0 | 888 | * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1 |
886 | * @ioc: per adapter object | 889 | * @ioc: per adapter object |
887 | * @mpi_reply: reply mf payload returned from firmware | 890 | * @mpi_reply: reply mf payload returned from firmware |
888 | * @config_page: contents of the config page | 891 | * @config_page: contents of the config page |
@@ -907,7 +910,7 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
907 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | 910 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; |
908 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; | 911 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; |
909 | mpi_request.Header.PageNumber = 1; | 912 | mpi_request.Header.PageNumber = 1; |
910 | mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; | 913 | mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; |
911 | mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); | 914 | mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); |
912 | r = _config_request(ioc, &mpi_request, mpi_reply, | 915 | r = _config_request(ioc, &mpi_request, mpi_reply, |
913 | MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | 916 | MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); |
@@ -922,6 +925,49 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
922 | } | 925 | } |
923 | 926 | ||
924 | /** | 927 | /** |
928 | * mpt2sas_config_set_sas_iounit_pg1 - send sas iounit page 1 | ||
929 | * @ioc: per adapter object | ||
930 | * @mpi_reply: reply mf payload returned from firmware | ||
931 | * @config_page: contents of the config page | ||
932 | * @sz: size of buffer passed in config_page | ||
933 | * Context: sleep. | ||
934 | * | ||
935 | * Calling function should call config_get_number_hba_phys prior to | ||
936 | * this function, so enough memory is allocated for config_page. | ||
937 | * | ||
938 | * Returns 0 for success, non-zero for failure. | ||
939 | */ | ||
940 | int | ||
941 | mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | ||
942 | *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz) | ||
943 | { | ||
944 | Mpi2ConfigRequest_t mpi_request; | ||
945 | int r; | ||
946 | |||
947 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | ||
948 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | ||
949 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | ||
950 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | ||
951 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; | ||
952 | mpi_request.Header.PageNumber = 1; | ||
953 | mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; | ||
954 | mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); | ||
955 | r = _config_request(ioc, &mpi_request, mpi_reply, | ||
956 | MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | ||
957 | if (r) | ||
958 | goto out; | ||
959 | |||
960 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
961 | _config_request(ioc, &mpi_request, mpi_reply, | ||
962 | MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); | ||
963 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; | ||
964 | r = _config_request(ioc, &mpi_request, mpi_reply, | ||
965 | MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); | ||
966 | out: | ||
967 | return r; | ||
968 | } | ||
969 | |||
970 | /** | ||
925 | * mpt2sas_config_get_expander_pg0 - obtain expander page 0 | 971 | * mpt2sas_config_get_expander_pg0 - obtain expander page 0 |
926 | * @ioc: per adapter object | 972 | * @ioc: per adapter object |
927 | * @mpi_reply: reply mf payload returned from firmware | 973 | * @mpi_reply: reply mf payload returned from firmware |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index 57d724633906..fa9bf83819d5 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 */ |
@@ -890,12 +891,14 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, | |||
890 | 891 | ||
891 | issue_host_reset: | 892 | issue_host_reset: |
892 | if (issue_reset) { | 893 | if (issue_reset) { |
894 | ret = -ENODATA; | ||
893 | if ((mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || | 895 | if ((mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || |
894 | mpi_request->Function == | 896 | mpi_request->Function == |
895 | MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { | 897 | MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { |
896 | printk(MPT2SAS_INFO_FMT "issue target reset: handle " | 898 | printk(MPT2SAS_INFO_FMT "issue target reset: handle " |
897 | "= (0x%04x)\n", ioc->name, | 899 | "= (0x%04x)\n", ioc->name, |
898 | mpi_request->FunctionDependent1); | 900 | mpi_request->FunctionDependent1); |
901 | mpt2sas_halt_firmware(ioc); | ||
899 | mutex_lock(&ioc->tm_cmds.mutex); | 902 | mutex_lock(&ioc->tm_cmds.mutex); |
900 | mpt2sas_scsih_issue_tm(ioc, | 903 | mpt2sas_scsih_issue_tm(ioc, |
901 | mpi_request->FunctionDependent1, 0, | 904 | mpi_request->FunctionDependent1, 0, |
@@ -1229,7 +1232,7 @@ _ctl_btdh_mapping(void __user *arg) | |||
1229 | /** | 1232 | /** |
1230 | * _ctl_diag_capability - return diag buffer capability | 1233 | * _ctl_diag_capability - return diag buffer capability |
1231 | * @ioc: per adapter object | 1234 | * @ioc: per adapter object |
1232 | * @buffer_type: specifies either TRACE or SNAPSHOT | 1235 | * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED |
1233 | * | 1236 | * |
1234 | * returns 1 when diag buffer support is enabled in firmware | 1237 | * returns 1 when diag buffer support is enabled in firmware |
1235 | */ | 1238 | */ |
@@ -1249,24 +1252,25 @@ _ctl_diag_capability(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type) | |||
1249 | MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) | 1252 | MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) |
1250 | rc = 1; | 1253 | rc = 1; |
1251 | break; | 1254 | break; |
1255 | case MPI2_DIAG_BUF_TYPE_EXTENDED: | ||
1256 | if (ioc->facts.IOCCapabilities & | ||
1257 | MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) | ||
1258 | rc = 1; | ||
1252 | } | 1259 | } |
1253 | 1260 | ||
1254 | return rc; | 1261 | return rc; |
1255 | } | 1262 | } |
1256 | 1263 | ||
1257 | /** | 1264 | /** |
1258 | * _ctl_diag_register - application register with driver | 1265 | * _ctl_diag_register_2 - wrapper for registering diag buffer support |
1259 | * @arg - user space buffer containing ioctl content | 1266 | * @ioc: per adapter object |
1260 | * @state - NON_BLOCKING or BLOCKING | 1267 | * @diag_register: the diag_register struct passed in from user space |
1261 | * | 1268 | * |
1262 | * This will allow the driver to setup any required buffers that will be | ||
1263 | * needed by firmware to communicate with the driver. | ||
1264 | */ | 1269 | */ |
1265 | static long | 1270 | static long |
1266 | _ctl_diag_register(void __user *arg, enum block_state state) | 1271 | _ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc, |
1272 | struct mpt2_diag_register *diag_register) | ||
1267 | { | 1273 | { |
1268 | struct mpt2_diag_register karg; | ||
1269 | struct MPT2SAS_ADAPTER *ioc; | ||
1270 | int rc, i; | 1274 | int rc, i; |
1271 | void *request_data = NULL; | 1275 | void *request_data = NULL; |
1272 | dma_addr_t request_data_dma; | 1276 | dma_addr_t request_data_dma; |
@@ -1279,18 +1283,17 @@ _ctl_diag_register(void __user *arg, enum block_state state) | |||
1279 | u16 ioc_status; | 1283 | u16 ioc_status; |
1280 | u8 issue_reset = 0; | 1284 | u8 issue_reset = 0; |
1281 | 1285 | ||
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, | 1286 | dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, |
1291 | __func__)); | 1287 | __func__)); |
1292 | 1288 | ||
1293 | buffer_type = karg.buffer_type; | 1289 | if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) { |
1290 | printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n", | ||
1291 | ioc->name, __func__); | ||
1292 | rc = -EAGAIN; | ||
1293 | goto out; | ||
1294 | } | ||
1295 | |||
1296 | buffer_type = diag_register->buffer_type; | ||
1294 | if (!_ctl_diag_capability(ioc, buffer_type)) { | 1297 | if (!_ctl_diag_capability(ioc, buffer_type)) { |
1295 | printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for " | 1298 | printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for " |
1296 | "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type); | 1299 | "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type); |
@@ -1305,24 +1308,12 @@ _ctl_diag_register(void __user *arg, enum block_state state) | |||
1305 | return -EINVAL; | 1308 | return -EINVAL; |
1306 | } | 1309 | } |
1307 | 1310 | ||
1308 | if (karg.requested_buffer_size % 4) { | 1311 | if (diag_register->requested_buffer_size % 4) { |
1309 | printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size " | 1312 | printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size " |
1310 | "is not 4 byte aligned\n", ioc->name, __func__); | 1313 | "is not 4 byte aligned\n", ioc->name, __func__); |
1311 | return -EINVAL; | 1314 | return -EINVAL; |
1312 | } | 1315 | } |
1313 | 1316 | ||
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); | 1317 | smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx); |
1327 | if (!smid) { | 1318 | if (!smid) { |
1328 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", | 1319 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", |
@@ -1338,12 +1329,12 @@ _ctl_diag_register(void __user *arg, enum block_state state) | |||
1338 | ioc->ctl_cmds.smid = smid; | 1329 | ioc->ctl_cmds.smid = smid; |
1339 | 1330 | ||
1340 | request_data = ioc->diag_buffer[buffer_type]; | 1331 | request_data = ioc->diag_buffer[buffer_type]; |
1341 | request_data_sz = karg.requested_buffer_size; | 1332 | request_data_sz = diag_register->requested_buffer_size; |
1342 | ioc->unique_id[buffer_type] = karg.unique_id; | 1333 | ioc->unique_id[buffer_type] = diag_register->unique_id; |
1343 | ioc->diag_buffer_status[buffer_type] = 0; | 1334 | ioc->diag_buffer_status[buffer_type] = 0; |
1344 | memcpy(ioc->product_specific[buffer_type], karg.product_specific, | 1335 | memcpy(ioc->product_specific[buffer_type], |
1345 | MPT2_PRODUCT_SPECIFIC_DWORDS); | 1336 | diag_register->product_specific, MPT2_PRODUCT_SPECIFIC_DWORDS); |
1346 | ioc->diagnostic_flags[buffer_type] = karg.diagnostic_flags; | 1337 | ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags; |
1347 | 1338 | ||
1348 | if (request_data) { | 1339 | if (request_data) { |
1349 | request_data_dma = ioc->diag_buffer_dma[buffer_type]; | 1340 | request_data_dma = ioc->diag_buffer_dma[buffer_type]; |
@@ -1373,8 +1364,8 @@ _ctl_diag_register(void __user *arg, enum block_state state) | |||
1373 | } | 1364 | } |
1374 | 1365 | ||
1375 | mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST; | 1366 | mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST; |
1376 | mpi_request->BufferType = karg.buffer_type; | 1367 | mpi_request->BufferType = diag_register->buffer_type; |
1377 | mpi_request->Flags = cpu_to_le32(karg.diagnostic_flags); | 1368 | mpi_request->Flags = cpu_to_le32(diag_register->diagnostic_flags); |
1378 | mpi_request->BufferAddress = cpu_to_le64(request_data_dma); | 1369 | mpi_request->BufferAddress = cpu_to_le64(request_data_dma); |
1379 | mpi_request->BufferLength = cpu_to_le32(request_data_sz); | 1370 | mpi_request->BufferLength = cpu_to_le32(request_data_sz); |
1380 | mpi_request->VF_ID = 0; /* TODO */ | 1371 | mpi_request->VF_ID = 0; /* TODO */ |
@@ -1422,7 +1413,7 @@ _ctl_diag_register(void __user *arg, enum block_state state) | |||
1422 | } else { | 1413 | } else { |
1423 | printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " | 1414 | printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " |
1424 | "log_info(0x%08x)\n", ioc->name, __func__, | 1415 | "log_info(0x%08x)\n", ioc->name, __func__, |
1425 | ioc_status, mpi_reply->IOCLogInfo); | 1416 | ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); |
1426 | rc = -EFAULT; | 1417 | rc = -EFAULT; |
1427 | } | 1418 | } |
1428 | 1419 | ||
@@ -1438,6 +1429,83 @@ _ctl_diag_register(void __user *arg, enum block_state state) | |||
1438 | request_data, request_data_dma); | 1429 | request_data, request_data_dma); |
1439 | 1430 | ||
1440 | ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; | 1431 | ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; |
1432 | return rc; | ||
1433 | } | ||
1434 | |||
1435 | /** | ||
1436 | * mpt2sas_enable_diag_buffer - enabling diag_buffers support driver load time | ||
1437 | * @ioc: per adapter object | ||
1438 | * @bits_to_register: bitwise field where trace is bit 0, and snapshot is bit 1 | ||
1439 | * | ||
1440 | * This is called when command line option diag_buffer_enable is enabled | ||
1441 | * at driver load time. | ||
1442 | */ | ||
1443 | void | ||
1444 | mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, u8 bits_to_register) | ||
1445 | { | ||
1446 | struct mpt2_diag_register diag_register; | ||
1447 | |||
1448 | memset(&diag_register, 0, sizeof(struct mpt2_diag_register)); | ||
1449 | |||
1450 | if (bits_to_register & 1) { | ||
1451 | printk(MPT2SAS_INFO_FMT "registering trace buffer support\n", | ||
1452 | ioc->name); | ||
1453 | diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE; | ||
1454 | /* register for 1MB buffers */ | ||
1455 | diag_register.requested_buffer_size = (1024 * 1024); | ||
1456 | diag_register.unique_id = 0x7075900; | ||
1457 | _ctl_diag_register_2(ioc, &diag_register); | ||
1458 | } | ||
1459 | |||
1460 | if (bits_to_register & 2) { | ||
1461 | printk(MPT2SAS_INFO_FMT "registering snapshot buffer support\n", | ||
1462 | ioc->name); | ||
1463 | diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_SNAPSHOT; | ||
1464 | /* register for 2MB buffers */ | ||
1465 | diag_register.requested_buffer_size = 2 * (1024 * 1024); | ||
1466 | diag_register.unique_id = 0x7075901; | ||
1467 | _ctl_diag_register_2(ioc, &diag_register); | ||
1468 | } | ||
1469 | |||
1470 | if (bits_to_register & 4) { | ||
1471 | printk(MPT2SAS_INFO_FMT "registering extended buffer support\n", | ||
1472 | ioc->name); | ||
1473 | diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_EXTENDED; | ||
1474 | /* register for 2MB buffers */ | ||
1475 | diag_register.requested_buffer_size = 2 * (1024 * 1024); | ||
1476 | diag_register.unique_id = 0x7075901; | ||
1477 | _ctl_diag_register_2(ioc, &diag_register); | ||
1478 | } | ||
1479 | } | ||
1480 | |||
1481 | /** | ||
1482 | * _ctl_diag_register - application register with driver | ||
1483 | * @arg - user space buffer containing ioctl content | ||
1484 | * @state - NON_BLOCKING or BLOCKING | ||
1485 | * | ||
1486 | * This will allow the driver to setup any required buffers that will be | ||
1487 | * needed by firmware to communicate with the driver. | ||
1488 | */ | ||
1489 | static long | ||
1490 | _ctl_diag_register(void __user *arg, enum block_state state) | ||
1491 | { | ||
1492 | struct mpt2_diag_register karg; | ||
1493 | struct MPT2SAS_ADAPTER *ioc; | ||
1494 | long rc; | ||
1495 | |||
1496 | if (copy_from_user(&karg, arg, sizeof(karg))) { | ||
1497 | printk(KERN_ERR "failure at %s:%d/%s()!\n", | ||
1498 | __FILE__, __LINE__, __func__); | ||
1499 | return -EFAULT; | ||
1500 | } | ||
1501 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1502 | return -ENODEV; | ||
1503 | |||
1504 | if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) | ||
1505 | return -EAGAIN; | ||
1506 | else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) | ||
1507 | return -ERESTARTSYS; | ||
1508 | rc = _ctl_diag_register_2(ioc, &karg); | ||
1441 | mutex_unlock(&ioc->ctl_cmds.mutex); | 1509 | mutex_unlock(&ioc->ctl_cmds.mutex); |
1442 | return rc; | 1510 | return rc; |
1443 | } | 1511 | } |
@@ -1600,7 +1668,7 @@ _ctl_diag_query(void __user *arg) | |||
1600 | /** | 1668 | /** |
1601 | * _ctl_send_release - Diag Release Message | 1669 | * _ctl_send_release - Diag Release Message |
1602 | * @ioc: per adapter object | 1670 | * @ioc: per adapter object |
1603 | * @buffer_type - specifies either TRACE or SNAPSHOT | 1671 | * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED |
1604 | * @issue_reset - specifies whether host reset is required. | 1672 | * @issue_reset - specifies whether host reset is required. |
1605 | * | 1673 | * |
1606 | */ | 1674 | */ |
@@ -1690,7 +1758,7 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset) | |||
1690 | } else { | 1758 | } else { |
1691 | printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " | 1759 | printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " |
1692 | "log_info(0x%08x)\n", ioc->name, __func__, | 1760 | "log_info(0x%08x)\n", ioc->name, __func__, |
1693 | ioc_status, mpi_reply->IOCLogInfo); | 1761 | ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); |
1694 | rc = -EFAULT; | 1762 | rc = -EFAULT; |
1695 | } | 1763 | } |
1696 | 1764 | ||
@@ -1951,7 +2019,7 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) | |||
1951 | } else { | 2019 | } else { |
1952 | printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " | 2020 | printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " |
1953 | "log_info(0x%08x)\n", ioc->name, __func__, | 2021 | "log_info(0x%08x)\n", ioc->name, __func__, |
1954 | ioc_status, mpi_reply->IOCLogInfo); | 2022 | ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); |
1955 | rc = -EFAULT; | 2023 | rc = -EFAULT; |
1956 | } | 2024 | } |
1957 | 2025 | ||
@@ -2135,14 +2203,10 @@ _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg) | |||
2135 | karg.data_out_size = karg32.data_out_size; | 2203 | karg.data_out_size = karg32.data_out_size; |
2136 | karg.max_sense_bytes = karg32.max_sense_bytes; | 2204 | karg.max_sense_bytes = karg32.max_sense_bytes; |
2137 | karg.data_sge_offset = karg32.data_sge_offset; | 2205 | karg.data_sge_offset = karg32.data_sge_offset; |
2138 | memcpy(&karg.reply_frame_buf_ptr, &karg32.reply_frame_buf_ptr, | 2206 | karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr); |
2139 | sizeof(uint32_t)); | 2207 | karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr); |
2140 | memcpy(&karg.data_in_buf_ptr, &karg32.data_in_buf_ptr, | 2208 | karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr); |
2141 | sizeof(uint32_t)); | 2209 | karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr); |
2142 | memcpy(&karg.data_out_buf_ptr, &karg32.data_out_buf_ptr, | ||
2143 | sizeof(uint32_t)); | ||
2144 | memcpy(&karg.sense_data_ptr, &karg32.sense_data_ptr, | ||
2145 | sizeof(uint32_t)); | ||
2146 | state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; | 2210 | state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; |
2147 | return _ctl_do_mpt_command(ioc, karg, &uarg->mf, state); | 2211 | return _ctl_do_mpt_command(ioc, karg, &uarg->mf, state); |
2148 | } | 2212 | } |
@@ -2474,6 +2538,43 @@ _ctl_logging_level_store(struct device *cdev, struct device_attribute *attr, | |||
2474 | static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR, | 2538 | static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR, |
2475 | _ctl_logging_level_show, _ctl_logging_level_store); | 2539 | _ctl_logging_level_show, _ctl_logging_level_store); |
2476 | 2540 | ||
2541 | /* device attributes */ | ||
2542 | /* | ||
2543 | * _ctl_fwfault_debug_show - show/store fwfault_debug | ||
2544 | * @cdev - pointer to embedded class device | ||
2545 | * @buf - the buffer returned | ||
2546 | * | ||
2547 | * mpt2sas_fwfault_debug is command line option | ||
2548 | * A sysfs 'read/write' shost attribute. | ||
2549 | */ | ||
2550 | static ssize_t | ||
2551 | _ctl_fwfault_debug_show(struct device *cdev, | ||
2552 | struct device_attribute *attr, char *buf) | ||
2553 | { | ||
2554 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
2555 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); | ||
2556 | |||
2557 | return snprintf(buf, PAGE_SIZE, "%d\n", ioc->fwfault_debug); | ||
2558 | } | ||
2559 | static ssize_t | ||
2560 | _ctl_fwfault_debug_store(struct device *cdev, | ||
2561 | struct device_attribute *attr, const char *buf, size_t count) | ||
2562 | { | ||
2563 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
2564 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); | ||
2565 | int val = 0; | ||
2566 | |||
2567 | if (sscanf(buf, "%d", &val) != 1) | ||
2568 | return -EINVAL; | ||
2569 | |||
2570 | ioc->fwfault_debug = val; | ||
2571 | printk(MPT2SAS_INFO_FMT "fwfault_debug=%d\n", ioc->name, | ||
2572 | ioc->fwfault_debug); | ||
2573 | return strlen(buf); | ||
2574 | } | ||
2575 | static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR, | ||
2576 | _ctl_fwfault_debug_show, _ctl_fwfault_debug_store); | ||
2577 | |||
2477 | struct device_attribute *mpt2sas_host_attrs[] = { | 2578 | struct device_attribute *mpt2sas_host_attrs[] = { |
2478 | &dev_attr_version_fw, | 2579 | &dev_attr_version_fw, |
2479 | &dev_attr_version_bios, | 2580 | &dev_attr_version_bios, |
@@ -2487,13 +2588,12 @@ struct device_attribute *mpt2sas_host_attrs[] = { | |||
2487 | &dev_attr_io_delay, | 2588 | &dev_attr_io_delay, |
2488 | &dev_attr_device_delay, | 2589 | &dev_attr_device_delay, |
2489 | &dev_attr_logging_level, | 2590 | &dev_attr_logging_level, |
2591 | &dev_attr_fwfault_debug, | ||
2490 | &dev_attr_fw_queue_depth, | 2592 | &dev_attr_fw_queue_depth, |
2491 | &dev_attr_host_sas_address, | 2593 | &dev_attr_host_sas_address, |
2492 | NULL, | 2594 | NULL, |
2493 | }; | 2595 | }; |
2494 | 2596 | ||
2495 | /* device attributes */ | ||
2496 | |||
2497 | /** | 2597 | /** |
2498 | * _ctl_device_sas_address_show - sas address | 2598 | * _ctl_device_sas_address_show - sas address |
2499 | * @cdev - pointer to embedded class device | 2599 | * @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..be171ed682e0 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -52,6 +52,8 @@ | |||
52 | #include <linux/delay.h> | 52 | #include <linux/delay.h> |
53 | #include <linux/pci.h> | 53 | #include <linux/pci.h> |
54 | #include <linux/interrupt.h> | 54 | #include <linux/interrupt.h> |
55 | #include <linux/raid_class.h> | ||
56 | #include <linux/slab.h> | ||
55 | 57 | ||
56 | #include "mpt2sas_base.h" | 58 | #include "mpt2sas_base.h" |
57 | 59 | ||
@@ -76,6 +78,7 @@ static u8 tm_cb_idx = -1; | |||
76 | static u8 ctl_cb_idx = -1; | 78 | static u8 ctl_cb_idx = -1; |
77 | static u8 base_cb_idx = -1; | 79 | static u8 base_cb_idx = -1; |
78 | static u8 transport_cb_idx = -1; | 80 | static u8 transport_cb_idx = -1; |
81 | static u8 scsih_cb_idx = -1; | ||
79 | static u8 config_cb_idx = -1; | 82 | static u8 config_cb_idx = -1; |
80 | static int mpt_ids; | 83 | static int mpt_ids; |
81 | 84 | ||
@@ -132,6 +135,9 @@ struct fw_event_work { | |||
132 | void *event_data; | 135 | void *event_data; |
133 | }; | 136 | }; |
134 | 137 | ||
138 | /* raid transport support */ | ||
139 | static struct raid_template *mpt2sas_raid_template; | ||
140 | |||
135 | /** | 141 | /** |
136 | * struct _scsi_io_transfer - scsi io transfer | 142 | * struct _scsi_io_transfer - scsi io transfer |
137 | * @handle: sas device handle (assigned by firmware) | 143 | * @handle: sas device handle (assigned by firmware) |
@@ -196,10 +202,28 @@ static struct pci_device_id scsih_pci_table[] = { | |||
196 | PCI_ANY_ID, PCI_ANY_ID }, | 202 | PCI_ANY_ID, PCI_ANY_ID }, |
197 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3, | 203 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3, |
198 | PCI_ANY_ID, PCI_ANY_ID }, | 204 | PCI_ANY_ID, PCI_ANY_ID }, |
205 | /* Meteor ~ 2116 */ | ||
199 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1, | 206 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1, |
200 | PCI_ANY_ID, PCI_ANY_ID }, | 207 | PCI_ANY_ID, PCI_ANY_ID }, |
201 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2, | 208 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2, |
202 | PCI_ANY_ID, PCI_ANY_ID }, | 209 | PCI_ANY_ID, PCI_ANY_ID }, |
210 | /* Thunderbolt ~ 2208 */ | ||
211 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1, | ||
212 | PCI_ANY_ID, PCI_ANY_ID }, | ||
213 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2, | ||
214 | PCI_ANY_ID, PCI_ANY_ID }, | ||
215 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3, | ||
216 | PCI_ANY_ID, PCI_ANY_ID }, | ||
217 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4, | ||
218 | PCI_ANY_ID, PCI_ANY_ID }, | ||
219 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5, | ||
220 | PCI_ANY_ID, PCI_ANY_ID }, | ||
221 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6, | ||
222 | PCI_ANY_ID, PCI_ANY_ID }, | ||
223 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_7, | ||
224 | PCI_ANY_ID, PCI_ANY_ID }, | ||
225 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_8, | ||
226 | PCI_ANY_ID, PCI_ANY_ID }, | ||
203 | {0} /* Terminating entry */ | 227 | {0} /* Terminating entry */ |
204 | }; | 228 | }; |
205 | MODULE_DEVICE_TABLE(pci, scsih_pci_table); | 229 | MODULE_DEVICE_TABLE(pci, scsih_pci_table); |
@@ -317,6 +341,47 @@ _scsih_is_boot_device(u64 sas_address, u64 device_name, | |||
317 | } | 341 | } |
318 | 342 | ||
319 | /** | 343 | /** |
344 | * _scsih_get_sas_address - set the sas_address for given device handle | ||
345 | * @handle: device handle | ||
346 | * @sas_address: sas address | ||
347 | * | ||
348 | * Returns 0 success, non-zero when failure | ||
349 | */ | ||
350 | static int | ||
351 | _scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle, | ||
352 | u64 *sas_address) | ||
353 | { | ||
354 | Mpi2SasDevicePage0_t sas_device_pg0; | ||
355 | Mpi2ConfigReply_t mpi_reply; | ||
356 | u32 ioc_status; | ||
357 | |||
358 | if (handle <= ioc->sas_hba.num_phys) { | ||
359 | *sas_address = ioc->sas_hba.sas_address; | ||
360 | return 0; | ||
361 | } else | ||
362 | *sas_address = 0; | ||
363 | |||
364 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, | ||
365 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { | ||
366 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
367 | ioc->name, __FILE__, __LINE__, __func__); | ||
368 | return -ENXIO; | ||
369 | } | ||
370 | |||
371 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
372 | MPI2_IOCSTATUS_MASK; | ||
373 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { | ||
374 | printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)" | ||
375 | "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status, | ||
376 | __FILE__, __LINE__, __func__); | ||
377 | return -EIO; | ||
378 | } | ||
379 | |||
380 | *sas_address = le64_to_cpu(sas_device_pg0.SASAddress); | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | /** | ||
320 | * _scsih_determine_boot_device - determine boot device. | 385 | * _scsih_determine_boot_device - determine boot device. |
321 | * @ioc: per adapter object | 386 | * @ioc: per adapter object |
322 | * @device: either sas_device or raid_device object | 387 | * @device: either sas_device or raid_device object |
@@ -510,8 +575,6 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc, | |||
510 | struct _sas_device *sas_device) | 575 | struct _sas_device *sas_device) |
511 | { | 576 | { |
512 | unsigned long flags; | 577 | unsigned long flags; |
513 | u16 handle, parent_handle; | ||
514 | u64 sas_address; | ||
515 | 578 | ||
516 | dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle" | 579 | dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle" |
517 | "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, | 580 | "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, |
@@ -521,10 +584,8 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc, | |||
521 | list_add_tail(&sas_device->list, &ioc->sas_device_list); | 584 | list_add_tail(&sas_device->list, &ioc->sas_device_list); |
522 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 585 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
523 | 586 | ||
524 | handle = sas_device->handle; | 587 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
525 | parent_handle = sas_device->parent_handle; | 588 | 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); | 589 | _scsih_sas_device_remove(ioc, sas_device); |
529 | } | 590 | } |
530 | 591 | ||
@@ -553,31 +614,6 @@ _scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc, | |||
553 | } | 614 | } |
554 | 615 | ||
555 | /** | 616 | /** |
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 | 617 | * _scsih_raid_device_find_by_id - raid device search |
582 | * @ioc: per adapter object | 618 | * @ioc: per adapter object |
583 | * @id: sas device target id | 619 | * @id: sas device target id |
@@ -699,6 +735,31 @@ _scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc, | |||
699 | } | 735 | } |
700 | 736 | ||
701 | /** | 737 | /** |
738 | * mpt2sas_scsih_expander_find_by_handle - expander device search | ||
739 | * @ioc: per adapter object | ||
740 | * @handle: expander handle (assigned by firmware) | ||
741 | * Context: Calling function should acquire ioc->sas_device_lock | ||
742 | * | ||
743 | * This searches for expander device based on handle, then returns the | ||
744 | * sas_node object. | ||
745 | */ | ||
746 | struct _sas_node * | ||
747 | mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) | ||
748 | { | ||
749 | struct _sas_node *sas_expander, *r; | ||
750 | |||
751 | r = NULL; | ||
752 | list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { | ||
753 | if (sas_expander->handle != handle) | ||
754 | continue; | ||
755 | r = sas_expander; | ||
756 | goto out; | ||
757 | } | ||
758 | out: | ||
759 | return r; | ||
760 | } | ||
761 | |||
762 | /** | ||
702 | * mpt2sas_scsih_expander_find_by_sas_address - expander device search | 763 | * mpt2sas_scsih_expander_find_by_sas_address - expander device search |
703 | * @ioc: per adapter object | 764 | * @ioc: per adapter object |
704 | * @sas_address: sas address | 765 | * @sas_address: sas address |
@@ -1043,17 +1104,46 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc, | |||
1043 | * _scsih_change_queue_depth - setting device queue depth | 1104 | * _scsih_change_queue_depth - setting device queue depth |
1044 | * @sdev: scsi device struct | 1105 | * @sdev: scsi device struct |
1045 | * @qdepth: requested queue depth | 1106 | * @qdepth: requested queue depth |
1107 | * @reason: calling context | ||
1046 | * | 1108 | * |
1047 | * Returns queue depth. | 1109 | * Returns queue depth. |
1048 | */ | 1110 | */ |
1049 | static int | 1111 | static int |
1050 | _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | 1112 | _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) |
1051 | { | 1113 | { |
1052 | struct Scsi_Host *shost = sdev->host; | 1114 | struct Scsi_Host *shost = sdev->host; |
1053 | int max_depth; | 1115 | int max_depth; |
1054 | int tag_type; | 1116 | int tag_type; |
1117 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); | ||
1118 | struct MPT2SAS_DEVICE *sas_device_priv_data; | ||
1119 | struct MPT2SAS_TARGET *sas_target_priv_data; | ||
1120 | struct _sas_device *sas_device; | ||
1121 | unsigned long flags; | ||
1122 | |||
1123 | if (reason != SCSI_QDEPTH_DEFAULT) | ||
1124 | return -EOPNOTSUPP; | ||
1055 | 1125 | ||
1056 | max_depth = shost->can_queue; | 1126 | max_depth = shost->can_queue; |
1127 | |||
1128 | /* limit max device queue for SATA to 32 */ | ||
1129 | sas_device_priv_data = sdev->hostdata; | ||
1130 | if (!sas_device_priv_data) | ||
1131 | goto not_sata; | ||
1132 | sas_target_priv_data = sas_device_priv_data->sas_target; | ||
1133 | if (!sas_target_priv_data) | ||
1134 | goto not_sata; | ||
1135 | if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) | ||
1136 | goto not_sata; | ||
1137 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
1138 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | ||
1139 | sas_device_priv_data->sas_target->sas_address); | ||
1140 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
1141 | if (sas_device && sas_device->device_info & | ||
1142 | MPI2_SAS_DEVICE_INFO_SATA_DEVICE) | ||
1143 | max_depth = MPT2SAS_SATA_QUEUE_DEPTH; | ||
1144 | |||
1145 | not_sata: | ||
1146 | |||
1057 | if (!sdev->tagged_supported) | 1147 | if (!sdev->tagged_supported) |
1058 | max_depth = 1; | 1148 | max_depth = 1; |
1059 | if (qdepth > max_depth) | 1149 | if (qdepth > max_depth) |
@@ -1220,7 +1310,6 @@ _scsih_slave_alloc(struct scsi_device *sdev) | |||
1220 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 1310 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
1221 | struct scsi_target *starget; | 1311 | struct scsi_target *starget; |
1222 | struct _raid_device *raid_device; | 1312 | struct _raid_device *raid_device; |
1223 | struct _sas_device *sas_device; | ||
1224 | unsigned long flags; | 1313 | unsigned long flags; |
1225 | 1314 | ||
1226 | sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); | 1315 | sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); |
@@ -1247,21 +1336,8 @@ _scsih_slave_alloc(struct scsi_device *sdev) | |||
1247 | if (raid_device) | 1336 | if (raid_device) |
1248 | raid_device->sdev = sdev; /* raid is single lun */ | 1337 | raid_device->sdev = sdev; /* raid is single lun */ |
1249 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 1338 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
1250 | } else { | ||
1251 | /* set TLR bit for SSP devices */ | ||
1252 | if (!(ioc->facts.IOCCapabilities & | ||
1253 | MPI2_IOCFACTS_CAPABILITY_TLR)) | ||
1254 | goto out; | ||
1255 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
1256 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | ||
1257 | sas_device_priv_data->sas_target->sas_address); | ||
1258 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
1259 | if (sas_device && sas_device->device_info & | ||
1260 | MPI2_SAS_DEVICE_INFO_SSP_TARGET) | ||
1261 | sas_device_priv_data->flags |= MPT_DEVICE_TLR_ON; | ||
1262 | } | 1339 | } |
1263 | 1340 | ||
1264 | out: | ||
1265 | return 0; | 1341 | return 0; |
1266 | } | 1342 | } |
1267 | 1343 | ||
@@ -1334,6 +1410,140 @@ _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc, | |||
1334 | } | 1410 | } |
1335 | 1411 | ||
1336 | /** | 1412 | /** |
1413 | * _scsih_is_raid - return boolean indicating device is raid volume | ||
1414 | * @dev the device struct object | ||
1415 | */ | ||
1416 | static int | ||
1417 | _scsih_is_raid(struct device *dev) | ||
1418 | { | ||
1419 | struct scsi_device *sdev = to_scsi_device(dev); | ||
1420 | |||
1421 | return (sdev->channel == RAID_CHANNEL) ? 1 : 0; | ||
1422 | } | ||
1423 | |||
1424 | /** | ||
1425 | * _scsih_get_resync - get raid volume resync percent complete | ||
1426 | * @dev the device struct object | ||
1427 | */ | ||
1428 | static void | ||
1429 | _scsih_get_resync(struct device *dev) | ||
1430 | { | ||
1431 | struct scsi_device *sdev = to_scsi_device(dev); | ||
1432 | struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host); | ||
1433 | static struct _raid_device *raid_device; | ||
1434 | unsigned long flags; | ||
1435 | Mpi2RaidVolPage0_t vol_pg0; | ||
1436 | Mpi2ConfigReply_t mpi_reply; | ||
1437 | u32 volume_status_flags; | ||
1438 | u8 percent_complete = 0; | ||
1439 | |||
1440 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | ||
1441 | raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, | ||
1442 | sdev->channel); | ||
1443 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | ||
1444 | |||
1445 | if (!raid_device) | ||
1446 | goto out; | ||
1447 | |||
1448 | if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, | ||
1449 | MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, | ||
1450 | sizeof(Mpi2RaidVolPage0_t))) { | ||
1451 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1452 | ioc->name, __FILE__, __LINE__, __func__); | ||
1453 | goto out; | ||
1454 | } | ||
1455 | |||
1456 | volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags); | ||
1457 | if (volume_status_flags & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) | ||
1458 | percent_complete = raid_device->percent_complete; | ||
1459 | out: | ||
1460 | raid_set_resync(mpt2sas_raid_template, dev, percent_complete); | ||
1461 | } | ||
1462 | |||
1463 | /** | ||
1464 | * _scsih_get_state - get raid volume level | ||
1465 | * @dev the device struct object | ||
1466 | */ | ||
1467 | static void | ||
1468 | _scsih_get_state(struct device *dev) | ||
1469 | { | ||
1470 | struct scsi_device *sdev = to_scsi_device(dev); | ||
1471 | struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host); | ||
1472 | static struct _raid_device *raid_device; | ||
1473 | unsigned long flags; | ||
1474 | Mpi2RaidVolPage0_t vol_pg0; | ||
1475 | Mpi2ConfigReply_t mpi_reply; | ||
1476 | u32 volstate; | ||
1477 | enum raid_state state = RAID_STATE_UNKNOWN; | ||
1478 | |||
1479 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | ||
1480 | raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, | ||
1481 | sdev->channel); | ||
1482 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | ||
1483 | |||
1484 | if (!raid_device) | ||
1485 | goto out; | ||
1486 | |||
1487 | if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, | ||
1488 | MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, | ||
1489 | sizeof(Mpi2RaidVolPage0_t))) { | ||
1490 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1491 | ioc->name, __FILE__, __LINE__, __func__); | ||
1492 | goto out; | ||
1493 | } | ||
1494 | |||
1495 | volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags); | ||
1496 | if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) { | ||
1497 | state = RAID_STATE_RESYNCING; | ||
1498 | goto out; | ||
1499 | } | ||
1500 | |||
1501 | switch (vol_pg0.VolumeState) { | ||
1502 | case MPI2_RAID_VOL_STATE_OPTIMAL: | ||
1503 | case MPI2_RAID_VOL_STATE_ONLINE: | ||
1504 | state = RAID_STATE_ACTIVE; | ||
1505 | break; | ||
1506 | case MPI2_RAID_VOL_STATE_DEGRADED: | ||
1507 | state = RAID_STATE_DEGRADED; | ||
1508 | break; | ||
1509 | case MPI2_RAID_VOL_STATE_FAILED: | ||
1510 | case MPI2_RAID_VOL_STATE_MISSING: | ||
1511 | state = RAID_STATE_OFFLINE; | ||
1512 | break; | ||
1513 | } | ||
1514 | out: | ||
1515 | raid_set_state(mpt2sas_raid_template, dev, state); | ||
1516 | } | ||
1517 | |||
1518 | /** | ||
1519 | * _scsih_set_level - set raid level | ||
1520 | * @sdev: scsi device struct | ||
1521 | * @raid_device: raid_device object | ||
1522 | */ | ||
1523 | static void | ||
1524 | _scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device) | ||
1525 | { | ||
1526 | enum raid_level level = RAID_LEVEL_UNKNOWN; | ||
1527 | |||
1528 | switch (raid_device->volume_type) { | ||
1529 | case MPI2_RAID_VOL_TYPE_RAID0: | ||
1530 | level = RAID_LEVEL_0; | ||
1531 | break; | ||
1532 | case MPI2_RAID_VOL_TYPE_RAID10: | ||
1533 | level = RAID_LEVEL_10; | ||
1534 | break; | ||
1535 | case MPI2_RAID_VOL_TYPE_RAID1E: | ||
1536 | level = RAID_LEVEL_1E; | ||
1537 | break; | ||
1538 | case MPI2_RAID_VOL_TYPE_RAID1: | ||
1539 | level = RAID_LEVEL_1; | ||
1540 | break; | ||
1541 | } | ||
1542 | |||
1543 | raid_set_level(mpt2sas_raid_template, &sdev->sdev_gendev, level); | ||
1544 | } | ||
1545 | |||
1546 | /** | ||
1337 | * _scsih_get_volume_capabilities - volume capabilities | 1547 | * _scsih_get_volume_capabilities - volume capabilities |
1338 | * @ioc: per adapter object | 1548 | * @ioc: per adapter object |
1339 | * @sas_device: the raid_device object | 1549 | * @sas_device: the raid_device object |
@@ -1394,6 +1604,32 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc, | |||
1394 | } | 1604 | } |
1395 | 1605 | ||
1396 | /** | 1606 | /** |
1607 | * _scsih_enable_tlr - setting TLR flags | ||
1608 | * @ioc: per adapter object | ||
1609 | * @sdev: scsi device struct | ||
1610 | * | ||
1611 | * Enabling Transaction Layer Retries for tape devices when | ||
1612 | * vpd page 0x90 is present | ||
1613 | * | ||
1614 | */ | ||
1615 | static void | ||
1616 | _scsih_enable_tlr(struct MPT2SAS_ADAPTER *ioc, struct scsi_device *sdev) | ||
1617 | { | ||
1618 | /* only for TAPE */ | ||
1619 | if (sdev->type != TYPE_TAPE) | ||
1620 | return; | ||
1621 | |||
1622 | if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR)) | ||
1623 | return; | ||
1624 | |||
1625 | sas_enable_tlr(sdev); | ||
1626 | sdev_printk(KERN_INFO, sdev, "TLR %s\n", | ||
1627 | sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled"); | ||
1628 | return; | ||
1629 | |||
1630 | } | ||
1631 | |||
1632 | /** | ||
1397 | * _scsih_slave_configure - device configure routine. | 1633 | * _scsih_slave_configure - device configure routine. |
1398 | * @sdev: scsi device struct | 1634 | * @sdev: scsi device struct |
1399 | * | 1635 | * |
@@ -1488,7 +1724,9 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1488 | r_level, raid_device->handle, | 1724 | r_level, raid_device->handle, |
1489 | (unsigned long long)raid_device->wwid, | 1725 | (unsigned long long)raid_device->wwid, |
1490 | raid_device->num_pds, ds); | 1726 | raid_device->num_pds, ds); |
1491 | _scsih_change_queue_depth(sdev, qdepth); | 1727 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); |
1728 | /* raid transport support */ | ||
1729 | _scsih_set_level(sdev, raid_device); | ||
1492 | return 0; | 1730 | return 0; |
1493 | } | 1731 | } |
1494 | 1732 | ||
@@ -1534,10 +1772,12 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1534 | _scsih_display_sata_capabilities(ioc, sas_device, sdev); | 1772 | _scsih_display_sata_capabilities(ioc, sas_device, sdev); |
1535 | } | 1773 | } |
1536 | 1774 | ||
1537 | _scsih_change_queue_depth(sdev, qdepth); | 1775 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); |
1538 | 1776 | ||
1539 | if (ssp_target) | 1777 | if (ssp_target) { |
1540 | sas_read_port_mode_page(sdev); | 1778 | sas_read_port_mode_page(sdev); |
1779 | _scsih_enable_tlr(ioc, sdev); | ||
1780 | } | ||
1541 | return 0; | 1781 | return 0; |
1542 | } | 1782 | } |
1543 | 1783 | ||
@@ -1874,6 +2114,8 @@ _scsih_abort(struct scsi_cmnd *scmd) | |||
1874 | goto out; | 2114 | goto out; |
1875 | } | 2115 | } |
1876 | 2116 | ||
2117 | mpt2sas_halt_firmware(ioc); | ||
2118 | |||
1877 | mutex_lock(&ioc->tm_cmds.mutex); | 2119 | mutex_lock(&ioc->tm_cmds.mutex); |
1878 | handle = sas_device_priv_data->sas_target->handle; | 2120 | handle = sas_device_priv_data->sas_target->handle; |
1879 | mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun, | 2121 | mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun, |
@@ -2297,7 +2539,6 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc, | |||
2297 | u16 handle; | 2539 | u16 handle; |
2298 | u16 reason_code; | 2540 | u16 reason_code; |
2299 | u8 phy_number; | 2541 | u8 phy_number; |
2300 | u8 link_rate; | ||
2301 | 2542 | ||
2302 | for (i = 0; i < event_data->NumEntries; i++) { | 2543 | for (i = 0; i < event_data->NumEntries; i++) { |
2303 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); | 2544 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); |
@@ -2308,11 +2549,6 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc, | |||
2308 | MPI2_EVENT_SAS_TOPO_RC_MASK; | 2549 | MPI2_EVENT_SAS_TOPO_RC_MASK; |
2309 | if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING) | 2550 | if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING) |
2310 | _scsih_block_io_device(ioc, handle); | 2551 | _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 | } | 2552 | } |
2317 | } | 2553 | } |
2318 | 2554 | ||
@@ -2349,16 +2585,10 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
2349 | 2585 | ||
2350 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2586 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
2351 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 2587 | 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); | 2588 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
2359 | 2589 | ||
2360 | /* skip is hidden raid component */ | 2590 | /* skip is hidden raid component */ |
2361 | if (sas_device->hidden_raid_component) | 2591 | if (sas_device && sas_device->hidden_raid_component) |
2362 | return; | 2592 | return; |
2363 | 2593 | ||
2364 | smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); | 2594 | smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); |
@@ -2371,18 +2601,31 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
2371 | delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL; | 2601 | delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL; |
2372 | list_add_tail(&delayed_tr->list, | 2602 | list_add_tail(&delayed_tr->list, |
2373 | &ioc->delayed_tr_list); | 2603 | &ioc->delayed_tr_list); |
2374 | if (sas_device->starget) | 2604 | if (sas_device && sas_device->starget) { |
2375 | dewtprintk(ioc, starget_printk(KERN_INFO, | 2605 | dewtprintk(ioc, starget_printk(KERN_INFO, |
2376 | sas_device->starget, "DELAYED:tr:handle(0x%04x), " | 2606 | sas_device->starget, "DELAYED:tr:handle(0x%04x), " |
2377 | "(open)\n", sas_device->handle)); | 2607 | "(open)\n", handle)); |
2608 | } else { | ||
2609 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
2610 | "DELAYED:tr:handle(0x%04x), (open)\n", | ||
2611 | ioc->name, handle)); | ||
2612 | } | ||
2378 | return; | 2613 | return; |
2379 | } | 2614 | } |
2380 | 2615 | ||
2381 | if (sas_device->starget && sas_device->starget->hostdata) { | 2616 | if (sas_device) { |
2382 | sas_target_priv_data = sas_device->starget->hostdata; | 2617 | sas_device->state |= MPTSAS_STATE_TR_SEND; |
2383 | sas_target_priv_data->tm_busy = 1; | 2618 | sas_device->state |= MPT2SAS_REQ_SAS_CNTRL; |
2384 | dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, | 2619 | if (sas_device->starget && sas_device->starget->hostdata) { |
2385 | "tr:handle(0x%04x), (open)\n", sas_device->handle)); | 2620 | sas_target_priv_data = sas_device->starget->hostdata; |
2621 | sas_target_priv_data->tm_busy = 1; | ||
2622 | dewtprintk(ioc, starget_printk(KERN_INFO, | ||
2623 | sas_device->starget, "tr:handle(0x%04x), (open)\n", | ||
2624 | handle)); | ||
2625 | } | ||
2626 | } else { | ||
2627 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
2628 | "tr:handle(0x%04x), (open)\n", ioc->name, handle)); | ||
2386 | } | 2629 | } |
2387 | 2630 | ||
2388 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); | 2631 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); |
@@ -2390,8 +2633,6 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
2390 | mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; | 2633 | mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; |
2391 | mpi_request->DevHandle = cpu_to_le16(handle); | 2634 | mpi_request->DevHandle = cpu_to_le16(handle); |
2392 | mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; | 2635 | 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); | 2636 | mpt2sas_base_put_smid_hi_priority(ioc, smid); |
2396 | } | 2637 | } |
2397 | 2638 | ||
@@ -2426,21 +2667,25 @@ _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, | |||
2426 | 2667 | ||
2427 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2668 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
2428 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 2669 | 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); | 2670 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
2437 | 2671 | ||
2438 | if (sas_device->starget) | 2672 | if (sas_device) { |
2439 | dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, | 2673 | sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE; |
2674 | if (sas_device->starget) | ||
2675 | dewtprintk(ioc, starget_printk(KERN_INFO, | ||
2676 | sas_device->starget, | ||
2677 | "sc_complete:handle(0x%04x), " | ||
2678 | "ioc_status(0x%04x), loginfo(0x%08x)\n", | ||
2679 | handle, le16_to_cpu(mpi_reply->IOCStatus), | ||
2680 | le32_to_cpu(mpi_reply->IOCLogInfo))); | ||
2681 | } else { | ||
2682 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
2440 | "sc_complete:handle(0x%04x), " | 2683 | "sc_complete:handle(0x%04x), " |
2441 | "ioc_status(0x%04x), loginfo(0x%08x)\n", | 2684 | "ioc_status(0x%04x), loginfo(0x%08x)\n", |
2442 | handle, le16_to_cpu(mpi_reply->IOCStatus), | 2685 | ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus), |
2443 | le32_to_cpu(mpi_reply->IOCLogInfo))); | 2686 | le32_to_cpu(mpi_reply->IOCLogInfo))); |
2687 | } | ||
2688 | |||
2444 | return 1; | 2689 | return 1; |
2445 | } | 2690 | } |
2446 | 2691 | ||
@@ -2478,28 +2723,33 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
2478 | handle = le16_to_cpu(mpi_reply->DevHandle); | 2723 | handle = le16_to_cpu(mpi_reply->DevHandle); |
2479 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2724 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
2480 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 2725 | 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); | 2726 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
2489 | 2727 | ||
2490 | if (sas_device->starget) | 2728 | if (sas_device) { |
2491 | dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, | 2729 | sas_device->state |= MPTSAS_STATE_TR_COMPLETE; |
2492 | "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), " | 2730 | if (sas_device->starget) { |
2493 | "loginfo(0x%08x), completed(%d)\n", | 2731 | dewtprintk(ioc, starget_printk(KERN_INFO, |
2494 | sas_device->handle, (sas_device->state & | 2732 | sas_device->starget, "tr_complete:handle(0x%04x), " |
2495 | MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active", | 2733 | "(%s) ioc_status(0x%04x), loginfo(0x%08x), " |
2496 | le16_to_cpu(mpi_reply->IOCStatus), | 2734 | "completed(%d)\n", sas_device->handle, |
2735 | (sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ? | ||
2736 | "open" : "active", | ||
2737 | le16_to_cpu(mpi_reply->IOCStatus), | ||
2738 | le32_to_cpu(mpi_reply->IOCLogInfo), | ||
2739 | le32_to_cpu(mpi_reply->TerminationCount))); | ||
2740 | if (sas_device->starget->hostdata) { | ||
2741 | sas_target_priv_data = | ||
2742 | sas_device->starget->hostdata; | ||
2743 | sas_target_priv_data->tm_busy = 0; | ||
2744 | } | ||
2745 | } | ||
2746 | } else { | ||
2747 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
2748 | "tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), " | ||
2749 | "loginfo(0x%08x), completed(%d)\n", ioc->name, | ||
2750 | handle, le16_to_cpu(mpi_reply->IOCStatus), | ||
2497 | le32_to_cpu(mpi_reply->IOCLogInfo), | 2751 | le32_to_cpu(mpi_reply->IOCLogInfo), |
2498 | le32_to_cpu(mpi_reply->TerminationCount))); | 2752 | 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 | } | 2753 | } |
2504 | 2754 | ||
2505 | if (!list_empty(&ioc->delayed_tr_list)) { | 2755 | if (!list_empty(&ioc->delayed_tr_list)) { |
@@ -2514,8 +2764,7 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
2514 | } else | 2764 | } else |
2515 | rc = 1; | 2765 | rc = 1; |
2516 | 2766 | ||
2517 | 2767 | if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL)) | |
2518 | if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL)) | ||
2519 | return rc; | 2768 | return rc; |
2520 | 2769 | ||
2521 | if (ioc->shost_recovery) { | 2770 | if (ioc->shost_recovery) { |
@@ -2531,12 +2780,14 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
2531 | return rc; | 2780 | return rc; |
2532 | } | 2781 | } |
2533 | 2782 | ||
2783 | if (sas_device) | ||
2784 | sas_device->state |= MPTSAS_STATE_CNTRL_SEND; | ||
2785 | |||
2534 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); | 2786 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); |
2535 | memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); | 2787 | memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); |
2536 | mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; | 2788 | mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; |
2537 | mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; | 2789 | mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; |
2538 | mpi_request->DevHandle = mpi_reply->DevHandle; | 2790 | mpi_request->DevHandle = mpi_reply->DevHandle; |
2539 | sas_device->state |= MPTSAS_STATE_CNTRL_SEND; | ||
2540 | mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); | 2791 | mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); |
2541 | return rc; | 2792 | return rc; |
2542 | } | 2793 | } |
@@ -2678,8 +2929,6 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request) | |||
2678 | else | 2929 | else |
2679 | return; | 2930 | return; |
2680 | 2931 | ||
2681 | mpi_request->EEDPBlockSize = scmd->device->sector_size; | ||
2682 | |||
2683 | switch (prot_type) { | 2932 | switch (prot_type) { |
2684 | case SCSI_PROT_DIF_TYPE1: | 2933 | case SCSI_PROT_DIF_TYPE1: |
2685 | 2934 | ||
@@ -2687,8 +2936,7 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request) | |||
2687 | * enable ref/guard checking | 2936 | * enable ref/guard checking |
2688 | * auto increment ref tag | 2937 | * auto increment ref tag |
2689 | */ | 2938 | */ |
2690 | mpi_request->EEDPFlags = eedp_flags | | 2939 | eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG | |
2691 | MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG | | ||
2692 | MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | | 2940 | MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | |
2693 | MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; | 2941 | MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; |
2694 | mpi_request->CDB.EEDP32.PrimaryReferenceTag = | 2942 | mpi_request->CDB.EEDP32.PrimaryReferenceTag = |
@@ -2701,11 +2949,11 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request) | |||
2701 | /* | 2949 | /* |
2702 | * enable guard checking | 2950 | * enable guard checking |
2703 | */ | 2951 | */ |
2704 | mpi_request->EEDPFlags = eedp_flags | | 2952 | eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; |
2705 | MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; | ||
2706 | |||
2707 | break; | 2953 | break; |
2708 | } | 2954 | } |
2955 | mpi_request->EEDPBlockSize = cpu_to_le32(scmd->device->sector_size); | ||
2956 | mpi_request->EEDPFlags = cpu_to_le16(eedp_flags); | ||
2709 | } | 2957 | } |
2710 | 2958 | ||
2711 | /** | 2959 | /** |
@@ -2788,7 +3036,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | |||
2788 | } | 3036 | } |
2789 | 3037 | ||
2790 | /* see if we are busy with task managment stuff */ | 3038 | /* see if we are busy with task managment stuff */ |
2791 | if (sas_target_priv_data->tm_busy) | 3039 | if (sas_device_priv_data->block || sas_target_priv_data->tm_busy) |
2792 | return SCSI_MLQUEUE_DEVICE_BUSY; | 3040 | return SCSI_MLQUEUE_DEVICE_BUSY; |
2793 | else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress) | 3041 | else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress) |
2794 | return SCSI_MLQUEUE_HOST_BUSY; | 3042 | return SCSI_MLQUEUE_HOST_BUSY; |
@@ -2815,8 +3063,9 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | |||
2815 | 3063 | ||
2816 | } else | 3064 | } else |
2817 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; | 3065 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; |
2818 | 3066 | /* Make sure Device is not raid volume */ | |
2819 | if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON)) | 3067 | if (!_scsih_is_raid(&scmd->device->sdev_gendev) && |
3068 | sas_is_tlr_enabled(scmd->device)) | ||
2820 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; | 3069 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; |
2821 | 3070 | ||
2822 | smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd); | 3071 | smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd); |
@@ -2842,7 +3091,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | |||
2842 | mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR; | 3091 | mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR; |
2843 | mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; | 3092 | mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; |
2844 | mpi_request->SenseBufferLowAddress = | 3093 | mpi_request->SenseBufferLowAddress = |
2845 | (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid); | 3094 | mpt2sas_base_get_sense_buffer_dma(ioc, smid); |
2846 | mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4; | 3095 | mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4; |
2847 | mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI + | 3096 | mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI + |
2848 | MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR); | 3097 | MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR); |
@@ -2894,7 +3143,7 @@ _scsih_normalize_sense(char *sense_buffer, struct sense_info *data) | |||
2894 | 3143 | ||
2895 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 3144 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
2896 | /** | 3145 | /** |
2897 | * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request | 3146 | * _scsih_scsi_ioc_info - translated non-successfull SCSI_IO request |
2898 | * @ioc: per adapter object | 3147 | * @ioc: per adapter object |
2899 | * @scmd: pointer to scsi command object | 3148 | * @scmd: pointer to scsi command object |
2900 | * @mpi_reply: reply mf payload returned from firmware | 3149 | * @mpi_reply: reply mf payload returned from firmware |
@@ -3059,7 +3308,7 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
3059 | if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { | 3308 | if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { |
3060 | response_info = le32_to_cpu(mpi_reply->ResponseInfo); | 3309 | response_info = le32_to_cpu(mpi_reply->ResponseInfo); |
3061 | response_bytes = (u8 *)&response_info; | 3310 | response_bytes = (u8 *)&response_info; |
3062 | _scsih_response_code(ioc, response_bytes[3]); | 3311 | _scsih_response_code(ioc, response_bytes[0]); |
3063 | } | 3312 | } |
3064 | } | 3313 | } |
3065 | #endif | 3314 | #endif |
@@ -3177,7 +3426,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3177 | u8 scsi_status; | 3426 | u8 scsi_status; |
3178 | u32 log_info; | 3427 | u32 log_info; |
3179 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 3428 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
3180 | u32 response_code; | 3429 | u32 response_code = 0; |
3181 | 3430 | ||
3182 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 3431 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
3183 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 3432 | scmd = _scsih_scsi_lookup_get(ioc, smid); |
@@ -3199,15 +3448,17 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3199 | } | 3448 | } |
3200 | 3449 | ||
3201 | /* turning off TLR */ | 3450 | /* turning off TLR */ |
3451 | scsi_state = mpi_reply->SCSIState; | ||
3452 | if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) | ||
3453 | response_code = | ||
3454 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; | ||
3202 | if (!sas_device_priv_data->tlr_snoop_check) { | 3455 | if (!sas_device_priv_data->tlr_snoop_check) { |
3203 | sas_device_priv_data->tlr_snoop_check++; | 3456 | sas_device_priv_data->tlr_snoop_check++; |
3204 | if (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) { | 3457 | if (!_scsih_is_raid(&scmd->device->sdev_gendev) && |
3205 | response_code = (le32_to_cpu(mpi_reply->ResponseInfo) | 3458 | sas_is_tlr_enabled(scmd->device) && |
3206 | >> 24); | 3459 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { |
3207 | if (response_code == | 3460 | sas_disable_tlr(scmd->device); |
3208 | MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) | 3461 | sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n"); |
3209 | sas_device_priv_data->flags &= | ||
3210 | ~MPT_DEVICE_TLR_ON; | ||
3211 | } | 3462 | } |
3212 | } | 3463 | } |
3213 | 3464 | ||
@@ -3219,7 +3470,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3219 | else | 3470 | else |
3220 | log_info = 0; | 3471 | log_info = 0; |
3221 | ioc_status &= MPI2_IOCSTATUS_MASK; | 3472 | ioc_status &= MPI2_IOCSTATUS_MASK; |
3222 | scsi_state = mpi_reply->SCSIState; | ||
3223 | scsi_status = mpi_reply->SCSIStatus; | 3473 | scsi_status = mpi_reply->SCSIStatus; |
3224 | 3474 | ||
3225 | if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 && | 3475 | if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 && |
@@ -3255,10 +3505,9 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3255 | 3505 | ||
3256 | case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: | 3506 | case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: |
3257 | if (sas_device_priv_data->block) { | 3507 | if (sas_device_priv_data->block) { |
3258 | scmd->result = (DID_BUS_BUSY << 16); | 3508 | scmd->result = DID_TRANSPORT_DISRUPTED << 16; |
3259 | break; | 3509 | goto out; |
3260 | } | 3510 | } |
3261 | |||
3262 | case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: | 3511 | case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: |
3263 | case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: | 3512 | case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: |
3264 | scmd->result = DID_RESET << 16; | 3513 | scmd->result = DID_RESET << 16; |
@@ -3304,8 +3553,10 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3304 | case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR: | 3553 | case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR: |
3305 | case MPI2_IOCSTATUS_SUCCESS: | 3554 | case MPI2_IOCSTATUS_SUCCESS: |
3306 | scmd->result = (DID_OK << 16) | scsi_status; | 3555 | scmd->result = (DID_OK << 16) | scsi_status; |
3307 | if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED | | 3556 | if (response_code == |
3308 | MPI2_SCSI_STATE_NO_SCSI_STATUS)) | 3557 | MPI2_SCSITASKMGMT_RSP_INVALID_FRAME || |
3558 | (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED | | ||
3559 | MPI2_SCSI_STATE_NO_SCSI_STATUS))) | ||
3309 | scmd->result = DID_SOFT_ERROR << 16; | 3560 | scmd->result = DID_SOFT_ERROR << 16; |
3310 | else if (scsi_state & MPI2_SCSI_STATE_TERMINATED) | 3561 | else if (scsi_state & MPI2_SCSI_STATE_TERMINATED) |
3311 | scmd->result = DID_RESET << 16; | 3562 | scmd->result = DID_RESET << 16; |
@@ -3344,7 +3595,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3344 | /** | 3595 | /** |
3345 | * _scsih_sas_host_refresh - refreshing sas host object contents | 3596 | * _scsih_sas_host_refresh - refreshing sas host object contents |
3346 | * @ioc: per adapter object | 3597 | * @ioc: per adapter object |
3347 | * @update: update link information | ||
3348 | * Context: user | 3598 | * Context: user |
3349 | * | 3599 | * |
3350 | * During port enable, fw will send topology events for every device. Its | 3600 | * During port enable, fw will send topology events for every device. Its |
@@ -3354,13 +3604,14 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3354 | * Return nothing. | 3604 | * Return nothing. |
3355 | */ | 3605 | */ |
3356 | static void | 3606 | static void |
3357 | _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update) | 3607 | _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc) |
3358 | { | 3608 | { |
3359 | u16 sz; | 3609 | u16 sz; |
3360 | u16 ioc_status; | 3610 | u16 ioc_status; |
3361 | int i; | 3611 | int i; |
3362 | Mpi2ConfigReply_t mpi_reply; | 3612 | Mpi2ConfigReply_t mpi_reply; |
3363 | Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; | 3613 | Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; |
3614 | u16 attached_handle; | ||
3364 | 3615 | ||
3365 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT | 3616 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT |
3366 | "updating handles for sas_host(0x%016llx)\n", | 3617 | "updating handles for sas_host(0x%016llx)\n", |
@@ -3374,27 +3625,24 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update) | |||
3374 | ioc->name, __FILE__, __LINE__, __func__); | 3625 | ioc->name, __FILE__, __LINE__, __func__); |
3375 | return; | 3626 | return; |
3376 | } | 3627 | } |
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 | 3628 | ||
3629 | if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, | ||
3630 | sas_iounit_pg0, sz)) != 0) | ||
3631 | goto out; | ||
3632 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; | ||
3633 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) | ||
3634 | goto out; | ||
3635 | for (i = 0; i < ioc->sas_hba.num_phys ; i++) { | ||
3636 | if (i == 0) | ||
3637 | ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> | ||
3638 | PhyData[0].ControllerDevHandle); | ||
3639 | ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; | ||
3640 | attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i]. | ||
3641 | AttachedDevHandle); | ||
3642 | mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address, | ||
3643 | attached_handle, i, sas_iounit_pg0->PhyData[i]. | ||
3644 | NegotiatedLinkRate >> 4); | ||
3645 | } | ||
3398 | out: | 3646 | out: |
3399 | kfree(sas_iounit_pg0); | 3647 | kfree(sas_iounit_pg0); |
3400 | } | 3648 | } |
@@ -3507,19 +3755,21 @@ _scsih_sas_host_add(struct MPT2SAS_ADAPTER *ioc) | |||
3507 | ioc->name, __FILE__, __LINE__, __func__); | 3755 | ioc->name, __FILE__, __LINE__, __func__); |
3508 | goto out; | 3756 | goto out; |
3509 | } | 3757 | } |
3510 | ioc->sas_hba.phy[i].handle = | 3758 | |
3511 | le16_to_cpu(sas_iounit_pg0->PhyData[i].ControllerDevHandle); | 3759 | if (i == 0) |
3760 | ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> | ||
3761 | PhyData[0].ControllerDevHandle); | ||
3762 | ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; | ||
3512 | ioc->sas_hba.phy[i].phy_id = i; | 3763 | ioc->sas_hba.phy[i].phy_id = i; |
3513 | mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], | 3764 | mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], |
3514 | phy_pg0, ioc->sas_hba.parent_dev); | 3765 | phy_pg0, ioc->sas_hba.parent_dev); |
3515 | } | 3766 | } |
3516 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, | 3767 | 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))) { | 3768 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) { |
3518 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 3769 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
3519 | ioc->name, __FILE__, __LINE__, __func__); | 3770 | ioc->name, __FILE__, __LINE__, __func__); |
3520 | goto out; | 3771 | goto out; |
3521 | } | 3772 | } |
3522 | ioc->sas_hba.handle = le16_to_cpu(sas_device_pg0.DevHandle); | ||
3523 | ioc->sas_hba.enclosure_handle = | 3773 | ioc->sas_hba.enclosure_handle = |
3524 | le16_to_cpu(sas_device_pg0.EnclosureHandle); | 3774 | le16_to_cpu(sas_device_pg0.EnclosureHandle); |
3525 | ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress); | 3775 | ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress); |
@@ -3562,7 +3812,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3562 | Mpi2SasEnclosurePage0_t enclosure_pg0; | 3812 | Mpi2SasEnclosurePage0_t enclosure_pg0; |
3563 | u32 ioc_status; | 3813 | u32 ioc_status; |
3564 | u16 parent_handle; | 3814 | u16 parent_handle; |
3565 | __le64 sas_address; | 3815 | __le64 sas_address, sas_address_parent = 0; |
3566 | int i; | 3816 | int i; |
3567 | unsigned long flags; | 3817 | unsigned long flags; |
3568 | struct _sas_port *mpt2sas_port = NULL; | 3818 | struct _sas_port *mpt2sas_port = NULL; |
@@ -3591,10 +3841,16 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3591 | 3841 | ||
3592 | /* handle out of order topology events */ | 3842 | /* handle out of order topology events */ |
3593 | parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle); | 3843 | parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle); |
3594 | if (parent_handle >= ioc->sas_hba.num_phys) { | 3844 | if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent) |
3845 | != 0) { | ||
3846 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
3847 | ioc->name, __FILE__, __LINE__, __func__); | ||
3848 | return -1; | ||
3849 | } | ||
3850 | if (sas_address_parent != ioc->sas_hba.sas_address) { | ||
3595 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 3851 | spin_lock_irqsave(&ioc->sas_node_lock, flags); |
3596 | sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, | 3852 | sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, |
3597 | parent_handle); | 3853 | sas_address_parent); |
3598 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 3854 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
3599 | if (!sas_expander) { | 3855 | if (!sas_expander) { |
3600 | rc = _scsih_expander_add(ioc, parent_handle); | 3856 | rc = _scsih_expander_add(ioc, parent_handle); |
@@ -3622,14 +3878,12 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3622 | 3878 | ||
3623 | sas_expander->handle = handle; | 3879 | sas_expander->handle = handle; |
3624 | sas_expander->num_phys = expander_pg0.NumPhys; | 3880 | sas_expander->num_phys = expander_pg0.NumPhys; |
3625 | sas_expander->parent_handle = parent_handle; | 3881 | 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; | 3882 | sas_expander->sas_address = sas_address; |
3629 | 3883 | ||
3630 | printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x)," | 3884 | printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x)," |
3631 | " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name, | 3885 | " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name, |
3632 | handle, sas_expander->parent_handle, (unsigned long long) | 3886 | handle, parent_handle, (unsigned long long) |
3633 | sas_expander->sas_address, sas_expander->num_phys); | 3887 | sas_expander->sas_address, sas_expander->num_phys); |
3634 | 3888 | ||
3635 | if (!sas_expander->num_phys) | 3889 | if (!sas_expander->num_phys) |
@@ -3645,7 +3899,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3645 | 3899 | ||
3646 | INIT_LIST_HEAD(&sas_expander->sas_port_list); | 3900 | INIT_LIST_HEAD(&sas_expander->sas_port_list); |
3647 | mpt2sas_port = mpt2sas_transport_port_add(ioc, handle, | 3901 | mpt2sas_port = mpt2sas_transport_port_add(ioc, handle, |
3648 | sas_expander->parent_handle); | 3902 | sas_address_parent); |
3649 | if (!mpt2sas_port) { | 3903 | if (!mpt2sas_port) { |
3650 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 3904 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
3651 | ioc->name, __FILE__, __LINE__, __func__); | 3905 | ioc->name, __FILE__, __LINE__, __func__); |
@@ -3691,20 +3945,54 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3691 | 3945 | ||
3692 | if (mpt2sas_port) | 3946 | if (mpt2sas_port) |
3693 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, | 3947 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, |
3694 | sas_expander->parent_handle); | 3948 | sas_address_parent); |
3695 | kfree(sas_expander); | 3949 | kfree(sas_expander); |
3696 | return rc; | 3950 | return rc; |
3697 | } | 3951 | } |
3698 | 3952 | ||
3699 | /** | 3953 | /** |
3954 | * _scsih_done - scsih callback handler. | ||
3955 | * @ioc: per adapter object | ||
3956 | * @smid: system request message index | ||
3957 | * @msix_index: MSIX table index supplied by the OS | ||
3958 | * @reply: reply message frame(lower 32bit addr) | ||
3959 | * | ||
3960 | * Callback handler when sending internal generated message frames. | ||
3961 | * The callback index passed is `ioc->scsih_cb_idx` | ||
3962 | * | ||
3963 | * Return 1 meaning mf should be freed from _base_interrupt | ||
3964 | * 0 means the mf is freed from this function. | ||
3965 | */ | ||
3966 | static u8 | ||
3967 | _scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | ||
3968 | { | ||
3969 | MPI2DefaultReply_t *mpi_reply; | ||
3970 | |||
3971 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | ||
3972 | if (ioc->scsih_cmds.status == MPT2_CMD_NOT_USED) | ||
3973 | return 1; | ||
3974 | if (ioc->scsih_cmds.smid != smid) | ||
3975 | return 1; | ||
3976 | ioc->scsih_cmds.status |= MPT2_CMD_COMPLETE; | ||
3977 | if (mpi_reply) { | ||
3978 | memcpy(ioc->scsih_cmds.reply, mpi_reply, | ||
3979 | mpi_reply->MsgLength*4); | ||
3980 | ioc->scsih_cmds.status |= MPT2_CMD_REPLY_VALID; | ||
3981 | } | ||
3982 | ioc->scsih_cmds.status &= ~MPT2_CMD_PENDING; | ||
3983 | complete(&ioc->scsih_cmds.done); | ||
3984 | return 1; | ||
3985 | } | ||
3986 | |||
3987 | /** | ||
3700 | * _scsih_expander_remove - removing expander object | 3988 | * _scsih_expander_remove - removing expander object |
3701 | * @ioc: per adapter object | 3989 | * @ioc: per adapter object |
3702 | * @handle: expander handle | 3990 | * @sas_address: expander sas_address |
3703 | * | 3991 | * |
3704 | * Return nothing. | 3992 | * Return nothing. |
3705 | */ | 3993 | */ |
3706 | static void | 3994 | static void |
3707 | _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle) | 3995 | _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) |
3708 | { | 3996 | { |
3709 | struct _sas_node *sas_expander; | 3997 | struct _sas_node *sas_expander; |
3710 | unsigned long flags; | 3998 | unsigned long flags; |
@@ -3713,7 +4001,8 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3713 | return; | 4001 | return; |
3714 | 4002 | ||
3715 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 4003 | spin_lock_irqsave(&ioc->sas_node_lock, flags); |
3716 | sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle); | 4004 | sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, |
4005 | sas_address); | ||
3717 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 4006 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
3718 | _scsih_expander_node_remove(ioc, sas_expander); | 4007 | _scsih_expander_node_remove(ioc, sas_expander); |
3719 | } | 4008 | } |
@@ -3805,8 +4094,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) | |||
3805 | } | 4094 | } |
3806 | 4095 | ||
3807 | sas_device->handle = handle; | 4096 | sas_device->handle = handle; |
3808 | sas_device->parent_handle = | 4097 | if (_scsih_get_sas_address(ioc, le16_to_cpu |
3809 | le16_to_cpu(sas_device_pg0.ParentDevHandle); | 4098 | (sas_device_pg0.ParentDevHandle), |
4099 | &sas_device->sas_address_parent) != 0) | ||
4100 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
4101 | ioc->name, __FILE__, __LINE__, __func__); | ||
3810 | sas_device->enclosure_handle = | 4102 | sas_device->enclosure_handle = |
3811 | le16_to_cpu(sas_device_pg0.EnclosureHandle); | 4103 | le16_to_cpu(sas_device_pg0.EnclosureHandle); |
3812 | sas_device->slot = | 4104 | sas_device->slot = |
@@ -3836,43 +4128,39 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) | |||
3836 | /** | 4128 | /** |
3837 | * _scsih_remove_device - removing sas device object | 4129 | * _scsih_remove_device - removing sas device object |
3838 | * @ioc: per adapter object | 4130 | * @ioc: per adapter object |
3839 | * @handle: sas device handle | 4131 | * @sas_device: the sas_device object |
3840 | * | 4132 | * |
3841 | * Return nothing. | 4133 | * Return nothing. |
3842 | */ | 4134 | */ |
3843 | static void | 4135 | static void |
3844 | _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) | 4136 | _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device |
4137 | *sas_device) | ||
3845 | { | 4138 | { |
3846 | struct MPT2SAS_TARGET *sas_target_priv_data; | 4139 | struct MPT2SAS_TARGET *sas_target_priv_data; |
3847 | struct _sas_device *sas_device; | ||
3848 | unsigned long flags; | ||
3849 | Mpi2SasIoUnitControlReply_t mpi_reply; | 4140 | Mpi2SasIoUnitControlReply_t mpi_reply; |
3850 | Mpi2SasIoUnitControlRequest_t mpi_request; | 4141 | Mpi2SasIoUnitControlRequest_t mpi_request; |
3851 | u16 device_handle; | 4142 | u16 device_handle, handle; |
3852 | 4143 | ||
3853 | /* lookup sas_device */ | 4144 | 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; | 4145 | return; |
3859 | } | ||
3860 | 4146 | ||
3861 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle" | 4147 | handle = sas_device->handle; |
3862 | "(0x%04x)\n", ioc->name, __func__, handle)); | 4148 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x)," |
4149 | " sas_addr(0x%016llx)\n", ioc->name, __func__, handle, | ||
4150 | (unsigned long long) sas_device->sas_address)); | ||
3863 | 4151 | ||
3864 | if (sas_device->starget && sas_device->starget->hostdata) { | 4152 | if (sas_device->starget && sas_device->starget->hostdata) { |
3865 | sas_target_priv_data = sas_device->starget->hostdata; | 4153 | sas_target_priv_data = sas_device->starget->hostdata; |
3866 | sas_target_priv_data->deleted = 1; | 4154 | sas_target_priv_data->deleted = 1; |
3867 | } | 4155 | } |
3868 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
3869 | 4156 | ||
3870 | if (ioc->remove_host) | 4157 | if (ioc->remove_host || ioc->shost_recovery || !handle) |
3871 | goto out; | 4158 | goto out; |
3872 | 4159 | ||
3873 | if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { | 4160 | if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { |
3874 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " | 4161 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " |
3875 | "target_reset handle(0x%04x)\n", ioc->name, handle)); | 4162 | "target_reset handle(0x%04x)\n", ioc->name, |
4163 | handle)); | ||
3876 | goto skip_tr; | 4164 | goto skip_tr; |
3877 | } | 4165 | } |
3878 | 4166 | ||
@@ -3925,10 +4213,10 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3925 | _scsih_ublock_io_device(ioc, handle); | 4213 | _scsih_ublock_io_device(ioc, handle); |
3926 | 4214 | ||
3927 | mpt2sas_transport_port_remove(ioc, sas_device->sas_address, | 4215 | mpt2sas_transport_port_remove(ioc, sas_device->sas_address, |
3928 | sas_device->parent_handle); | 4216 | sas_device->sas_address_parent); |
3929 | 4217 | ||
3930 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" | 4218 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" |
3931 | "(0x%016llx)\n", ioc->name, sas_device->handle, | 4219 | "(0x%016llx)\n", ioc->name, handle, |
3932 | (unsigned long long) sas_device->sas_address); | 4220 | (unsigned long long) sas_device->sas_address); |
3933 | _scsih_sas_device_remove(ioc, sas_device); | 4221 | _scsih_sas_device_remove(ioc, sas_device); |
3934 | 4222 | ||
@@ -3952,7 +4240,7 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc, | |||
3952 | u16 reason_code; | 4240 | u16 reason_code; |
3953 | u8 phy_number; | 4241 | u8 phy_number; |
3954 | char *status_str = NULL; | 4242 | char *status_str = NULL; |
3955 | char link_rate[25]; | 4243 | u8 link_rate, prev_link_rate; |
3956 | 4244 | ||
3957 | switch (event_data->ExpStatus) { | 4245 | switch (event_data->ExpStatus) { |
3958 | case MPI2_EVENT_SAS_TOPO_ES_ADDED: | 4246 | case MPI2_EVENT_SAS_TOPO_ES_ADDED: |
@@ -3962,6 +4250,7 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc, | |||
3962 | status_str = "remove"; | 4250 | status_str = "remove"; |
3963 | break; | 4251 | break; |
3964 | case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: | 4252 | case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: |
4253 | case 0: | ||
3965 | status_str = "responding"; | 4254 | status_str = "responding"; |
3966 | break; | 4255 | break; |
3967 | case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: | 4256 | case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: |
@@ -3987,30 +4276,30 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc, | |||
3987 | MPI2_EVENT_SAS_TOPO_RC_MASK; | 4276 | MPI2_EVENT_SAS_TOPO_RC_MASK; |
3988 | switch (reason_code) { | 4277 | switch (reason_code) { |
3989 | case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: | 4278 | case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: |
3990 | snprintf(link_rate, 25, ": add, link(0x%02x)", | 4279 | status_str = "target add"; |
3991 | (event_data->PHY[i].LinkRate >> 4)); | ||
3992 | status_str = link_rate; | ||
3993 | break; | 4280 | break; |
3994 | case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: | 4281 | case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: |
3995 | status_str = ": remove"; | 4282 | status_str = "target remove"; |
3996 | break; | 4283 | break; |
3997 | case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: | 4284 | case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: |
3998 | status_str = ": remove_delay"; | 4285 | status_str = "delay target remove"; |
3999 | break; | 4286 | break; |
4000 | case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: | 4287 | case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: |
4001 | snprintf(link_rate, 25, ": link(0x%02x)", | 4288 | status_str = "link rate change"; |
4002 | (event_data->PHY[i].LinkRate >> 4)); | ||
4003 | status_str = link_rate; | ||
4004 | break; | 4289 | break; |
4005 | case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: | 4290 | case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: |
4006 | status_str = ": responding"; | 4291 | status_str = "target responding"; |
4007 | break; | 4292 | break; |
4008 | default: | 4293 | default: |
4009 | status_str = ": unknown"; | 4294 | status_str = "unknown"; |
4010 | break; | 4295 | break; |
4011 | } | 4296 | } |
4012 | printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x)%s\n", | 4297 | link_rate = event_data->PHY[i].LinkRate >> 4; |
4013 | phy_number, handle, status_str); | 4298 | prev_link_rate = event_data->PHY[i].LinkRate & 0xF; |
4299 | printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x): %s:" | ||
4300 | " link rate: new(0x%02x), old(0x%02x)\n", phy_number, | ||
4301 | handle, status_str, link_rate, prev_link_rate); | ||
4302 | |||
4014 | } | 4303 | } |
4015 | } | 4304 | } |
4016 | #endif | 4305 | #endif |
@@ -4031,8 +4320,10 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4031 | u16 reason_code; | 4320 | u16 reason_code; |
4032 | u8 phy_number; | 4321 | u8 phy_number; |
4033 | struct _sas_node *sas_expander; | 4322 | struct _sas_node *sas_expander; |
4323 | struct _sas_device *sas_device; | ||
4324 | u64 sas_address; | ||
4034 | unsigned long flags; | 4325 | unsigned long flags; |
4035 | u8 link_rate_; | 4326 | u8 link_rate, prev_link_rate; |
4036 | Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data; | 4327 | Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data; |
4037 | 4328 | ||
4038 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 4329 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
@@ -4040,10 +4331,13 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4040 | _scsih_sas_topology_change_event_debug(ioc, event_data); | 4331 | _scsih_sas_topology_change_event_debug(ioc, event_data); |
4041 | #endif | 4332 | #endif |
4042 | 4333 | ||
4334 | if (ioc->shost_recovery) | ||
4335 | return; | ||
4336 | |||
4043 | if (!ioc->sas_hba.num_phys) | 4337 | if (!ioc->sas_hba.num_phys) |
4044 | _scsih_sas_host_add(ioc); | 4338 | _scsih_sas_host_add(ioc); |
4045 | else | 4339 | else |
4046 | _scsih_sas_host_refresh(ioc, 0); | 4340 | _scsih_sas_host_refresh(ioc); |
4047 | 4341 | ||
4048 | if (fw_event->ignore) { | 4342 | if (fw_event->ignore) { |
4049 | dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander " | 4343 | dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander " |
@@ -4058,6 +4352,17 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4058 | if (_scsih_expander_add(ioc, parent_handle) != 0) | 4352 | if (_scsih_expander_add(ioc, parent_handle) != 0) |
4059 | return; | 4353 | return; |
4060 | 4354 | ||
4355 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | ||
4356 | sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, | ||
4357 | parent_handle); | ||
4358 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | ||
4359 | if (sas_expander) | ||
4360 | sas_address = sas_expander->sas_address; | ||
4361 | else if (parent_handle < ioc->sas_hba.num_phys) | ||
4362 | sas_address = ioc->sas_hba.sas_address; | ||
4363 | else | ||
4364 | return; | ||
4365 | |||
4061 | /* handle siblings events */ | 4366 | /* handle siblings events */ |
4062 | for (i = 0; i < event_data->NumEntries; i++) { | 4367 | for (i = 0; i < event_data->NumEntries; i++) { |
4063 | if (fw_event->ignore) { | 4368 | if (fw_event->ignore) { |
@@ -4077,48 +4382,47 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4077 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); | 4382 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); |
4078 | if (!handle) | 4383 | if (!handle) |
4079 | continue; | 4384 | continue; |
4080 | link_rate_ = event_data->PHY[i].LinkRate >> 4; | 4385 | link_rate = event_data->PHY[i].LinkRate >> 4; |
4386 | prev_link_rate = event_data->PHY[i].LinkRate & 0xF; | ||
4081 | switch (reason_code) { | 4387 | switch (reason_code) { |
4082 | case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: | 4388 | case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: |
4389 | |||
4390 | if (link_rate == prev_link_rate) | ||
4391 | break; | ||
4392 | |||
4393 | mpt2sas_transport_update_links(ioc, sas_address, | ||
4394 | handle, phy_number, link_rate); | ||
4395 | |||
4396 | if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5) | ||
4397 | _scsih_ublock_io_device(ioc, handle); | ||
4398 | break; | ||
4083 | case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: | 4399 | case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: |
4084 | if (!parent_handle) { | 4400 | |
4085 | if (phy_number < ioc->sas_hba.num_phys) | 4401 | mpt2sas_transport_update_links(ioc, sas_address, |
4086 | mpt2sas_transport_update_links( | 4402 | handle, phy_number, link_rate); |
4087 | ioc, | 4403 | |
4088 | ioc->sas_hba.phy[phy_number].handle, | 4404 | _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; | 4405 | break; |
4113 | case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: | 4406 | case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: |
4114 | _scsih_remove_device(ioc, handle); | 4407 | |
4408 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
4409 | sas_device = _scsih_sas_device_find_by_handle(ioc, | ||
4410 | handle); | ||
4411 | if (!sas_device) { | ||
4412 | spin_unlock_irqrestore(&ioc->sas_device_lock, | ||
4413 | flags); | ||
4414 | break; | ||
4415 | } | ||
4416 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
4417 | _scsih_remove_device(ioc, sas_device); | ||
4115 | break; | 4418 | break; |
4116 | } | 4419 | } |
4117 | } | 4420 | } |
4118 | 4421 | ||
4119 | /* handle expander removal */ | 4422 | /* handle expander removal */ |
4120 | if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING) | 4423 | if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING && |
4121 | _scsih_expander_remove(ioc, parent_handle); | 4424 | sas_expander) |
4425 | _scsih_expander_remove(ioc, sas_address); | ||
4122 | 4426 | ||
4123 | } | 4427 | } |
4124 | 4428 | ||
@@ -4170,6 +4474,12 @@ _scsih_sas_device_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc, | |||
4170 | case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: | 4474 | case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: |
4171 | reason_str = "internal async notification"; | 4475 | reason_str = "internal async notification"; |
4172 | break; | 4476 | break; |
4477 | case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY: | ||
4478 | reason_str = "expander reduced functionality"; | ||
4479 | break; | ||
4480 | case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY: | ||
4481 | reason_str = "expander reduced functionality complete"; | ||
4482 | break; | ||
4173 | default: | 4483 | default: |
4174 | reason_str = "unknown reason"; | 4484 | reason_str = "unknown reason"; |
4175 | break; | 4485 | break; |
@@ -4197,11 +4507,43 @@ static void | |||
4197 | _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, | 4507 | _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, |
4198 | struct fw_event_work *fw_event) | 4508 | struct fw_event_work *fw_event) |
4199 | { | 4509 | { |
4510 | struct MPT2SAS_TARGET *target_priv_data; | ||
4511 | struct _sas_device *sas_device; | ||
4512 | __le64 sas_address; | ||
4513 | unsigned long flags; | ||
4514 | Mpi2EventDataSasDeviceStatusChange_t *event_data = | ||
4515 | fw_event->event_data; | ||
4516 | |||
4200 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 4517 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
4201 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 4518 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
4202 | _scsih_sas_device_status_change_event_debug(ioc, | 4519 | _scsih_sas_device_status_change_event_debug(ioc, |
4203 | fw_event->event_data); | 4520 | event_data); |
4204 | #endif | 4521 | #endif |
4522 | |||
4523 | if (!(event_data->ReasonCode == | ||
4524 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && | ||
4525 | event_data->ReasonCode == | ||
4526 | MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET)) | ||
4527 | return; | ||
4528 | |||
4529 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
4530 | sas_address = le64_to_cpu(event_data->SASAddress); | ||
4531 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | ||
4532 | sas_address); | ||
4533 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
4534 | |||
4535 | if (!sas_device || !sas_device->starget) | ||
4536 | return; | ||
4537 | |||
4538 | target_priv_data = sas_device->starget->hostdata; | ||
4539 | if (!target_priv_data) | ||
4540 | return; | ||
4541 | |||
4542 | if (event_data->ReasonCode == | ||
4543 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET) | ||
4544 | target_priv_data->tm_busy = 1; | ||
4545 | else | ||
4546 | target_priv_data->tm_busy = 0; | ||
4205 | } | 4547 | } |
4206 | 4548 | ||
4207 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 4549 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
@@ -4281,6 +4623,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
4281 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 4623 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
4282 | Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; | 4624 | Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; |
4283 | #endif | 4625 | #endif |
4626 | u16 ioc_status; | ||
4284 | dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: " | 4627 | dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: " |
4285 | "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, | 4628 | "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, |
4286 | event_data->PortWidth)); | 4629 | event_data->PortWidth)); |
@@ -4314,8 +4657,9 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
4314 | mpt2sas_scsih_issue_tm(ioc, handle, lun, | 4657 | mpt2sas_scsih_issue_tm(ioc, handle, lun, |
4315 | MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30); | 4658 | MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30); |
4316 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; | 4659 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; |
4317 | 4660 | ioc_status = le16_to_cpu(mpi_reply->IOCStatus) | |
4318 | if ((mpi_reply->IOCStatus == MPI2_IOCSTATUS_SUCCESS) && | 4661 | & MPI2_IOCSTATUS_MASK; |
4662 | if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) && | ||
4319 | (mpi_reply->ResponseCode == | 4663 | (mpi_reply->ResponseCode == |
4320 | MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || | 4664 | MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || |
4321 | mpi_reply->ResponseCode == | 4665 | mpi_reply->ResponseCode == |
@@ -4570,7 +4914,7 @@ _scsih_sas_pd_delete(struct MPT2SAS_ADAPTER *ioc, | |||
4570 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4914 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
4571 | if (!sas_device) | 4915 | if (!sas_device) |
4572 | return; | 4916 | return; |
4573 | _scsih_remove_device(ioc, handle); | 4917 | _scsih_remove_device(ioc, sas_device); |
4574 | } | 4918 | } |
4575 | 4919 | ||
4576 | /** | 4920 | /** |
@@ -4591,6 +4935,8 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc, | |||
4591 | Mpi2ConfigReply_t mpi_reply; | 4935 | Mpi2ConfigReply_t mpi_reply; |
4592 | Mpi2SasDevicePage0_t sas_device_pg0; | 4936 | Mpi2SasDevicePage0_t sas_device_pg0; |
4593 | u32 ioc_status; | 4937 | u32 ioc_status; |
4938 | u64 sas_address; | ||
4939 | u16 parent_handle; | ||
4594 | 4940 | ||
4595 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 4941 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
4596 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 4942 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); |
@@ -4615,9 +4961,10 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc, | |||
4615 | return; | 4961 | return; |
4616 | } | 4962 | } |
4617 | 4963 | ||
4618 | mpt2sas_transport_update_links(ioc, | 4964 | parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); |
4619 | le16_to_cpu(sas_device_pg0.ParentDevHandle), | 4965 | if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) |
4620 | handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | 4966 | mpt2sas_transport_update_links(ioc, sas_address, handle, |
4967 | sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | ||
4621 | 4968 | ||
4622 | _scsih_add_device(ioc, handle, 0, 1); | 4969 | _scsih_add_device(ioc, handle, 0, 1); |
4623 | } | 4970 | } |
@@ -4857,7 +5204,7 @@ static void | |||
4857 | _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | 5204 | _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, |
4858 | struct fw_event_work *fw_event) | 5205 | struct fw_event_work *fw_event) |
4859 | { | 5206 | { |
4860 | u16 handle; | 5207 | u16 handle, parent_handle; |
4861 | u32 state; | 5208 | u32 state; |
4862 | struct _sas_device *sas_device; | 5209 | struct _sas_device *sas_device; |
4863 | unsigned long flags; | 5210 | unsigned long flags; |
@@ -4865,6 +5212,7 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | |||
4865 | Mpi2SasDevicePage0_t sas_device_pg0; | 5212 | Mpi2SasDevicePage0_t sas_device_pg0; |
4866 | u32 ioc_status; | 5213 | u32 ioc_status; |
4867 | Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data; | 5214 | Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data; |
5215 | u64 sas_address; | ||
4868 | 5216 | ||
4869 | if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) | 5217 | if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) |
4870 | return; | 5218 | return; |
@@ -4906,9 +5254,10 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | |||
4906 | return; | 5254 | return; |
4907 | } | 5255 | } |
4908 | 5256 | ||
4909 | mpt2sas_transport_update_links(ioc, | 5257 | parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); |
4910 | le16_to_cpu(sas_device_pg0.ParentDevHandle), | 5258 | if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) |
4911 | handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | 5259 | mpt2sas_transport_update_links(ioc, sas_address, handle, |
5260 | sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | ||
4912 | 5261 | ||
4913 | _scsih_add_device(ioc, handle, 0, 1); | 5262 | _scsih_add_device(ioc, handle, 0, 1); |
4914 | 5263 | ||
@@ -4948,11 +5297,17 @@ _scsih_sas_ir_operation_status_event_debug(struct MPT2SAS_ADAPTER *ioc, | |||
4948 | case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: | 5297 | case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: |
4949 | reason_str = "consistency check"; | 5298 | reason_str = "consistency check"; |
4950 | break; | 5299 | break; |
4951 | default: | 5300 | case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT: |
4952 | reason_str = "unknown reason"; | 5301 | reason_str = "background init"; |
5302 | break; | ||
5303 | case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT: | ||
5304 | reason_str = "make data consistent"; | ||
4953 | break; | 5305 | break; |
4954 | } | 5306 | } |
4955 | 5307 | ||
5308 | if (!reason_str) | ||
5309 | return; | ||
5310 | |||
4956 | printk(MPT2SAS_INFO_FMT "raid operational status: (%s)" | 5311 | printk(MPT2SAS_INFO_FMT "raid operational status: (%s)" |
4957 | "\thandle(0x%04x), percent complete(%d)\n", | 5312 | "\thandle(0x%04x), percent complete(%d)\n", |
4958 | ioc->name, reason_str, | 5313 | ioc->name, reason_str, |
@@ -4973,11 +5328,33 @@ static void | |||
4973 | _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, | 5328 | _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, |
4974 | struct fw_event_work *fw_event) | 5329 | struct fw_event_work *fw_event) |
4975 | { | 5330 | { |
5331 | Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data; | ||
5332 | static struct _raid_device *raid_device; | ||
5333 | unsigned long flags; | ||
5334 | u16 handle; | ||
5335 | |||
4976 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 5336 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
4977 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 5337 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
4978 | _scsih_sas_ir_operation_status_event_debug(ioc, | 5338 | _scsih_sas_ir_operation_status_event_debug(ioc, |
4979 | fw_event->event_data); | 5339 | event_data); |
4980 | #endif | 5340 | #endif |
5341 | |||
5342 | /* code added for raid transport support */ | ||
5343 | if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) { | ||
5344 | |||
5345 | handle = le16_to_cpu(event_data->VolDevHandle); | ||
5346 | |||
5347 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | ||
5348 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | ||
5349 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | ||
5350 | |||
5351 | if (!raid_device) | ||
5352 | return; | ||
5353 | |||
5354 | if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) | ||
5355 | raid_device->percent_complete = | ||
5356 | event_data->PercentComplete; | ||
5357 | } | ||
4981 | } | 5358 | } |
4982 | 5359 | ||
4983 | /** | 5360 | /** |
@@ -5252,18 +5629,23 @@ _scsih_mark_responding_expander(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
5252 | { | 5629 | { |
5253 | struct _sas_node *sas_expander; | 5630 | struct _sas_node *sas_expander; |
5254 | unsigned long flags; | 5631 | unsigned long flags; |
5632 | int i; | ||
5255 | 5633 | ||
5256 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 5634 | spin_lock_irqsave(&ioc->sas_node_lock, flags); |
5257 | list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { | 5635 | list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { |
5258 | if (sas_expander->sas_address == sas_address) { | 5636 | if (sas_expander->sas_address != sas_address) |
5259 | sas_expander->responding = 1; | 5637 | continue; |
5260 | if (sas_expander->handle != handle) { | 5638 | sas_expander->responding = 1; |
5261 | printk(KERN_INFO "old handle(0x%04x)\n", | 5639 | if (sas_expander->handle == handle) |
5262 | sas_expander->handle); | ||
5263 | sas_expander->handle = handle; | ||
5264 | } | ||
5265 | goto out; | 5640 | goto out; |
5266 | } | 5641 | printk(KERN_INFO "\texpander(0x%016llx): handle changed" |
5642 | " from(0x%04x) to (0x%04x)!!!\n", | ||
5643 | (unsigned long long)sas_expander->sas_address, | ||
5644 | sas_expander->handle, handle); | ||
5645 | sas_expander->handle = handle; | ||
5646 | for (i = 0 ; i < sas_expander->num_phys ; i++) | ||
5647 | sas_expander->phy[i].handle = handle; | ||
5648 | goto out; | ||
5267 | } | 5649 | } |
5268 | out: | 5650 | out: |
5269 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 5651 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
@@ -5340,7 +5722,9 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc) | |||
5340 | (unsigned long long) | 5722 | (unsigned long long) |
5341 | sas_device->enclosure_logical_id, | 5723 | sas_device->enclosure_logical_id, |
5342 | sas_device->slot); | 5724 | sas_device->slot); |
5343 | _scsih_remove_device(ioc, sas_device->handle); | 5725 | /* invalidate the device handle */ |
5726 | sas_device->handle = 0; | ||
5727 | _scsih_remove_device(ioc, sas_device); | ||
5344 | } | 5728 | } |
5345 | 5729 | ||
5346 | list_for_each_entry_safe(raid_device, raid_device_next, | 5730 | list_for_each_entry_safe(raid_device, raid_device_next, |
@@ -5366,7 +5750,7 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc) | |||
5366 | sas_expander->responding = 0; | 5750 | sas_expander->responding = 0; |
5367 | continue; | 5751 | continue; |
5368 | } | 5752 | } |
5369 | _scsih_expander_remove(ioc, sas_expander->handle); | 5753 | _scsih_expander_remove(ioc, sas_expander->sas_address); |
5370 | goto retry_expander_search; | 5754 | goto retry_expander_search; |
5371 | } | 5755 | } |
5372 | } | 5756 | } |
@@ -5406,7 +5790,7 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | |||
5406 | case MPT2_IOC_DONE_RESET: | 5790 | case MPT2_IOC_DONE_RESET: |
5407 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | 5791 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " |
5408 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); | 5792 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); |
5409 | _scsih_sas_host_refresh(ioc, 0); | 5793 | _scsih_sas_host_refresh(ioc); |
5410 | _scsih_search_responding_sas_devices(ioc); | 5794 | _scsih_search_responding_sas_devices(ioc); |
5411 | _scsih_search_responding_raid_devices(ioc); | 5795 | _scsih_search_responding_raid_devices(ioc); |
5412 | _scsih_search_responding_expanders(ioc); | 5796 | _scsih_search_responding_expanders(ioc); |
@@ -5646,7 +6030,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, | |||
5646 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 6030 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
5647 | if (!sas_device) | 6031 | if (!sas_device) |
5648 | continue; | 6032 | continue; |
5649 | _scsih_remove_device(ioc, sas_device->handle); | 6033 | _scsih_remove_device(ioc, sas_device); |
5650 | if (ioc->shost_recovery) | 6034 | if (ioc->shost_recovery) |
5651 | return; | 6035 | return; |
5652 | goto retry_device_search; | 6036 | goto retry_device_search; |
@@ -5669,7 +6053,8 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, | |||
5669 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 6053 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
5670 | if (!expander_sibling) | 6054 | if (!expander_sibling) |
5671 | continue; | 6055 | continue; |
5672 | _scsih_expander_remove(ioc, expander_sibling->handle); | 6056 | _scsih_expander_remove(ioc, |
6057 | expander_sibling->sas_address); | ||
5673 | if (ioc->shost_recovery) | 6058 | if (ioc->shost_recovery) |
5674 | return; | 6059 | return; |
5675 | goto retry_expander_search; | 6060 | goto retry_expander_search; |
@@ -5677,7 +6062,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, | |||
5677 | } | 6062 | } |
5678 | 6063 | ||
5679 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, | 6064 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, |
5680 | sas_expander->parent_handle); | 6065 | sas_expander->sas_address_parent); |
5681 | 6066 | ||
5682 | printk(MPT2SAS_INFO_FMT "expander_remove: handle" | 6067 | printk(MPT2SAS_INFO_FMT "expander_remove: handle" |
5683 | "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, | 6068 | "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, |
@@ -5690,9 +6075,99 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, | |||
5690 | } | 6075 | } |
5691 | 6076 | ||
5692 | /** | 6077 | /** |
6078 | * _scsih_ir_shutdown - IR shutdown notification | ||
6079 | * @ioc: per adapter object | ||
6080 | * | ||
6081 | * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that | ||
6082 | * the host system is shutting down. | ||
6083 | * | ||
6084 | * Return nothing. | ||
6085 | */ | ||
6086 | static void | ||
6087 | _scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc) | ||
6088 | { | ||
6089 | Mpi2RaidActionRequest_t *mpi_request; | ||
6090 | Mpi2RaidActionReply_t *mpi_reply; | ||
6091 | u16 smid; | ||
6092 | |||
6093 | /* is IR firmware build loaded ? */ | ||
6094 | if (!ioc->ir_firmware) | ||
6095 | return; | ||
6096 | |||
6097 | /* are there any volumes ? */ | ||
6098 | if (list_empty(&ioc->raid_device_list)) | ||
6099 | return; | ||
6100 | |||
6101 | mutex_lock(&ioc->scsih_cmds.mutex); | ||
6102 | |||
6103 | if (ioc->scsih_cmds.status != MPT2_CMD_NOT_USED) { | ||
6104 | printk(MPT2SAS_ERR_FMT "%s: scsih_cmd in use\n", | ||
6105 | ioc->name, __func__); | ||
6106 | goto out; | ||
6107 | } | ||
6108 | ioc->scsih_cmds.status = MPT2_CMD_PENDING; | ||
6109 | |||
6110 | smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx); | ||
6111 | if (!smid) { | ||
6112 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", | ||
6113 | ioc->name, __func__); | ||
6114 | ioc->scsih_cmds.status = MPT2_CMD_NOT_USED; | ||
6115 | goto out; | ||
6116 | } | ||
6117 | |||
6118 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); | ||
6119 | ioc->scsih_cmds.smid = smid; | ||
6120 | memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t)); | ||
6121 | |||
6122 | mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; | ||
6123 | mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; | ||
6124 | |||
6125 | printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name); | ||
6126 | init_completion(&ioc->scsih_cmds.done); | ||
6127 | mpt2sas_base_put_smid_default(ioc, smid); | ||
6128 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); | ||
6129 | |||
6130 | if (!(ioc->scsih_cmds.status & MPT2_CMD_COMPLETE)) { | ||
6131 | printk(MPT2SAS_ERR_FMT "%s: timeout\n", | ||
6132 | ioc->name, __func__); | ||
6133 | goto out; | ||
6134 | } | ||
6135 | |||
6136 | if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) { | ||
6137 | mpi_reply = ioc->scsih_cmds.reply; | ||
6138 | |||
6139 | printk(MPT2SAS_INFO_FMT "IR shutdown (complete): " | ||
6140 | "ioc_status(0x%04x), loginfo(0x%08x)\n", | ||
6141 | ioc->name, le16_to_cpu(mpi_reply->IOCStatus), | ||
6142 | le32_to_cpu(mpi_reply->IOCLogInfo)); | ||
6143 | } | ||
6144 | |||
6145 | out: | ||
6146 | ioc->scsih_cmds.status = MPT2_CMD_NOT_USED; | ||
6147 | mutex_unlock(&ioc->scsih_cmds.mutex); | ||
6148 | } | ||
6149 | |||
6150 | /** | ||
6151 | * _scsih_shutdown - routine call during system shutdown | ||
6152 | * @pdev: PCI device struct | ||
6153 | * | ||
6154 | * Return nothing. | ||
6155 | */ | ||
6156 | static void | ||
6157 | _scsih_shutdown(struct pci_dev *pdev) | ||
6158 | { | ||
6159 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | ||
6160 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); | ||
6161 | |||
6162 | _scsih_ir_shutdown(ioc); | ||
6163 | mpt2sas_base_detach(ioc); | ||
6164 | } | ||
6165 | |||
6166 | /** | ||
5693 | * _scsih_remove - detach and remove add host | 6167 | * _scsih_remove - detach and remove add host |
5694 | * @pdev: PCI device struct | 6168 | * @pdev: PCI device struct |
5695 | * | 6169 | * |
6170 | * Routine called when unloading the driver. | ||
5696 | * Return nothing. | 6171 | * Return nothing. |
5697 | */ | 6172 | */ |
5698 | static void __devexit | 6173 | static void __devexit |
@@ -5703,6 +6178,8 @@ _scsih_remove(struct pci_dev *pdev) | |||
5703 | struct _sas_port *mpt2sas_port; | 6178 | struct _sas_port *mpt2sas_port; |
5704 | struct _sas_device *sas_device; | 6179 | struct _sas_device *sas_device; |
5705 | struct _sas_node *expander_sibling; | 6180 | struct _sas_node *expander_sibling; |
6181 | struct _raid_device *raid_device, *next; | ||
6182 | struct MPT2SAS_TARGET *sas_target_priv_data; | ||
5706 | struct workqueue_struct *wq; | 6183 | struct workqueue_struct *wq; |
5707 | unsigned long flags; | 6184 | unsigned long flags; |
5708 | 6185 | ||
@@ -5716,6 +6193,21 @@ _scsih_remove(struct pci_dev *pdev) | |||
5716 | if (wq) | 6193 | if (wq) |
5717 | destroy_workqueue(wq); | 6194 | destroy_workqueue(wq); |
5718 | 6195 | ||
6196 | /* release all the volumes */ | ||
6197 | list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, | ||
6198 | list) { | ||
6199 | if (raid_device->starget) { | ||
6200 | sas_target_priv_data = | ||
6201 | raid_device->starget->hostdata; | ||
6202 | sas_target_priv_data->deleted = 1; | ||
6203 | scsi_remove_target(&raid_device->starget->dev); | ||
6204 | } | ||
6205 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid" | ||
6206 | "(0x%016llx)\n", ioc->name, raid_device->handle, | ||
6207 | (unsigned long long) raid_device->wwid); | ||
6208 | _scsih_raid_device_remove(ioc, raid_device); | ||
6209 | } | ||
6210 | |||
5719 | /* free ports attached to the sas_host */ | 6211 | /* free ports attached to the sas_host */ |
5720 | retry_again: | 6212 | retry_again: |
5721 | list_for_each_entry(mpt2sas_port, | 6213 | list_for_each_entry(mpt2sas_port, |
@@ -5726,7 +6218,7 @@ _scsih_remove(struct pci_dev *pdev) | |||
5726 | mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 6218 | mpt2sas_scsih_sas_device_find_by_sas_address(ioc, |
5727 | mpt2sas_port->remote_identify.sas_address); | 6219 | mpt2sas_port->remote_identify.sas_address); |
5728 | if (sas_device) { | 6220 | if (sas_device) { |
5729 | _scsih_remove_device(ioc, sas_device->handle); | 6221 | _scsih_remove_device(ioc, sas_device); |
5730 | goto retry_again; | 6222 | goto retry_again; |
5731 | } | 6223 | } |
5732 | } else { | 6224 | } else { |
@@ -5735,7 +6227,7 @@ _scsih_remove(struct pci_dev *pdev) | |||
5735 | mpt2sas_port->remote_identify.sas_address); | 6227 | mpt2sas_port->remote_identify.sas_address); |
5736 | if (expander_sibling) { | 6228 | if (expander_sibling) { |
5737 | _scsih_expander_remove(ioc, | 6229 | _scsih_expander_remove(ioc, |
5738 | expander_sibling->handle); | 6230 | expander_sibling->sas_address); |
5739 | goto retry_again; | 6231 | goto retry_again; |
5740 | } | 6232 | } |
5741 | } | 6233 | } |
@@ -5749,7 +6241,7 @@ _scsih_remove(struct pci_dev *pdev) | |||
5749 | } | 6241 | } |
5750 | 6242 | ||
5751 | sas_remove_host(shost); | 6243 | sas_remove_host(shost); |
5752 | mpt2sas_base_detach(ioc); | 6244 | _scsih_shutdown(pdev); |
5753 | list_del(&ioc->list); | 6245 | list_del(&ioc->list); |
5754 | scsi_remove_host(shost); | 6246 | scsi_remove_host(shost); |
5755 | scsi_host_put(shost); | 6247 | scsi_host_put(shost); |
@@ -5770,7 +6262,8 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc) | |||
5770 | void *device; | 6262 | void *device; |
5771 | struct _sas_device *sas_device; | 6263 | struct _sas_device *sas_device; |
5772 | struct _raid_device *raid_device; | 6264 | struct _raid_device *raid_device; |
5773 | u16 handle, parent_handle; | 6265 | u16 handle; |
6266 | u64 sas_address_parent; | ||
5774 | u64 sas_address; | 6267 | u64 sas_address; |
5775 | unsigned long flags; | 6268 | unsigned long flags; |
5776 | int rc; | 6269 | int rc; |
@@ -5799,17 +6292,17 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc) | |||
5799 | } else { | 6292 | } else { |
5800 | sas_device = device; | 6293 | sas_device = device; |
5801 | handle = sas_device->handle; | 6294 | handle = sas_device->handle; |
5802 | parent_handle = sas_device->parent_handle; | 6295 | sas_address_parent = sas_device->sas_address_parent; |
5803 | sas_address = sas_device->sas_address; | 6296 | sas_address = sas_device->sas_address; |
5804 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6297 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
5805 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | 6298 | list_move_tail(&sas_device->list, &ioc->sas_device_list); |
5806 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 6299 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
5807 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, | 6300 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
5808 | sas_device->parent_handle)) { | 6301 | sas_device->sas_address_parent)) { |
5809 | _scsih_sas_device_remove(ioc, sas_device); | 6302 | _scsih_sas_device_remove(ioc, sas_device); |
5810 | } else if (!sas_device->starget) { | 6303 | } else if (!sas_device->starget) { |
5811 | mpt2sas_transport_port_remove(ioc, sas_address, | 6304 | mpt2sas_transport_port_remove(ioc, sas_address, |
5812 | parent_handle); | 6305 | sas_address_parent); |
5813 | _scsih_sas_device_remove(ioc, sas_device); | 6306 | _scsih_sas_device_remove(ioc, sas_device); |
5814 | } | 6307 | } |
5815 | } | 6308 | } |
@@ -5849,8 +6342,6 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc) | |||
5849 | { | 6342 | { |
5850 | struct _sas_device *sas_device, *next; | 6343 | struct _sas_device *sas_device, *next; |
5851 | unsigned long flags; | 6344 | unsigned long flags; |
5852 | u16 handle, parent_handle; | ||
5853 | u64 sas_address; | ||
5854 | 6345 | ||
5855 | /* SAS Device List */ | 6346 | /* SAS Device List */ |
5856 | list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, | 6347 | list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, |
@@ -5859,14 +6350,13 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc) | |||
5859 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | 6350 | list_move_tail(&sas_device->list, &ioc->sas_device_list); |
5860 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 6351 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
5861 | 6352 | ||
5862 | handle = sas_device->handle; | 6353 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
5863 | parent_handle = sas_device->parent_handle; | 6354 | 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); | 6355 | _scsih_sas_device_remove(ioc, sas_device); |
5867 | } else if (!sas_device->starget) { | 6356 | } else if (!sas_device->starget) { |
5868 | mpt2sas_transport_port_remove(ioc, sas_address, | 6357 | mpt2sas_transport_port_remove(ioc, |
5869 | parent_handle); | 6358 | sas_device->sas_address, |
6359 | sas_device->sas_address_parent); | ||
5870 | _scsih_sas_device_remove(ioc, sas_device); | 6360 | _scsih_sas_device_remove(ioc, sas_device); |
5871 | } | 6361 | } |
5872 | } | 6362 | } |
@@ -5935,6 +6425,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
5935 | ioc->ctl_cb_idx = ctl_cb_idx; | 6425 | ioc->ctl_cb_idx = ctl_cb_idx; |
5936 | ioc->base_cb_idx = base_cb_idx; | 6426 | ioc->base_cb_idx = base_cb_idx; |
5937 | ioc->transport_cb_idx = transport_cb_idx; | 6427 | ioc->transport_cb_idx = transport_cb_idx; |
6428 | ioc->scsih_cb_idx = scsih_cb_idx; | ||
5938 | ioc->config_cb_idx = config_cb_idx; | 6429 | ioc->config_cb_idx = config_cb_idx; |
5939 | ioc->tm_tr_cb_idx = tm_tr_cb_idx; | 6430 | ioc->tm_tr_cb_idx = tm_tr_cb_idx; |
5940 | ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; | 6431 | ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; |
@@ -6072,12 +6563,20 @@ static struct pci_driver scsih_driver = { | |||
6072 | .id_table = scsih_pci_table, | 6563 | .id_table = scsih_pci_table, |
6073 | .probe = _scsih_probe, | 6564 | .probe = _scsih_probe, |
6074 | .remove = __devexit_p(_scsih_remove), | 6565 | .remove = __devexit_p(_scsih_remove), |
6566 | .shutdown = _scsih_shutdown, | ||
6075 | #ifdef CONFIG_PM | 6567 | #ifdef CONFIG_PM |
6076 | .suspend = _scsih_suspend, | 6568 | .suspend = _scsih_suspend, |
6077 | .resume = _scsih_resume, | 6569 | .resume = _scsih_resume, |
6078 | #endif | 6570 | #endif |
6079 | }; | 6571 | }; |
6080 | 6572 | ||
6573 | /* raid transport support */ | ||
6574 | static struct raid_function_template mpt2sas_raid_functions = { | ||
6575 | .cookie = &scsih_driver_template, | ||
6576 | .is_raid = _scsih_is_raid, | ||
6577 | .get_resync = _scsih_get_resync, | ||
6578 | .get_state = _scsih_get_state, | ||
6579 | }; | ||
6081 | 6580 | ||
6082 | /** | 6581 | /** |
6083 | * _scsih_init - main entry point for this driver. | 6582 | * _scsih_init - main entry point for this driver. |
@@ -6097,6 +6596,12 @@ _scsih_init(void) | |||
6097 | sas_attach_transport(&mpt2sas_transport_functions); | 6596 | sas_attach_transport(&mpt2sas_transport_functions); |
6098 | if (!mpt2sas_transport_template) | 6597 | if (!mpt2sas_transport_template) |
6099 | return -ENODEV; | 6598 | return -ENODEV; |
6599 | /* raid transport support */ | ||
6600 | mpt2sas_raid_template = raid_class_attach(&mpt2sas_raid_functions); | ||
6601 | if (!mpt2sas_raid_template) { | ||
6602 | sas_release_transport(mpt2sas_transport_template); | ||
6603 | return -ENODEV; | ||
6604 | } | ||
6100 | 6605 | ||
6101 | mpt2sas_base_initialize_callback_handler(); | 6606 | mpt2sas_base_initialize_callback_handler(); |
6102 | 6607 | ||
@@ -6113,6 +6618,9 @@ _scsih_init(void) | |||
6113 | transport_cb_idx = mpt2sas_base_register_callback_handler( | 6618 | transport_cb_idx = mpt2sas_base_register_callback_handler( |
6114 | mpt2sas_transport_done); | 6619 | mpt2sas_transport_done); |
6115 | 6620 | ||
6621 | /* scsih internal commands callback handler */ | ||
6622 | scsih_cb_idx = mpt2sas_base_register_callback_handler(_scsih_done); | ||
6623 | |||
6116 | /* configuration page API internal commands callback handler */ | 6624 | /* configuration page API internal commands callback handler */ |
6117 | config_cb_idx = mpt2sas_base_register_callback_handler( | 6625 | config_cb_idx = mpt2sas_base_register_callback_handler( |
6118 | mpt2sas_config_done); | 6626 | mpt2sas_config_done); |
@@ -6128,8 +6636,11 @@ _scsih_init(void) | |||
6128 | mpt2sas_ctl_init(); | 6636 | mpt2sas_ctl_init(); |
6129 | 6637 | ||
6130 | error = pci_register_driver(&scsih_driver); | 6638 | error = pci_register_driver(&scsih_driver); |
6131 | if (error) | 6639 | if (error) { |
6640 | /* raid transport support */ | ||
6641 | raid_class_release(mpt2sas_raid_template); | ||
6132 | sas_release_transport(mpt2sas_transport_template); | 6642 | sas_release_transport(mpt2sas_transport_template); |
6643 | } | ||
6133 | 6644 | ||
6134 | return error; | 6645 | return error; |
6135 | } | 6646 | } |
@@ -6147,18 +6658,23 @@ _scsih_exit(void) | |||
6147 | 6658 | ||
6148 | pci_unregister_driver(&scsih_driver); | 6659 | pci_unregister_driver(&scsih_driver); |
6149 | 6660 | ||
6150 | sas_release_transport(mpt2sas_transport_template); | 6661 | mpt2sas_ctl_exit(); |
6662 | |||
6151 | mpt2sas_base_release_callback_handler(scsi_io_cb_idx); | 6663 | mpt2sas_base_release_callback_handler(scsi_io_cb_idx); |
6152 | mpt2sas_base_release_callback_handler(tm_cb_idx); | 6664 | mpt2sas_base_release_callback_handler(tm_cb_idx); |
6153 | mpt2sas_base_release_callback_handler(base_cb_idx); | 6665 | mpt2sas_base_release_callback_handler(base_cb_idx); |
6154 | mpt2sas_base_release_callback_handler(transport_cb_idx); | 6666 | mpt2sas_base_release_callback_handler(transport_cb_idx); |
6667 | mpt2sas_base_release_callback_handler(scsih_cb_idx); | ||
6155 | mpt2sas_base_release_callback_handler(config_cb_idx); | 6668 | mpt2sas_base_release_callback_handler(config_cb_idx); |
6156 | mpt2sas_base_release_callback_handler(ctl_cb_idx); | 6669 | mpt2sas_base_release_callback_handler(ctl_cb_idx); |
6157 | 6670 | ||
6158 | mpt2sas_base_release_callback_handler(tm_tr_cb_idx); | 6671 | mpt2sas_base_release_callback_handler(tm_tr_cb_idx); |
6159 | mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); | 6672 | mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); |
6160 | 6673 | ||
6161 | mpt2sas_ctl_exit(); | 6674 | /* raid transport support */ |
6675 | raid_class_release(mpt2sas_raid_template); | ||
6676 | sas_release_transport(mpt2sas_transport_template); | ||
6677 | |||
6162 | } | 6678 | } |
6163 | 6679 | ||
6164 | module_init(_scsih_init); | 6680 | module_init(_scsih_init); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c index eb98188c7f3f..bd7ca2b49f81 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_transport.c +++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/workqueue.h> | 49 | #include <linux/workqueue.h> |
50 | #include <linux/delay.h> | 50 | #include <linux/delay.h> |
51 | #include <linux/pci.h> | 51 | #include <linux/pci.h> |
52 | #include <linux/slab.h> | ||
52 | 53 | ||
53 | #include <scsi/scsi.h> | 54 | #include <scsi/scsi.h> |
54 | #include <scsi/scsi_cmnd.h> | 55 | #include <scsi/scsi_cmnd.h> |
@@ -59,24 +60,23 @@ | |||
59 | 60 | ||
60 | #include "mpt2sas_base.h" | 61 | #include "mpt2sas_base.h" |
61 | /** | 62 | /** |
62 | * _transport_sas_node_find_by_handle - sas node search | 63 | * _transport_sas_node_find_by_sas_address - sas node search |
63 | * @ioc: per adapter object | 64 | * @ioc: per adapter object |
64 | * @handle: expander or hba handle (assigned by firmware) | 65 | * @sas_address: sas address of expander or sas host |
65 | * Context: Calling function should acquire ioc->sas_node_lock. | 66 | * Context: Calling function should acquire ioc->sas_node_lock. |
66 | * | 67 | * |
67 | * Search for either hba phys or expander device based on handle, then returns | 68 | * Search for either hba phys or expander device based on handle, then returns |
68 | * the sas_node object. | 69 | * the sas_node object. |
69 | */ | 70 | */ |
70 | static struct _sas_node * | 71 | static struct _sas_node * |
71 | _transport_sas_node_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) | 72 | _transport_sas_node_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc, |
73 | u64 sas_address) | ||
72 | { | 74 | { |
73 | int i; | 75 | if (ioc->sas_hba.sas_address == sas_address) |
74 | 76 | return &ioc->sas_hba; | |
75 | for (i = 0; i < ioc->sas_hba.num_phys; i++) | 77 | else |
76 | if (ioc->sas_hba.phy[i].handle == handle) | 78 | return mpt2sas_scsih_expander_find_by_sas_address(ioc, |
77 | return &ioc->sas_hba; | 79 | sas_address); |
78 | |||
79 | return mpt2sas_scsih_expander_find_by_handle(ioc, handle); | ||
80 | } | 80 | } |
81 | 81 | ||
82 | /** | 82 | /** |
@@ -259,8 +259,7 @@ struct rep_manu_reply{ | |||
259 | u8 response_length; | 259 | u8 response_length; |
260 | u16 expander_change_count; | 260 | u16 expander_change_count; |
261 | u8 reserved0[2]; | 261 | u8 reserved0[2]; |
262 | u8 sas_format:1; | 262 | u8 sas_format; |
263 | u8 reserved1:7; | ||
264 | u8 reserved2[3]; | 263 | u8 reserved2[3]; |
265 | u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN]; | 264 | u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN]; |
266 | u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN]; | 265 | u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN]; |
@@ -375,7 +374,8 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, | |||
375 | mpi_request->VP_ID = 0; | 374 | mpi_request->VP_ID = 0; |
376 | sas_address_le = (u64 *)&mpi_request->SASAddress; | 375 | sas_address_le = (u64 *)&mpi_request->SASAddress; |
377 | *sas_address_le = cpu_to_le64(sas_address); | 376 | *sas_address_le = cpu_to_le64(sas_address); |
378 | mpi_request->RequestDataLength = sizeof(struct rep_manu_request); | 377 | mpi_request->RequestDataLength = |
378 | cpu_to_le16(sizeof(struct rep_manu_request)); | ||
379 | psge = &mpi_request->SGL; | 379 | psge = &mpi_request->SGL; |
380 | 380 | ||
381 | /* WRITE sgel first */ | 381 | /* WRITE sgel first */ |
@@ -438,8 +438,8 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, | |||
438 | SAS_EXPANDER_PRODUCT_ID_LEN); | 438 | SAS_EXPANDER_PRODUCT_ID_LEN); |
439 | strncpy(edev->product_rev, manufacture_reply->product_rev, | 439 | strncpy(edev->product_rev, manufacture_reply->product_rev, |
440 | SAS_EXPANDER_PRODUCT_REV_LEN); | 440 | SAS_EXPANDER_PRODUCT_REV_LEN); |
441 | edev->level = manufacture_reply->sas_format; | 441 | edev->level = manufacture_reply->sas_format & 1; |
442 | if (manufacture_reply->sas_format) { | 442 | if (edev->level) { |
443 | strncpy(edev->component_vendor_id, | 443 | strncpy(edev->component_vendor_id, |
444 | manufacture_reply->component_vendor_id, | 444 | manufacture_reply->component_vendor_id, |
445 | SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); | 445 | SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); |
@@ -469,7 +469,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, | |||
469 | * mpt2sas_transport_port_add - insert port to the list | 469 | * mpt2sas_transport_port_add - insert port to the list |
470 | * @ioc: per adapter object | 470 | * @ioc: per adapter object |
471 | * @handle: handle of attached device | 471 | * @handle: handle of attached device |
472 | * @parent_handle: parent handle(either hba or expander) | 472 | * @sas_address: sas address of parent expander or sas host |
473 | * Context: This function will acquire ioc->sas_node_lock. | 473 | * Context: This function will acquire ioc->sas_node_lock. |
474 | * | 474 | * |
475 | * Adding new port object to the sas_node->sas_port_list. | 475 | * Adding new port object to the sas_node->sas_port_list. |
@@ -478,7 +478,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, | |||
478 | */ | 478 | */ |
479 | struct _sas_port * | 479 | struct _sas_port * |
480 | mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle, | 480 | mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle, |
481 | u16 parent_handle) | 481 | u64 sas_address) |
482 | { | 482 | { |
483 | struct _sas_phy *mpt2sas_phy, *next; | 483 | struct _sas_phy *mpt2sas_phy, *next; |
484 | struct _sas_port *mpt2sas_port; | 484 | struct _sas_port *mpt2sas_port; |
@@ -488,9 +488,6 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
488 | int i; | 488 | int i; |
489 | struct sas_port *port; | 489 | struct sas_port *port; |
490 | 490 | ||
491 | if (!parent_handle) | ||
492 | return NULL; | ||
493 | |||
494 | mpt2sas_port = kzalloc(sizeof(struct _sas_port), | 491 | mpt2sas_port = kzalloc(sizeof(struct _sas_port), |
495 | GFP_KERNEL); | 492 | GFP_KERNEL); |
496 | if (!mpt2sas_port) { | 493 | if (!mpt2sas_port) { |
@@ -502,17 +499,16 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
502 | INIT_LIST_HEAD(&mpt2sas_port->port_list); | 499 | INIT_LIST_HEAD(&mpt2sas_port->port_list); |
503 | INIT_LIST_HEAD(&mpt2sas_port->phy_list); | 500 | INIT_LIST_HEAD(&mpt2sas_port->phy_list); |
504 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 501 | spin_lock_irqsave(&ioc->sas_node_lock, flags); |
505 | sas_node = _transport_sas_node_find_by_handle(ioc, parent_handle); | 502 | sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); |
506 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 503 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
507 | 504 | ||
508 | if (!sas_node) { | 505 | if (!sas_node) { |
509 | printk(MPT2SAS_ERR_FMT "%s: Could not find parent(0x%04x)!\n", | 506 | printk(MPT2SAS_ERR_FMT "%s: Could not find " |
510 | ioc->name, __func__, parent_handle); | 507 | "parent sas_address(0x%016llx)!\n", ioc->name, |
508 | __func__, (unsigned long long)sas_address); | ||
511 | goto out_fail; | 509 | goto out_fail; |
512 | } | 510 | } |
513 | 511 | ||
514 | mpt2sas_port->handle = parent_handle; | ||
515 | mpt2sas_port->sas_address = sas_node->sas_address; | ||
516 | if ((_transport_set_identify(ioc, handle, | 512 | if ((_transport_set_identify(ioc, handle, |
517 | &mpt2sas_port->remote_identify))) { | 513 | &mpt2sas_port->remote_identify))) { |
518 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 514 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
@@ -604,7 +600,7 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
604 | * mpt2sas_transport_port_remove - remove port from the list | 600 | * mpt2sas_transport_port_remove - remove port from the list |
605 | * @ioc: per adapter object | 601 | * @ioc: per adapter object |
606 | * @sas_address: sas address of attached device | 602 | * @sas_address: sas address of attached device |
607 | * @parent_handle: handle to the upstream parent(either hba or expander) | 603 | * @sas_address_parent: sas address of parent expander or sas host |
608 | * Context: This function will acquire ioc->sas_node_lock. | 604 | * Context: This function will acquire ioc->sas_node_lock. |
609 | * | 605 | * |
610 | * Removing object and freeing associated memory from the | 606 | * Removing object and freeing associated memory from the |
@@ -614,7 +610,7 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
614 | */ | 610 | */ |
615 | void | 611 | void |
616 | mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | 612 | mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, |
617 | u16 parent_handle) | 613 | u64 sas_address_parent) |
618 | { | 614 | { |
619 | int i; | 615 | int i; |
620 | unsigned long flags; | 616 | unsigned long flags; |
@@ -624,7 +620,8 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
624 | struct _sas_phy *mpt2sas_phy, *next_phy; | 620 | struct _sas_phy *mpt2sas_phy, *next_phy; |
625 | 621 | ||
626 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 622 | spin_lock_irqsave(&ioc->sas_node_lock, flags); |
627 | sas_node = _transport_sas_node_find_by_handle(ioc, parent_handle); | 623 | sas_node = _transport_sas_node_find_by_sas_address(ioc, |
624 | sas_address_parent); | ||
628 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 625 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
629 | if (!sas_node) | 626 | if (!sas_node) |
630 | return; | 627 | return; |
@@ -650,8 +647,7 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
650 | &mpt2sas_port->phy_list, port_siblings) { | 647 | &mpt2sas_port->phy_list, port_siblings) { |
651 | if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) | 648 | if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) |
652 | dev_printk(KERN_INFO, &mpt2sas_port->port->dev, | 649 | dev_printk(KERN_INFO, &mpt2sas_port->port->dev, |
653 | "remove: parent_handle(0x%04x), " | 650 | "remove: sas_addr(0x%016llx), phy(%d)\n", |
654 | "sas_addr(0x%016llx), phy(%d)\n", parent_handle, | ||
655 | (unsigned long long) | 651 | (unsigned long long) |
656 | mpt2sas_port->remote_identify.sas_address, | 652 | mpt2sas_port->remote_identify.sas_address, |
657 | mpt2sas_phy->phy_id); | 653 | mpt2sas_phy->phy_id); |
@@ -799,8 +795,8 @@ mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy | |||
799 | /** | 795 | /** |
800 | * mpt2sas_transport_update_links - refreshing phy link changes | 796 | * mpt2sas_transport_update_links - refreshing phy link changes |
801 | * @ioc: per adapter object | 797 | * @ioc: per adapter object |
802 | * @handle: handle to sas_host or expander | 798 | * @sas_address: sas address of parent expander or sas host |
803 | * @attached_handle: attached device handle | 799 | * @handle: attached device handle |
804 | * @phy_numberv: phy number | 800 | * @phy_numberv: phy number |
805 | * @link_rate: new link rate | 801 | * @link_rate: new link rate |
806 | * | 802 | * |
@@ -808,28 +804,25 @@ mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy | |||
808 | */ | 804 | */ |
809 | void | 805 | void |
810 | mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, | 806 | mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, |
811 | u16 handle, u16 attached_handle, u8 phy_number, u8 link_rate) | 807 | u64 sas_address, u16 handle, u8 phy_number, u8 link_rate) |
812 | { | 808 | { |
813 | unsigned long flags; | 809 | unsigned long flags; |
814 | struct _sas_node *sas_node; | 810 | struct _sas_node *sas_node; |
815 | struct _sas_phy *mpt2sas_phy; | 811 | struct _sas_phy *mpt2sas_phy; |
816 | 812 | ||
817 | if (ioc->shost_recovery) { | 813 | if (ioc->shost_recovery) |
818 | printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", | ||
819 | __func__, ioc->name); | ||
820 | return; | 814 | return; |
821 | } | ||
822 | 815 | ||
823 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 816 | spin_lock_irqsave(&ioc->sas_node_lock, flags); |
824 | sas_node = _transport_sas_node_find_by_handle(ioc, handle); | 817 | sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); |
825 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 818 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
826 | if (!sas_node) | 819 | if (!sas_node) |
827 | return; | 820 | return; |
828 | 821 | ||
829 | mpt2sas_phy = &sas_node->phy[phy_number]; | 822 | mpt2sas_phy = &sas_node->phy[phy_number]; |
830 | mpt2sas_phy->attached_handle = attached_handle; | 823 | mpt2sas_phy->attached_handle = handle; |
831 | if (attached_handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) | 824 | if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) |
832 | _transport_set_identify(ioc, mpt2sas_phy->attached_handle, | 825 | _transport_set_identify(ioc, handle, |
833 | &mpt2sas_phy->remote_identify); | 826 | &mpt2sas_phy->remote_identify); |
834 | else | 827 | else |
835 | memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct | 828 | memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct |
@@ -841,13 +834,11 @@ mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, | |||
841 | 834 | ||
842 | if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) | 835 | if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) |
843 | dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, | 836 | dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, |
844 | "refresh: handle(0x%04x), sas_addr(0x%016llx),\n" | 837 | "refresh: parent sas_addr(0x%016llx),\n" |
845 | "\tlink_rate(0x%02x), phy(%d)\n" | 838 | "\tlink_rate(0x%02x), phy(%d)\n" |
846 | "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", | 839 | "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", |
847 | handle, (unsigned long long) | 840 | (unsigned long long)sas_address, |
848 | mpt2sas_phy->identify.sas_address, link_rate, | 841 | link_rate, phy_number, handle, (unsigned long long) |
849 | phy_number, attached_handle, | ||
850 | (unsigned long long) | ||
851 | mpt2sas_phy->remote_identify.sas_address); | 842 | mpt2sas_phy->remote_identify.sas_address); |
852 | } | 843 | } |
853 | 844 | ||
@@ -865,6 +856,17 @@ rphy_to_ioc(struct sas_rphy *rphy) | |||
865 | return shost_priv(shost); | 856 | return shost_priv(shost); |
866 | } | 857 | } |
867 | 858 | ||
859 | static struct _sas_phy * | ||
860 | _transport_find_local_phy(struct MPT2SAS_ADAPTER *ioc, struct sas_phy *phy) | ||
861 | { | ||
862 | int i; | ||
863 | |||
864 | for (i = 0; i < ioc->sas_hba.num_phys; i++) | ||
865 | if (ioc->sas_hba.phy[i].phy == phy) | ||
866 | return(&ioc->sas_hba.phy[i]); | ||
867 | return NULL; | ||
868 | } | ||
869 | |||
868 | /** | 870 | /** |
869 | * _transport_get_linkerrors - | 871 | * _transport_get_linkerrors - |
870 | * @phy: The sas phy object | 872 | * @phy: The sas phy object |
@@ -880,14 +882,8 @@ _transport_get_linkerrors(struct sas_phy *phy) | |||
880 | struct _sas_phy *mpt2sas_phy; | 882 | struct _sas_phy *mpt2sas_phy; |
881 | Mpi2ConfigReply_t mpi_reply; | 883 | Mpi2ConfigReply_t mpi_reply; |
882 | Mpi2SasPhyPage1_t phy_pg1; | 884 | Mpi2SasPhyPage1_t phy_pg1; |
883 | int i; | ||
884 | 885 | ||
885 | for (i = 0, mpt2sas_phy = NULL; i < ioc->sas_hba.num_phys && | 886 | mpt2sas_phy = _transport_find_local_phy(ioc, phy); |
886 | !mpt2sas_phy; i++) { | ||
887 | if (ioc->sas_hba.phy[i].phy != phy) | ||
888 | continue; | ||
889 | mpt2sas_phy = &ioc->sas_hba.phy[i]; | ||
890 | } | ||
891 | 887 | ||
892 | if (!mpt2sas_phy) /* this phy not on sas_host */ | 888 | if (!mpt2sas_phy) /* this phy not on sas_host */ |
893 | return -EINVAL; | 889 | return -EINVAL; |
@@ -981,14 +977,8 @@ _transport_phy_reset(struct sas_phy *phy, int hard_reset) | |||
981 | struct _sas_phy *mpt2sas_phy; | 977 | struct _sas_phy *mpt2sas_phy; |
982 | Mpi2SasIoUnitControlReply_t mpi_reply; | 978 | Mpi2SasIoUnitControlReply_t mpi_reply; |
983 | Mpi2SasIoUnitControlRequest_t mpi_request; | 979 | Mpi2SasIoUnitControlRequest_t mpi_request; |
984 | int i; | ||
985 | 980 | ||
986 | for (i = 0, mpt2sas_phy = NULL; i < ioc->sas_hba.num_phys && | 981 | mpt2sas_phy = _transport_find_local_phy(ioc, phy); |
987 | !mpt2sas_phy; i++) { | ||
988 | if (ioc->sas_hba.phy[i].phy != phy) | ||
989 | continue; | ||
990 | mpt2sas_phy = &ioc->sas_hba.phy[i]; | ||
991 | } | ||
992 | 982 | ||
993 | if (!mpt2sas_phy) /* this phy not on sas_host */ | 983 | if (!mpt2sas_phy) /* this phy not on sas_host */ |
994 | return -EINVAL; | 984 | return -EINVAL; |
@@ -1016,6 +1006,173 @@ _transport_phy_reset(struct sas_phy *phy, int hard_reset) | |||
1016 | } | 1006 | } |
1017 | 1007 | ||
1018 | /** | 1008 | /** |
1009 | * _transport_phy_enable - enable/disable phys | ||
1010 | * @phy: The sas phy object | ||
1011 | * @enable: enable phy when true | ||
1012 | * | ||
1013 | * Only support sas_host direct attached phys. | ||
1014 | * Returns 0 for success, non-zero for failure. | ||
1015 | */ | ||
1016 | static int | ||
1017 | _transport_phy_enable(struct sas_phy *phy, int enable) | ||
1018 | { | ||
1019 | struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); | ||
1020 | struct _sas_phy *mpt2sas_phy; | ||
1021 | Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; | ||
1022 | Mpi2ConfigReply_t mpi_reply; | ||
1023 | u16 ioc_status; | ||
1024 | u16 sz; | ||
1025 | int rc = 0; | ||
1026 | |||
1027 | mpt2sas_phy = _transport_find_local_phy(ioc, phy); | ||
1028 | |||
1029 | if (!mpt2sas_phy) /* this phy not on sas_host */ | ||
1030 | return -EINVAL; | ||
1031 | |||
1032 | /* sas_iounit page 1 */ | ||
1033 | sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * | ||
1034 | sizeof(Mpi2SasIOUnit1PhyData_t)); | ||
1035 | sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); | ||
1036 | if (!sas_iounit_pg1) { | ||
1037 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1038 | ioc->name, __FILE__, __LINE__, __func__); | ||
1039 | rc = -ENOMEM; | ||
1040 | goto out; | ||
1041 | } | ||
1042 | if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, | ||
1043 | sas_iounit_pg1, sz))) { | ||
1044 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1045 | ioc->name, __FILE__, __LINE__, __func__); | ||
1046 | rc = -ENXIO; | ||
1047 | goto out; | ||
1048 | } | ||
1049 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
1050 | MPI2_IOCSTATUS_MASK; | ||
1051 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { | ||
1052 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1053 | ioc->name, __FILE__, __LINE__, __func__); | ||
1054 | rc = -EIO; | ||
1055 | goto out; | ||
1056 | } | ||
1057 | |||
1058 | if (enable) | ||
1059 | sas_iounit_pg1->PhyData[mpt2sas_phy->phy_id].PhyFlags | ||
1060 | &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; | ||
1061 | else | ||
1062 | sas_iounit_pg1->PhyData[mpt2sas_phy->phy_id].PhyFlags | ||
1063 | |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; | ||
1064 | |||
1065 | mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz); | ||
1066 | |||
1067 | out: | ||
1068 | kfree(sas_iounit_pg1); | ||
1069 | return rc; | ||
1070 | } | ||
1071 | |||
1072 | /** | ||
1073 | * _transport_phy_speed - set phy min/max link rates | ||
1074 | * @phy: The sas phy object | ||
1075 | * @rates: rates defined in sas_phy_linkrates | ||
1076 | * | ||
1077 | * Only support sas_host direct attached phys. | ||
1078 | * Returns 0 for success, non-zero for failure. | ||
1079 | */ | ||
1080 | static int | ||
1081 | _transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) | ||
1082 | { | ||
1083 | struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); | ||
1084 | struct _sas_phy *mpt2sas_phy; | ||
1085 | Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; | ||
1086 | Mpi2SasPhyPage0_t phy_pg0; | ||
1087 | Mpi2ConfigReply_t mpi_reply; | ||
1088 | u16 ioc_status; | ||
1089 | u16 sz; | ||
1090 | int i; | ||
1091 | int rc = 0; | ||
1092 | |||
1093 | mpt2sas_phy = _transport_find_local_phy(ioc, phy); | ||
1094 | |||
1095 | if (!mpt2sas_phy) /* this phy not on sas_host */ | ||
1096 | return -EINVAL; | ||
1097 | |||
1098 | if (!rates->minimum_linkrate) | ||
1099 | rates->minimum_linkrate = phy->minimum_linkrate; | ||
1100 | else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) | ||
1101 | rates->minimum_linkrate = phy->minimum_linkrate_hw; | ||
1102 | |||
1103 | if (!rates->maximum_linkrate) | ||
1104 | rates->maximum_linkrate = phy->maximum_linkrate; | ||
1105 | else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) | ||
1106 | rates->maximum_linkrate = phy->maximum_linkrate_hw; | ||
1107 | |||
1108 | /* sas_iounit page 1 */ | ||
1109 | sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * | ||
1110 | sizeof(Mpi2SasIOUnit1PhyData_t)); | ||
1111 | sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); | ||
1112 | if (!sas_iounit_pg1) { | ||
1113 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1114 | ioc->name, __FILE__, __LINE__, __func__); | ||
1115 | rc = -ENOMEM; | ||
1116 | goto out; | ||
1117 | } | ||
1118 | if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, | ||
1119 | sas_iounit_pg1, sz))) { | ||
1120 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1121 | ioc->name, __FILE__, __LINE__, __func__); | ||
1122 | rc = -ENXIO; | ||
1123 | goto out; | ||
1124 | } | ||
1125 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
1126 | MPI2_IOCSTATUS_MASK; | ||
1127 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { | ||
1128 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1129 | ioc->name, __FILE__, __LINE__, __func__); | ||
1130 | rc = -EIO; | ||
1131 | goto out; | ||
1132 | } | ||
1133 | |||
1134 | for (i = 0; i < ioc->sas_hba.num_phys; i++) { | ||
1135 | if (mpt2sas_phy->phy_id != i) { | ||
1136 | sas_iounit_pg1->PhyData[i].MaxMinLinkRate = | ||
1137 | (ioc->sas_hba.phy[i].phy->minimum_linkrate + | ||
1138 | (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4)); | ||
1139 | } else { | ||
1140 | sas_iounit_pg1->PhyData[i].MaxMinLinkRate = | ||
1141 | (rates->minimum_linkrate + | ||
1142 | (rates->maximum_linkrate << 4)); | ||
1143 | } | ||
1144 | } | ||
1145 | |||
1146 | if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, | ||
1147 | sz)) { | ||
1148 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1149 | ioc->name, __FILE__, __LINE__, __func__); | ||
1150 | rc = -ENXIO; | ||
1151 | goto out; | ||
1152 | } | ||
1153 | |||
1154 | /* link reset */ | ||
1155 | _transport_phy_reset(phy, 0); | ||
1156 | |||
1157 | /* read phy page 0, then update the rates in the sas transport phy */ | ||
1158 | if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0, | ||
1159 | mpt2sas_phy->phy_id)) { | ||
1160 | phy->minimum_linkrate = _transport_convert_phy_link_rate( | ||
1161 | phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); | ||
1162 | phy->maximum_linkrate = _transport_convert_phy_link_rate( | ||
1163 | phy_pg0.ProgrammedLinkRate >> 4); | ||
1164 | phy->negotiated_linkrate = _transport_convert_phy_link_rate( | ||
1165 | phy_pg0.NegotiatedLinkRate & | ||
1166 | MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); | ||
1167 | } | ||
1168 | |||
1169 | out: | ||
1170 | kfree(sas_iounit_pg1); | ||
1171 | return rc; | ||
1172 | } | ||
1173 | |||
1174 | |||
1175 | /** | ||
1019 | * _transport_smp_handler - transport portal for smp passthru | 1176 | * _transport_smp_handler - transport portal for smp passthru |
1020 | * @shost: shost object | 1177 | * @shost: shost object |
1021 | * @rphy: sas transport rphy object | 1178 | * @rphy: sas transport rphy object |
@@ -1126,7 +1283,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), | 1283 | dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio), |
1127 | blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); | 1284 | blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); |
1128 | if (!dma_addr_out) { | 1285 | if (!dma_addr_out) { |
1129 | mpt2sas_base_free_smid(ioc, le16_to_cpu(smid)); | 1286 | mpt2sas_base_free_smid(ioc, smid); |
1130 | goto unmap; | 1287 | goto unmap; |
1131 | } | 1288 | } |
1132 | 1289 | ||
@@ -1144,7 +1301,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), | 1301 | dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio), |
1145 | blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); | 1302 | blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); |
1146 | if (!dma_addr_in) { | 1303 | if (!dma_addr_in) { |
1147 | mpt2sas_base_free_smid(ioc, le16_to_cpu(smid)); | 1304 | mpt2sas_base_free_smid(ioc, smid); |
1148 | goto unmap; | 1305 | goto unmap; |
1149 | } | 1306 | } |
1150 | 1307 | ||
@@ -1217,6 +1374,8 @@ struct sas_function_template mpt2sas_transport_functions = { | |||
1217 | .get_enclosure_identifier = _transport_get_enclosure_identifier, | 1374 | .get_enclosure_identifier = _transport_get_enclosure_identifier, |
1218 | .get_bay_identifier = _transport_get_bay_identifier, | 1375 | .get_bay_identifier = _transport_get_bay_identifier, |
1219 | .phy_reset = _transport_phy_reset, | 1376 | .phy_reset = _transport_phy_reset, |
1377 | .phy_enable = _transport_phy_enable, | ||
1378 | .set_phy_speed = _transport_phy_speed, | ||
1220 | .smp_handler = _transport_smp_handler, | 1379 | .smp_handler = _transport_smp_handler, |
1221 | }; | 1380 | }; |
1222 | 1381 | ||