aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r--drivers/scsi/mpt2sas/Kconfig1
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2.h17
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h297
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_history.txt93
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_init.h24
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_ioc.h91
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_raid.h14
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_sas.h6
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_tool.h16
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c171
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h47
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c52
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c210
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.h4
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c1078
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c283
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
820typedef 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
1834typedef 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
1883typedef 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
2299typedef 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) */
2527typedef 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
2535typedef 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
2588typedef 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
70mpi2_cnfg.h 76mpi2_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
160mpi2_init.h 175mpi2_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
177mpi2_ioc.h 196mpi2_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
251mpi2_raid.h 284mpi2_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
261mpi2_sas.h 296mpi2_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
269mpi2_targ.h 306mpi2_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
288mpi2_type.h 329mpi2_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
337mpi2_hbd.h
338 * 10-28-09 02.00.00 Initial version.
339 * --------------------------------------------------------------------------
340
341
296mpi2_history.txt Parts list history 342mpi2_history.txt Parts list history
297 343
298Filename 02.00.12 344Filename 02.00.14 02.00.13 02.00.12
299---------- -------- 345---------- -------- -------- --------
300mpi2.h 02.00.12 346mpi2.h 02.00.14 02.00.13 02.00.12
301mpi2_cnfg.h 02.00.11 347mpi2_cnfg.h 02.00.13 02.00.12 02.00.11
302mpi2_init.h 02.00.07 348mpi2_init.h 02.00.08 02.00.07 02.00.07
303mpi2_ioc.h 02.00.11 349mpi2_ioc.h 02.00.13 02.00.12 02.00.11
304mpi2_raid.h 02.00.03 350mpi2_raid.h 02.00.04 02.00.04 02.00.03
305mpi2_sas.h 02.00.02 351mpi2_sas.h 02.00.03 02.00.02 02.00.02
306mpi2_targ.h 02.00.03 352mpi2_targ.h 02.00.03 02.00.03 02.00.03
307mpi2_tool.h 02.00.03 353mpi2_tool.h 02.00.04 02.00.04 02.00.03
308mpi2_type.h 02.00.00 354mpi2_type.h 02.00.00 02.00.00 02.00.00
309mpi2_ra.h 02.00.00 355mpi2_ra.h 02.00.00 02.00.00 02.00.00
356mpi2_hbd.h 02.00.00
310 357
311Filename 02.00.11 02.00.10 02.00.09 02.00.08 02.00.07 02.00.06 358Filename 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
495typedef 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
474typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED 505typedef 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
900typedef 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
917typedef 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
922typedef 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
283typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST 287typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST
284{ 288{
285 U8 Reserved1; /* 0x00 */ 289 U8 ExtendedType; /* 0x00 */
286 U8 BufferType; /* 0x01 */ 290 U8 BufferType; /* 0x01 */
287 U8 ChainOffset; /* 0x02 */ 291 U8 ChainOffset; /* 0x02 */
288 U8 Function; /* 0x03 */ 292 U8 Function; /* 0x03 */
@@ -301,11 +305,15 @@ typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST
301} MPI2_DIAG_BUFFER_POST_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REQUEST, 305} MPI2_DIAG_BUFFER_POST_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REQUEST,
302 Mpi2DiagBufferPostRequest_t, MPI2_POINTER pMpi2DiagBufferPostRequest_t; 306 Mpi2DiagBufferPostRequest_t, MPI2_POINTER pMpi2DiagBufferPostRequest_t;
303 307
308/* values for the ExtendedType field */
309#define MPI2_DIAG_EXTENDED_TYPE_UTILIZATION (0x02)
310
304/* values for the BufferType field */ 311/* values for the BufferType field */
305#define MPI2_DIAG_BUF_TYPE_TRACE (0x00) 312#define MPI2_DIAG_BUF_TYPE_TRACE (0x00)
306#define MPI2_DIAG_BUF_TYPE_SNAPSHOT (0x01) 313#define MPI2_DIAG_BUF_TYPE_SNAPSHOT (0x01)
314#define MPI2_DIAG_BUF_TYPE_EXTENDED (0x02)
307/* count of the number of buffer types */ 315/* count of the number of buffer types */
308#define MPI2_DIAG_BUF_TYPE_COUNT (0x02) 316#define MPI2_DIAG_BUF_TYPE_COUNT (0x03)
309 317
310 318
311/**************************************************************************** 319/****************************************************************************
@@ -314,7 +322,7 @@ typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST
314 322
315typedef struct _MPI2_DIAG_BUFFER_POST_REPLY 323typedef struct _MPI2_DIAG_BUFFER_POST_REPLY
316{ 324{
317 U8 Reserved1; /* 0x00 */ 325 U8 ExtendedType; /* 0x00 */
318 U8 BufferType; /* 0x01 */ 326 U8 BufferType; /* 0x01 */
319 U8 MsgLength; /* 0x02 */ 327 U8 MsgLength; /* 0x02 */
320 U8 Function; /* 0x03 */ 328 U8 Function; /* 0x03 */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 670241efa4b5..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;
77module_param(msix_disable, int, 0); 78module_param(msix_disable, int, 0);
78MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); 79MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
79 80
81/* diag_buffer_enable is bitwise
82 * bit 0 set = TRACE
83 * bit 1 set = SNAPSHOT
84 * bit 2 set = EXTENDED
85 *
86 * Either bit can be set, or both
87 */
88static int diag_buffer_enable;
89module_param(diag_buffer_enable, int, 0);
90MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
91 "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
92
93int mpt2sas_fwfault_debug;
94MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
95 "and halt firmware - (default=0)");
96
97/**
98 * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
99 *
100 */
101static int
102_scsih_set_fwfault_debug(const char *val, struct kernel_param *kp)
103{
104 int ret = param_set_int(val, kp);
105 struct MPT2SAS_ADAPTER *ioc;
106
107 if (ret)
108 return ret;
109
110 printk(KERN_INFO "setting 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}
115module_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 */
225void
226mpt2sas_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 */
241void
242mpt2sas_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 */
535void
536mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code)
537{
538 printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n",
539 ioc->name, fault_code);
540}
541
542/**
543 * _base_display_reply_info - 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 */
1263dma_addr_t 1335__le32
1264mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid) 1336mpt2sas_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(&current_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 */
327struct _raid_device { 328struct _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 */
363struct _sas_port { 363struct _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,
773void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid); 775void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid);
774void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid); 776void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid);
775void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr); 777void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr);
776dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, 778__le32 mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc,
777 u16 smid); 779 u16 smid);
778 780
779/* hi-priority queue */ 781/* hi-priority queue */
@@ -807,6 +809,8 @@ int mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
807 Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request); 809 Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request);
808void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type); 810void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type);
809 811
812void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc);
813
810/* scsih shared API */ 814/* scsih shared API */
811u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, 815u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
812 u32 reply); 816 u32 reply);
@@ -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);
850int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t 854int 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);
856int mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
857 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);
852int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t 858int 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);
854int mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t 860int 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,
886void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, 892void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
887 Mpi2EventNotificationReply_t *mpi_reply); 893 Mpi2EventNotificationReply_t *mpi_reply);
888 894
895void mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc,
896 u8 bits_to_regsiter);
897
889/* transport shared API */ 898/* transport shared API */
890u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 899u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
891 u32 reply); 900 u32 reply);
892struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, 901struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc,
893 u16 handle, u16 parent_handle); 902 u16 handle, u64 sas_address);
894void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, 903void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
895 u16 parent_handle); 904 u64 sas_address_parent);
896int mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy 905int 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);
898int mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy 907int 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);
900void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, u16 handle, 909void 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);
902extern struct sas_function_template mpt2sas_transport_functions; 911extern struct sas_function_template mpt2sas_transport_functions;
903extern struct scsi_transport_template *mpt2sas_transport_template; 912extern struct scsi_transport_template *mpt2sas_transport_template;
904extern int scsi_internal_device_block(struct scsi_device *sdev); 913extern 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 */
940int
941mpt2sas_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 */
1265static long 1270static 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 */
1443void
1444mpt2sas_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 */
1489static 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,
2474static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR, 2538static 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 */
2550static 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}
2559static 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}
2575static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR,
2576 _ctl_fwfault_debug_show, _ctl_fwfault_debug_store);
2577
2477struct device_attribute *mpt2sas_host_attrs[] = { 2578struct 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;
76static u8 ctl_cb_idx = -1; 78static u8 ctl_cb_idx = -1;
77static u8 base_cb_idx = -1; 79static u8 base_cb_idx = -1;
78static u8 transport_cb_idx = -1; 80static u8 transport_cb_idx = -1;
81static u8 scsih_cb_idx = -1;
79static u8 config_cb_idx = -1; 82static u8 config_cb_idx = -1;
80static int mpt_ids; 83static 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 */
139static 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};
205MODULE_DEVICE_TABLE(pci, scsih_pci_table); 229MODULE_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 */
350static 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 */
564struct _sas_node *
565mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
566{
567 struct _sas_node *sas_expander, *r;
568
569 r = NULL;
570 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
571 if (sas_expander->handle != handle)
572 continue;
573 r = sas_expander;
574 goto out;
575 }
576 out:
577 return r;
578}
579
580/**
581 * _scsih_raid_device_find_by_id - raid device search 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 */
746struct _sas_node *
747mpt2sas_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 */
1049static int 1111static 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 */
1416static 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 */
1428static 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 */
1467static 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 */
1523static 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 */
1615static 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 */
3356static void 3606static 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 */
3966static 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 */
3706static void 3994static 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 */
3843static void 4135static 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 */
6086static 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 */
6156static 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 */
5698static void __devexit 6173static 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 */
6574static 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
6164module_init(_scsih_init); 6680module_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 */
70static struct _sas_node * 71static 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 */
479struct _sas_port * 479struct _sas_port *
480mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle, 480mpt2sas_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 */
615void 611void
616mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, 612mpt2sas_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 */
809void 805void
810mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, 806mpt2sas_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
859static 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 */
1016static 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 */
1080static 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